1

Update format to SystemVerilog Module

This commit is contained in:
2023-03-29 19:13:51 +02:00
parent 28a7c14059
commit a7f4bf6e92
3 changed files with 34 additions and 32 deletions

View File

@ -5,7 +5,7 @@ set(CMAKE_CXX_STANDARD 20)
find_package(Boost 1.81 COMPONENTS program_options REQUIRED)
add_executable(lasm
add_executable(svrasm
src/main.cpp
src/lexer/Token.cpp
src/lexer/Lexer.cpp
@ -25,4 +25,4 @@ add_executable(lasm
src/codegen/CodegenObserver.cpp
)
target_link_libraries(lasm Boost::program_options)
target_link_libraries(svrasm Boost::program_options)

View File

@ -3,8 +3,7 @@
//
#include "CodegenObserver.h"
#include <boost/format.hpp>
#include <iostream>
#include <bitset>
CodegenObserver::CodegenObserver(const Node &node, std::vector<std::string> &output_string)
: PostfixObserver(node), output_string(output_string) {}
@ -13,12 +12,13 @@ void CodegenObserver::action(const Node &node) {
const uint8_t dec = node.compile();
const uint8_t INVALID = -1;
// TODO: Don't do the conversion to binary here, but in generator module
if (dec != INVALID) {
// uint8_t is always interpreted as char, so cast to uint32_t
const std::string hex = (boost::format("%x") % static_cast<uint32_t>(dec)).str();
if (hex.empty() || hex.size() > 2) {
const std::string bin = std::bitset<8>(dec).to_string();
if (bin.empty() || bin.size() > 8) {
throw "Compile Error: Resulting instruction has invalid size!";
}
output_string.push_back(hex.length() == 2 ? hex : "0" + hex);
output_string.push_back(bin);
}
}

View File

@ -1,19 +1,19 @@
#include <iostream>
#include "ast/Node.h"
#include "codegen/CodegenObserver.h"
#include "codegen/PrintObserver.h"
#include "lexer/Lexer.h"
#include "parser/Parser.h"
#include <bitset>
#include <boost/program_options.hpp>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
#include <boost/program_options.hpp>
#include <boost/format.hpp>
#include <iomanip>
#include "lexer/Lexer.h"
#include "ast/Node.h"
#include "parser/Parser.h"
#include "codegen/PrintObserver.h"
#include "codegen/CodegenObserver.h"
namespace po = boost::program_options;
auto read(const std::string& input_file, std::string &input_string) -> bool {
auto read(const std::string &input_file, std::string &input_string) -> bool {
std::ifstream ifs;
ifs.open(input_file, std::ios_base::in);
if (!ifs) {
@ -54,6 +54,7 @@ auto parse(std::vector<Token> &tokens) -> std::unique_ptr<Node> {
return std::move(parser.parse());
}
// TODO: Modularize the output generation, I want different generators for different formats
auto write(const std::string &output_file, const std::vector<std::string> &output_string) -> bool {
if (output_string.size() > 255) {
std::cout << "Program too large!" << std::endl;
@ -67,22 +68,26 @@ auto write(const std::string &output_file, const std::vector<std::string> &outpu
return false;
}
ofs << "v3.0 hex words addressed";
for (uint32_t i = 0; i <= 255; ++i) {
if (i % 16 == 0) {
ofs << std::endl;
// Print Address
std::string address = (boost::format("%x") % i).str();
ofs << (address == "0" ? "00" : address) << ": ";
}
ofs << "`default_nettype none\n\n"
<< "module ROM(\n"
<< " input var logic[7:0] address,\n"
<< " output var logic[7:0] dataout\n"
<< ");\n\n"
<< " always @(address) case (address)\n";
for (uint32_t i = 0; i <= 255; ++i) {
if (i < output_string.size()) {
ofs << output_string[i] << " ";
} else {
ofs << "00 ";
ofs << " case 8'b" << std::bitset<8>(i).to_string() << ": dataout = 8'b" << output_string[i] << ";\n";
}
}
ofs << " default: dataout = 8'b00000000;\n"
<< " endcase\n\n"
<< "endmodule" << std::endl;
ofs.flush();
ofs.close();
return true;
@ -91,10 +96,7 @@ auto write(const std::string &output_file, const std::vector<std::string> &outpu
auto main(int argc, char **argv) -> int {
// Argument parsing straight from the Boost manual: https://www.boost.org/doc/libs/1_60_0/doc/html/program_options/tutorial.html
po::options_description desc("Allowed options");
desc.add_options()
("help,h", "Show this help message")
("input,i", po::value<std::string>(), "Input file")
("output,o", po::value<std::string>(), "Output file");
desc.add_options()("help,h", "Show this help message")("input,i", po::value<std::string>(), "Input file")("output,o", po::value<std::string>(), "Output file");
po::variables_map vm;
po::store(po::parse_command_line(argc, argv, desc), vm);