From 60e1775b874015a3451e4bde10a8eb30701b1165 Mon Sep 17 00:00:00 2001 From: Julian Blake Kongslie Date: Tue, 6 Jul 2021 09:44:36 -0700 Subject: Initial commit. --- sim/.gitignore | 2 ++ sim/Makefile | 12 +++++++++ sim/alu.sv | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++ sim/control.sv | 54 ++++++++++++++++++++++++++++++++++++++ sim/decode.sv | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ sim/main.cpp | 61 +++++++++++++++++++++++++++++++++++++++++++ sim/memory.sv | 35 +++++++++++++++++++++++++ sim/pc.sv | 36 ++++++++++++++++++++++++++ sim/rf.sv | 39 ++++++++++++++++++++++++++++ sim/tmp.sv | 41 +++++++++++++++++++++++++++++ sim/top.sv | 27 +++++++++++++++++++ sim/uart.sv | 47 +++++++++++++++++++++++++++++++++ sim/urom.sv | 19 ++++++++++++++ 13 files changed, 531 insertions(+) create mode 100644 sim/.gitignore create mode 100644 sim/Makefile create mode 100644 sim/alu.sv create mode 100644 sim/control.sv create mode 100644 sim/decode.sv create mode 100644 sim/main.cpp create mode 100644 sim/memory.sv create mode 100644 sim/pc.sv create mode 100644 sim/rf.sv create mode 100644 sim/tmp.sv create mode 100644 sim/top.sv create mode 100644 sim/uart.sv create mode 100644 sim/urom.sv (limited to 'sim') diff --git a/sim/.gitignore b/sim/.gitignore new file mode 100644 index 0000000..dc3fae8 --- /dev/null +++ b/sim/.gitignore @@ -0,0 +1,2 @@ +/build +/verilator diff --git a/sim/Makefile b/sim/Makefile new file mode 100644 index 0000000..af9d22a --- /dev/null +++ b/sim/Makefile @@ -0,0 +1,12 @@ +run: build/Vtop + $< +.PHONY: run + +build/Vtop: $(wildcard *.cpp *.sv) + @rm -rf verilator + @mkdir -p build verilator + verilator +1800-2017ext+sv -Wall -Wno-BLKSEQ -Wno-UNUSED -O3 -Ihdl --Mdir verilator --trace --cc --build -j --exe --top-module top $(wildcard *.cpp *.sv) + @ln -t build -f verilator/Vtop + @rm -rf verilator + +.SECONDARY: diff --git a/sim/alu.sv b/sim/alu.sv new file mode 100644 index 0000000..407b083 --- /dev/null +++ b/sim/alu.sv @@ -0,0 +1,76 @@ +module alu + #( parameter UROM = "" + , parameter UIP_BITS = 15 + , parameter UROM_BITS = 8 + , parameter BUS_BITS = 16 + ) + ( input bit clk + , input bit reset + , input bit [UIP_BITS-1:0] uip + , inout bit [BUS_BITS-1:0] abus + , inout bit [BUS_BITS-1:0] dbus + ); + +bit [BUS_BITS-1:0] x; + +typedef enum + { OP + , OP_SEL0 + , OP_SEL1 + , OP_SEL2 + , OUTADDR + , OUTDATA + } CtrlBit; + +bit [UROM_BITS-1:0] ctrl; +urom#(UROM, UIP_BITS, UROM_BITS) urom(uip, ctrl); + +bit [2:0] sel; +assign sel = {ctrl[OP_SEL2], ctrl[OP_SEL1], ctrl[OP_SEL0]}; + +bit [BUS_BITS-1:0] and_result; +bit [BUS_BITS-1:0] or_result; +bit [BUS_BITS-1:0] xor_result; +bit [BUS_BITS-1:0] add_result; +bit [BUS_BITS-1:0] sub_result; +bit [BUS_BITS-1:0] cmp_result; +bit [BUS_BITS-1:0] lshift_result; +bit [BUS_BITS-1:0] rshift_result; + +assign and_result = abus & dbus; +assign or_result = abus | dbus; +assign xor_result = abus ^ dbus; +assign add_result = abus + dbus; +assign sub_result = abus - dbus; +assign cmp_result = {{(BUS_BITS-6){1'b0}}, + (abus != 0) & (dbus != 0), + (abus != 0) | (dbus != 0), + (abus != 0) ^ (dbus != 0), + abus > dbus, + abus == dbus, + abus < dbus}; +assign lshift_result = (dbus >= BUS_BITS) ? 0 : (abus << dbus); +assign rshift_result = (dbus >= BUS_BITS) ? 0 : (abus >> dbus); + +bit [BUS_BITS-1:0] newx; +assign newx = + (sel == 0) ? and_result : + (sel == 1) ? or_result : + (sel == 2) ? xor_result : + (sel == 3) ? add_result : + (sel == 4) ? sub_result : + (sel == 5) ? cmp_result : + (sel == 6) ? lshift_result : + (sel == 7) ? rshift_result : + {(BUS_BITS){1'bX}}; + +assign abus = ctrl[OUTADDR] ? x : {(BUS_BITS){1'bZ}}; +assign dbus = ctrl[OUTDATA] ? x : {(BUS_BITS){1'bZ}}; + +always @(posedge clk) begin + if (ctrl[OP]) begin + x <= newx; + end +end + +endmodule diff --git a/sim/control.sv b/sim/control.sv new file mode 100644 index 0000000..7808f61 --- /dev/null +++ b/sim/control.sv @@ -0,0 +1,54 @@ +module control + #( parameter UROM = "" + , parameter UIP_BITS = 15 + , parameter UROM_BITS = 8 + , parameter BUS_BITS = 16 + , parameter CONST_0 = "" + , parameter CONST_1 = "" + , parameter RESET = ~0 + ) + ( input bit clk + , input bit reset + , output bit [UIP_BITS-1:0] uip + , inout bit [BUS_BITS-1:0] abus + , inout bit [BUS_BITS-1:0] dbus + ); + +typedef enum + { HALT + , SET_UIP_COND + , NOCOND + , OUTADDR + , OUTDATA + } CtrlBit; + +bit [UROM_BITS-1:0] ctrl; +urom#(UROM, UIP_BITS, UROM_BITS) urom(uip, ctrl); + +bit [UROM_BITS*2-1:0] constant; +urom#(CONST_0, UIP_BITS, UROM_BITS) const_0(uip, constant[1*UROM_BITS-1:0*UROM_BITS]); +urom#(CONST_1, UIP_BITS, UROM_BITS) const_1(uip, constant[2*UROM_BITS-1:1*UROM_BITS]); + +assign abus = ctrl[OUTADDR] ? constant : {(BUS_BITS){1'bZ}}; +assign dbus = ctrl[OUTDATA] ? constant : {(BUS_BITS){1'bZ}}; + +bit cond; +assign cond = (dbus != 0) || ctrl[NOCOND]; + +always @(posedge clk) begin + if (reset) begin + uip <= RESET; + end else begin + if (! ctrl[HALT]) begin + if (ctrl[SET_UIP_COND] && cond) begin + uip <= abus[UIP_BITS-1:0]; + end else begin + uip <= uip + 1; + end + end else begin + $finish; + end + end +end + +endmodule diff --git a/sim/decode.sv b/sim/decode.sv new file mode 100644 index 0000000..5c9a9c9 --- /dev/null +++ b/sim/decode.sv @@ -0,0 +1,82 @@ +module decode + #( parameter UROM = "" + , parameter UIP_BITS = 15 + , parameter UROM_BITS = 8 + , parameter BUS_BITS = 16 + , parameter OPCODE_BITS = 8 + ) + ( input bit clk + , input bit reset + , input bit [UIP_BITS-1:0] uip + , inout bit [BUS_BITS-1:0] abus + , inout bit [BUS_BITS-1:0] dbus + ); + +bit [OPCODE_BITS-1:0] opcode; +bit [BUS_BITS-1:0] a; +bit [BUS_BITS-1:0] b; +bit needmore; + +bit [UIP_BITS-1:0] new_uip; +assign new_uip = {opcode, {(UIP_BITS-OPCODE_BITS){1'b0}}}; + +typedef enum + { CLEAR + , DECODE + , OUTADDR + , OUTADDR_SEL0 + , OUTADDR_SEL1 + , OUTDATA + , OUTDATA_SEL0 + , OUTDATA_SEL1 + } CtrlBit; + +bit [UROM_BITS-1:0] ctrl; +urom#(UROM, UIP_BITS, UROM_BITS) urom(uip, ctrl); + +bit [1:0] asel; +assign asel = {ctrl[OUTADDR_SEL1], ctrl[OUTADDR_SEL0]}; + +bit [1:0] dsel; +assign dsel = {ctrl[OUTDATA_SEL1], ctrl[OUTDATA_SEL0]}; + +bit [BUS_BITS-1:0] aout; +assign aout = + (asel == 0) ? a : + (asel == 1) ? b : + (asel == 2) ? {{(BUS_BITS-UIP_BITS){1'b0}}, new_uip} : + {(BUS_BITS){1'bX}}; + +assign abus = ctrl[OUTADDR] ? aout : {(BUS_BITS){1'bZ}}; + +bit [BUS_BITS-1:0] dout; +assign dout = + (dsel == 0) ? a : + (dsel == 1) ? b : + (dsel == 2) ? {{(BUS_BITS-1){1'b0}}, needmore} : + {(BUS_BITS){1'bX}}; + +assign dbus = ctrl[OUTDATA] ? dout : {(BUS_BITS){1'bZ}}; + +always @(posedge clk) begin + if (reset || ctrl[CLEAR]) begin + opcode <= 0; + a <= 0; + b <= 0; + needmore <= 1; + end else if (ctrl[DECODE]) begin + automatic bit m = dbus[7]; + automatic bit i = dbus[6]; + automatic bit [1:0] field = dbus[5:4]; + automatic bit [3:0] shift = dbus[3:0]; + needmore <= m; + if (field == 0) begin + opcode <= {i ? ~opcode[OPCODE_BITS-1-4:0] : opcode[OPCODE_BITS-1-4:0], shift}; + end else if (field == 2) begin + a <= {i ? ~a[BUS_BITS-1-4:0] : a[BUS_BITS-1-4:0], shift}; + end else if (field == 3) begin + b <= {i ? ~b[BUS_BITS-1-4:0] : b[BUS_BITS-1-4:0], shift}; + end + end +end +endmodule diff --git a/sim/main.cpp b/sim/main.cpp new file mode 100644 index 0000000..ac4befa --- /dev/null +++ b/sim/main.cpp @@ -0,0 +1,61 @@ +#include +#include +#include +#include + +#include "Vtop.h" + +std::uint64_t phases = 0; + +double sc_time_stamp() +{ + return (double)phases / 2; +} + +int main(int argc, const char *argv[]) +{ + Verilated::commandArgs(argc, argv); + + Verilated::traceEverOn(true); + VerilatedVcdC vcd; + + Vtop top; + top.trace(&vcd, 100 /* levels of hierarchy */); + + vcd.set_time_unit("ns"); + vcd.set_time_resolution("ns"); + vcd.open("build/out.vcd"); + + std::cout << "*** RESET SEQUENCE ***\n"; + + top.clk = 0; + top.reset = 1; + top.eval(); + vcd.dump(++phases); + + top.clk = 1; + top.eval(); + vcd.dump(++phases); + + top.clk = 0; + top.reset = 0; + top.eval(); + vcd.dump(++phases); + + std::cout << "*** MAIN LOOP ***\n"; + + for (unsigned int i = 0; i < 10000 && !Verilated::gotFinish(); ++i) { + top.clk = 1; + top.eval(); + vcd.dump(++phases); + top.clk = 0; + top.eval(); + vcd.dump(++phases); + } + + std::cout << "\n"; + + vcd.close(); + + return 0; +} diff --git a/sim/memory.sv b/sim/memory.sv new file mode 100644 index 0000000..0eb1233 --- /dev/null +++ b/sim/memory.sv @@ -0,0 +1,35 @@ +module memory + #( parameter UROM = "" + , parameter UIP_BITS = 15 + , parameter UROM_BITS = 8 + , parameter BUS_BITS = 16 + , parameter IMAGE = "" + , parameter BYTE_BITS = 8 + ) + ( input bit clk + , input bit reset + , input bit [UIP_BITS-1:0] uip + , inout bit [BUS_BITS-1:0] abus + , inout bit [BUS_BITS-1:0] dbus + ); + +bit [BYTE_BITS-1:0] storage [0:(1<