diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index 28f5a36..6c78102 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -4,6 +4,7 @@ "name": "Linux", "includePath": [ "${workspaceFolder}/**", + "${workspaceFolder}/sim/obj_dir", "/usr/share/verilator/include" ], "defines": [], diff --git a/model/DCData_bram.v b/model/DCData_bram.v index 027925d..0c69fff 100644 --- a/model/DCData_bram.v +++ b/model/DCData_bram.v @@ -1,17 +1,17 @@ module DCData_bram ( - input [ 6:0] addra, - input clka, - input [127:0] dina, - output [127:0] douta, - input wea + input [ 6:0] addra, + input clka, + input [127:0] dina, + output reg [127:0] douta, + input wea ); reg [127:0] ram [0:127]; - always @(posedge CLK) begin + always @(posedge clka) begin if(wea) begin ram[addra] <= dina; end - douta <= ~wea ? ram[addra] : {128{$random}}; + douta <= ~wea ? ram[addra] : {4{$random}}; end endmodule diff --git a/model/DCTag_bram.v b/model/DCTag_bram.v index 030bf8e..d3e148d 100644 --- a/model/DCTag_bram.v +++ b/model/DCTag_bram.v @@ -1,17 +1,17 @@ module DCTag_bram ( - input [ 6:0] addra, - input clka, - input [22:0] dina, - output [22:0] douta, - input wea + input [ 6:0] addra, + input clka, + input [22:0] dina, + output reg [22:0] douta, + input wea ); reg [22:0] ram [0:127]; - always @(posedge CLK) begin + always @(posedge clka) begin if(wea) begin ram[addra] <= dina; end - douta <= ~wea ? ram[addra] : {23{$random}}; + douta <= ~wea ? ram[addra] : {$random}[22:0]; end endmodule diff --git a/model/ICData_bram.v b/model/ICData_bram.v index 7778312..bea4730 100644 --- a/model/ICData_bram.v +++ b/model/ICData_bram.v @@ -1,16 +1,16 @@ module ICData_bram ( - input [ 5:0] addra, - input clka, - input [255:0] dina, - output [255:0] douta, - input wea + input [ 5:0] addra, + input clka, + input [255:0] dina, + output reg [255:0] douta, + input wea ); reg [255:0] ram [0:63]; - always @(posedge CLK) begin + always @(posedge clka) begin if(wea) begin ram[addra] <= dina; end - douta <= ~wea ? ram[addra] : {256{$random}}; + douta <= ~wea ? ram[addra] : {8{$random}}; end endmodule diff --git a/model/ICTag_bram.v b/model/ICTag_bram.v index aeaac26..c9cc324 100644 --- a/model/ICTag_bram.v +++ b/model/ICTag_bram.v @@ -1,17 +1,17 @@ module ICTag_bram ( - input [ 5:0] addra, - input clka, - input [21:0] dina, - output [21:0] douta, - input wea + input [ 5:0] addra, + input clka, + input [21:0] dina, + output reg [21:0] douta, + input wea ); reg [21:0] ram [0:63]; - always @(posedge CLK) begin + always @(posedge clka) begin if(wea) begin ram[addra] <= dina; end - douta <= ~wea ? ram[addra] : {21{$random}}; + douta <= ~wea ? ram[addra] : {$random}[21:0]; end endmodule diff --git a/model/div_signed.v b/model/div_signed.v index 99b5cfd..2e3ec9c 100644 --- a/model/div_signed.v +++ b/model/div_signed.v @@ -1,5 +1,5 @@ module div_signed( - input clk, + input aclk, input s_axis_dividend_tvalid, input [31:0] s_axis_dividend_tdata, input s_axis_divisor_tvalid, @@ -14,7 +14,7 @@ module div_signed( assign m_axis_dout_tvalid = nxtValid; assign m_axis_dout_tdata = nxtData; - always @(posedge clk) begin + always @(posedge aclk) begin nxtValid <= valid; nxtData <= data; if (s_axis_dividend_tvalid & s_axis_divisor_tvalid) begin @@ -27,4 +27,4 @@ module div_signed( end -endmodule \ No newline at end of file +endmodule diff --git a/model/div_unsigned.v b/model/div_unsigned.v index 95aab98..c434387 100644 --- a/model/div_unsigned.v +++ b/model/div_unsigned.v @@ -1,5 +1,5 @@ -module div_signed( - input clk, +module div_unsigned( + input aclk, input s_axis_dividend_tvalid, input [31:0] s_axis_dividend_tdata, input s_axis_divisor_tvalid, @@ -14,7 +14,7 @@ module div_signed( assign m_axis_dout_tvalid = nxtValid; assign m_axis_dout_tdata = nxtData; - always @(posedge clk) begin + always @(posedge aclk) begin nxtValid <= valid; nxtData <= data; if (s_axis_dividend_tvalid & s_axis_divisor_tvalid) begin @@ -27,4 +27,4 @@ module div_signed( end -endmodule \ No newline at end of file +endmodule diff --git a/model/mul_unsigned.sv b/model/mul_unsigned.sv index ead6e29..5a062ef 100644 --- a/model/mul_unsigned.sv +++ b/model/mul_unsigned.sv @@ -1,6 +1,6 @@ `include "defines.svh" -module mul_signed( +module mul_unsigned( input logic CLK, input word_t A, input word_t B, diff --git a/sim/.gitignore b/sim/.gitignore new file mode 100644 index 0000000..9b2e351 --- /dev/null +++ b/sim/.gitignore @@ -0,0 +1,2 @@ +logs +obj_dir \ No newline at end of file diff --git a/sim/Makefile b/sim/Makefile new file mode 100644 index 0000000..3d3c773 --- /dev/null +++ b/sim/Makefile @@ -0,0 +1,60 @@ +GENHTML = genhtml + +VERILATOR = verilator +VERILATOR_COVERAGE = verilator_coverage + +VERILATOR_FLAGS = +# Generate C++ in executable form +VERILATOR_FLAGS += -cc --exe +# Generate makefile dependencies (not shown as complicates the Makefile) +VERILATOR_FLAGS += -MMD +# Optimize +VERILATOR_FLAGS += -Os -x-assign 0 +# Warn abount lint issues; may not want this on less solid designs +VERILATOR_FLAGS += -Wall +# Make waveforms +VERILATOR_FLAGS += --trace +# Check SystemVerilog assertions +VERILATOR_FLAGS += --assert +# Generate coverage analysis +VERILATOR_FLAGS += --coverage +# Run make to compile model, with as many CPUs as are free +VERILATOR_FLAGS += --build -j + +# Get rid of annoying warnings +VERILATOR_FLAGS += -Wno-UNOPT -Wno-UNOPTFLAT -Wno-BLKSEQ +VERILATOR_FLAGS += -DSIMULATION_PC + +# Create annotated source +VERILATOR_COV_FLAGS += --annotate logs/annotated +# A single coverage hit is considered good enough +VERILATOR_COV_FLAGS += --annotate-min 1 +# Create LCOV info +VERILATOR_COV_FLAGS += --write-info logs/coverage.info +# Input file from Verilator +VERILATOR_COV_FLAGS += logs/coverage.dat + +SOURCE = $(wildcard ../model/*.v ../model/*.sv ../src/*.v ../src/*.sv ../src/**/*.v ../src/**/*.sv) +INCLUDE = $(addprefix -I, $(dir $(wildcard ../src/*/. ../src/**/*/.))) +# Input files for Verilator +VERILATOR_INPUT = $(INCLUDE) $(SOURCE) -top mycpu_top sim_main.cpp + +default: run + +test: + echo $(INCLUDE) + +verilate: + $(VERILATOR) $(VERILATOR_FLAGS) $(VERILATOR_INPUT) + +run: verilate + @rm -rf logs + @mkdir -p logs + obj_dir/Vmycpu_top + +coverage: verilate + @rm -rf logs/annotated + $(VERILATOR_COVERAGE) $(VERILATOR_COV_FLAGS) + +clean: + -rm -rf obj_dir logs *.log *.dmp *.vpd core \ No newline at end of file diff --git a/sim/sim_main.cpp b/sim/sim_main.cpp new file mode 100644 index 0000000..f02506a --- /dev/null +++ b/sim/sim_main.cpp @@ -0,0 +1,47 @@ +#include + +#include "Vmycpu_top.h" + +vluint64_t main_time = 0; +double sc_time_stamp() { + return main_time; // Note does conversion to real, to match SystemC +} + +int main(int argc, char** argv, char** env) { + if (0 && argc && argv && env) {} + + Verilated::debug(0); + Verilated::randReset(2); + Verilated::traceEverOn(true); + Verilated::commandArgs(argc, argv); + Verilated::mkdir("logs"); + + Vmycpu_top* top = new Vmycpu_top; // Or use a const unique_ptr, or the VL_UNIQUE_PTR wrapper + + top->aclk = 0; + while (!Verilated::gotFinish()) { + ++main_time; + top->aclk = !top->aclk; + top->aresetn = (main_time < 10) ? 1 : 0; + if (main_time < 5) { + // Zero coverage if still early in reset, otherwise toggles there may + // falsely indicate a signal is covered + VerilatedCov::zero(); + } + top->eval(); + + // TODO: fake AXI + } + + top->final(); + + // Coverage analysis (since test passed) +#if VM_COVERAGE + Verilated::mkdir("logs"); + VerilatedCov::write("logs/coverage.dat"); +#endif + + delete top; + top = NULL; + exit(0); +} \ No newline at end of file diff --git a/src/AXI/AXIRead_i.sv b/src/AXI/AXIRead_i.sv index 497d580..9632b3e 100644 --- a/src/AXI/AXIRead_i.sv +++ b/src/AXI/AXIRead_i.sv @@ -6,4 +6,4 @@ interface AXIRead_i; modport master(input AXIReadData, output AXIReadAddr); modport slave(input AXIReadAddr, output AXIReadData); -endinterface //AXIRead \ No newline at end of file +endinterface //AXIRead diff --git a/src/AXI/AXIWrite_i.sv b/src/AXI/AXIWrite_i.sv index 1ab4052..b50786f 100644 --- a/src/AXI/AXIWrite_i.sv +++ b/src/AXI/AXIWrite_i.sv @@ -6,4 +6,4 @@ interface AXIWrite_i; modport master(input AXIWriteData, output AXIWriteAddr); modport slave(input AXIWriteAddr, output AXIWriteData); -endinterface //AXIWrite \ No newline at end of file +endinterface //AXIWrite diff --git a/src/Cache/DCache.sv b/src/Cache/DCache.sv index ca28e62..9d5ba3e 100644 --- a/src/Cache/DCache.sv +++ b/src/Cache/DCache.sv @@ -206,12 +206,16 @@ module DCache ( always_ff @(posedge clk) begin if (rst) begin for (integer i = 0; i < 128; i++) +`ifndef VERILATOR LRU[i] <= 4'b0; +`else + LRU[i] = 4'b0; +`endif end else begin if (port.req) begin if (state != IDLE) - LRU[index1] = nextLRU; - nowLRU = LRU[port.index]; + LRU[index1] <= nextLRU; + nowLRU <= LRU[port.index]; end end end diff --git a/src/Cache/DCache_i.sv b/src/Cache/DCache_i.sv index 34e064d..76d2b8b 100644 --- a/src/Cache/DCache_i.sv +++ b/src/Cache/DCache_i.sv @@ -34,4 +34,4 @@ interface DCache_i; input hit, dirt_valid, dirt_addr, dirt_data, row, output clear, clearIdx, clearWb ); -endinterface //DCache_i \ No newline at end of file +endinterface //DCache_i diff --git a/src/Cache/ICache.sv b/src/Cache/ICache.sv index 0c305d7..f6cd622 100644 --- a/src/Cache/ICache.sv +++ b/src/Cache/ICache.sv @@ -149,8 +149,8 @@ module ICache ( always_ff @(posedge clk) begin if (port.req) begin if (state != IDLE) - LRU[index1] = nextLRU; - nowLRU = LRU[port.index]; + LRU[index1] <= nextLRU; + nowLRU <= LRU[port.index]; end end diff --git a/src/Cache/ICache_i.sv b/src/Cache/ICache_i.sv index 4957cc7..9c281b5 100644 --- a/src/Cache/ICache_i.sv +++ b/src/Cache/ICache_i.sv @@ -26,4 +26,4 @@ interface ICache_i; output rvalid, rdata, output clear, clearIdx ); -endinterface //ICache_i \ No newline at end of file +endinterface //ICache_i diff --git a/src/Core/ALU.sv b/src/Core/ALU.sv index b8b5582..82fab76 100644 --- a/src/Core/ALU.sv +++ b/src/Core/ALU.sv @@ -11,13 +11,17 @@ module ALU( wire logic [4:0] sa = a[4:0]; wire logic ex = alt & b[31]; wire word_t sl = b << sa; + /* verilator lint_off WIDTH */ wire word_t sr = {{31{ex}}, b} >> sa; + /* verilator lint_on WIDTH */ wire word_t b2 = alt ? ~b : b; wire word_t sum; wire logic lt, ltu; + /* verilator lint_off WIDTH */ assign {lt, ltu, sum} = {a[31], 1'b0, a} + {b2[31], 1'b1, b2} + alt; // alt for cin(CARRY4) at synthesis + /* verilator lint_on WIDTH */ assign aluout = (aluctrl.f_sl ? sl : 32'b0) | (aluctrl.f_sr ? sr : 32'b0) | (aluctrl.f_add ? sum : 32'b0) diff --git a/src/Core/Datapath.sv b/src/Core/Datapath.sv index 26e75aa..3c1e3dd 100644 --- a/src/Core/Datapath.sv +++ b/src/Core/Datapath.sv @@ -549,11 +549,11 @@ module Datapath ( // TODO: CACHE | D.IA.MCtrl1.TLBR & D.IB.MCtrl0.C0W | D.IA.MCtrl1.TLBP & D.IB.MCtrl0.C0W - | D.IA.MCtrl1.TLBR & D.IB.WCtrl.RW & D.IB.MCtrl0.C0D == C0_ENTRYHI & D.IB.MCtrl0.RS0 == C0 - | D.IA.MCtrl1.TLBR & D.IB.WCtrl.RW & D.IB.MCtrl0.C0D == C0_ENTRYLO0 & D.IB.MCtrl0.RS0 == C0 - | D.IA.MCtrl1.TLBR & D.IB.WCtrl.RW & D.IB.MCtrl0.C0D == C0_ENTRYLO1 & D.IB.MCtrl0.RS0 == C0 - // | D.IA.MCtrl1.TLBR & D.IB.WCtrl.RW & D.IB.MCtrl0.C0D == C0_PAGEMASK & D.IB.MCtrl0.RS0 == C0 - | D.IA.MCtrl1.TLBP & D.IB.WCtrl.RW & D.IB.MCtrl0.C0D == C0_INDEX & D.IB.MCtrl0.RS0 == C0 + | D.IA.MCtrl1.TLBR & D.IB.WCtrl.RW & D.IB.MCtrl0.C0D == C0_ENTRYHI & D.IB.MCtrl0.RS0 == RS0_C0 + | D.IA.MCtrl1.TLBR & D.IB.WCtrl.RW & D.IB.MCtrl0.C0D == C0_ENTRYLO0 & D.IB.MCtrl0.RS0 == RS0_C0 + | D.IA.MCtrl1.TLBR & D.IB.WCtrl.RW & D.IB.MCtrl0.C0D == C0_ENTRYLO1 & D.IB.MCtrl0.RS0 == RS0_C0 + // | D.IA.MCtrl1.TLBR & D.IB.WCtrl.RW & D.IB.MCtrl0.C0D == C0_PAGEMASK & D.IB.MCtrl0.RS0 == RS0_C0 + | D.IA.MCtrl1.TLBP & D.IB.WCtrl.RW & D.IB.MCtrl0.C0D == C0_INDEX & D.IB.MCtrl0.RS0 == RS0_C0 // Hazards Related to Exceptions or Interrupts | D.IA.MCtrl0.C0W & D.IB.ERET & D.IA.MCtrl0.C0D == C0_EPC ; diff --git a/src/Core/Gadgets/memoutput.sv b/src/Core/Gadgets/memoutput.sv index 03220b6..fdef24d 100644 --- a/src/Core/Gadgets/memoutput.sv +++ b/src/Core/Gadgets/memoutput.sv @@ -57,4 +57,4 @@ module memoutput ( end default: begin wstrb = 4'b0000; end endcase -endmodule \ No newline at end of file +endmodule diff --git a/src/MMU/SRAM_RO_AXI_i.sv b/src/MMU/SRAM_RO_AXI_i.sv index 3fb72d7..de3af4c 100644 --- a/src/MMU/SRAM_RO_AXI_i.sv +++ b/src/MMU/SRAM_RO_AXI_i.sv @@ -14,4 +14,4 @@ interface SRAM_RO_AXI_i; modport master(output req, addr, len, size, input addr_ok, data_ok, rdata, rvalid); modport slave(input req, addr, len, size, output addr_ok, data_ok, rdata, rvalid); -endinterface \ No newline at end of file +endinterface diff --git a/src/MMU/SRAM_W_AXI_i.sv b/src/MMU/SRAM_W_AXI_i.sv index f9c0450..ea5df08 100644 --- a/src/MMU/SRAM_W_AXI_i.sv +++ b/src/MMU/SRAM_W_AXI_i.sv @@ -17,4 +17,4 @@ interface SRAM_W_AXI_i; modport master(output req, addr, len, size, wstrb, wdata, wvalid, wlast, input addr_ok, data_ok, wready); modport slave(input req, addr, len, size, wstrb, wdata, wvalid, wlast, output addr_ok, data_ok, wready); -endinterface \ No newline at end of file +endinterface diff --git a/src/MMU/TLB.sv b/src/MMU/TLB.sv index fcac3e1..9c03ab6 100644 --- a/src/MMU/TLB.sv +++ b/src/MMU/TLB.sv @@ -118,6 +118,7 @@ module TLB ( // IF vaddr -> paddr assign fVAddr = iVAddr; + /* verilator lint_off PINCONNECTEMPTY */ TLB_Lookup Lookup_F ( .TLB_entries(TLB_entries), .VPN(fVAddr[31:12]), @@ -130,6 +131,7 @@ module TLB ( .valid(fValid), .index() ); + /* verilator lint_on PINCONNECTEMPTY */ // Output ffenr #(55) inst_ff( diff --git a/src/MMU/sram_i.sv b/src/MMU/sram_i.sv index d4554b2..13e9bed 100644 --- a/src/MMU/sram_i.sv +++ b/src/MMU/sram_i.sv @@ -14,4 +14,4 @@ interface sram_i (); modport master(output req, wr, addr, size, wstrb, wdata, input addr_ok, data_ok, rdata); modport slave(input req, wr, addr, size, wstrb, wdata, output addr_ok, data_ok, rdata); -endinterface \ No newline at end of file +endinterface diff --git a/src/MMU/sramro_i.sv b/src/MMU/sramro_i.sv index 6ccf12e..80de7a0 100644 --- a/src/MMU/sramro_i.sv +++ b/src/MMU/sramro_i.sv @@ -12,4 +12,4 @@ interface sramro_i (); modport master(output req, addr, input addr_ok, data_ok, rdata0, rdata1); modport slave(input req, addr, output addr_ok, data_ok, rdata0, rdata1); -endinterface \ No newline at end of file +endinterface diff --git a/src/include/CP0.svh b/src/include/CP0.svh index 405a634..52f275a 100644 --- a/src/include/CP0.svh +++ b/src/include/CP0.svh @@ -94,7 +94,7 @@ typedef struct packed { // word_t DESAVE, // ErrorEPC, // TagHi - word_t TagLo; + // TagLo; // CacheErr, // Errctl, // PerfCnt, diff --git a/src/include/defines.svh b/src/include/defines.svh index 54194b3..ac7aa86 100644 --- a/src/include/defines.svh +++ b/src/include/defines.svh @@ -57,11 +57,11 @@ typedef enum logic [1:0] { } SB_t; typedef enum logic [2:0] { - LO = 3'b000, - HI = 3'b001, - MUL = 3'b010, - C0 = 3'b011, - ALUOut = 3'b100 // 3'b1?? + RS0_LO = 3'b000, + RS0_HI = 3'b001, + RS0_MUL = 3'b010, + RS0_C0 = 3'b011, + RS0_ALUOut = 3'b100 // 3'b1?? } RS0_t; typedef enum logic [2:0] { diff --git a/src/MyCPU.sv b/src/mycpu_top.sv similarity index 100% rename from src/MyCPU.sv rename to src/mycpu_top.sv