forked from Github_Repos/cvw
Merge branch 'main' of github.com:davidharrishmc/riscv-wally into main
This commit is contained in:
commit
c79e14fec5
@ -31,7 +31,8 @@ rv64i_sc_tests = \
|
||||
WALLY-MMU-SV39 \
|
||||
WALLY-MMU-SV48 \
|
||||
WALLY-PMA \
|
||||
WALLY-PMP
|
||||
WALLY-PMP
|
||||
|
||||
|
||||
rv64i_tests = $(addsuffix .elf, $(rv64i_sc_tests))
|
||||
|
||||
|
@ -629,40 +629,6 @@ terminate_test:
|
||||
ecall # writes mcause to the output.
|
||||
csrw mtvec, x4 # restore original trap handler to halt program
|
||||
|
||||
/*
|
||||
# ---------------------------------------------------------------------------------------------
|
||||
|
||||
RVTEST_IO_WRITE_STR(x31, "Test End\n")
|
||||
|
||||
# ---------------------------------------------------------------------------------------------
|
||||
|
||||
RV_COMPLIANCE_HALT
|
||||
|
||||
RV_COMPLIANCE_CODE_END
|
||||
|
||||
# Input data section.
|
||||
.data
|
||||
|
||||
.align 3 # align stack to 8 byte boundary
|
||||
bottom_of_stack:
|
||||
.fill 1024, 4, -1
|
||||
top_of_stack:
|
||||
|
||||
|
||||
# Output data section.
|
||||
RV_COMPLIANCE_DATA_BEGIN
|
||||
|
||||
.align 3 # align output to 8 byte boundary
|
||||
test_1_res:
|
||||
.fill 1024, 4, -1
|
||||
|
||||
RV_COMPLIANCE_DATA_END
|
||||
|
||||
|
||||
.align 3
|
||||
test_cases:
|
||||
*/
|
||||
|
||||
RVTEST_CODE_END
|
||||
RVMODEL_HALT
|
||||
|
||||
@ -678,37 +644,13 @@ bottom_of_stack:
|
||||
top_of_stack:
|
||||
|
||||
|
||||
|
||||
RVMODEL_DATA_BEGIN
|
||||
|
||||
// next lines through test cases copied over from old framework
|
||||
test_1_res:
|
||||
.fill 1024, 4, -1
|
||||
|
||||
RVMODEL_DATA_END
|
||||
|
||||
|
||||
/*
|
||||
signature_x8_0:
|
||||
.fill 0*(XLEN/32),4,0xdeadbeef
|
||||
|
||||
|
||||
signature_x8_1:
|
||||
.fill 19*(XLEN/32),4,0xdeadbeef
|
||||
|
||||
|
||||
signature_x1_0:
|
||||
.fill 256*(XLEN/32),4,0xdeadbeef
|
||||
|
||||
|
||||
signature_x1_1:
|
||||
.fill 256*(XLEN/32),4,0xdeadbeef
|
||||
|
||||
|
||||
signature_x1_2:
|
||||
.fill 148*(XLEN/32),4,0xdeadbeef
|
||||
*/
|
||||
|
||||
#ifdef rvtest_mtrap_routine
|
||||
|
||||
mtrap_sigptr:
|
||||
|
@ -51,7 +51,7 @@ tc = TestCase(
|
||||
grepstr="400100000 instructions")
|
||||
configs.append(tc)
|
||||
|
||||
tests64gc = ["arch64i", "arch64priv", "arch64c", "arch64m", "arch64d", "imperas64i", "imperas64f", "imperas64d", "imperas64p", "imperas64mmu", "imperas64m", "imperas64a", "imperas64c"] # "wally64i", #, "testsBP64"]
|
||||
tests64gc = ["arch64i", "arch64priv", "arch64c", "arch64m", "arch64d", "imperas64i", "imperas64f", "imperas64d", "imperas64p", "imperas64m", "imperas64a", "imperas64c", "wally64priv"] # "wally64i", #, "testsBP64"]
|
||||
for test in tests64gc:
|
||||
tc = TestCase(
|
||||
name=test,
|
||||
@ -59,7 +59,7 @@ for test in tests64gc:
|
||||
cmd="vsim > {} -c <<!\ndo wally-pipelined-batch.do rv64gc "+test+"\n!",
|
||||
grepstr="All tests ran without failures")
|
||||
configs.append(tc)
|
||||
tests32gc = ["arch32i", "arch32priv", "arch32c", "arch32m", "arch32f", "imperas32i", "imperas32f", "imperas32p", "imperas32mmu", "imperas32m", "imperas32a", "imperas32c"] #"wally32i",
|
||||
tests32gc = ["arch32i", "arch32priv", "arch32c", "arch32m", "arch32f", "imperas32i", "imperas32f", "imperas32p", "imperas32m", "imperas32a", "imperas32c", "wally32priv"] #"wally32i",
|
||||
for test in tests32gc:
|
||||
tc = TestCase(
|
||||
name=test,
|
||||
|
@ -1,3 +1,3 @@
|
||||
vsim -c <<!
|
||||
do wally-pipelined-batch.do rv32ic arch32i
|
||||
do wally-pipelined-batch.do rv64gc wally64priv
|
||||
!
|
||||
|
4
wally-pipelined/src/cache/cacheway.sv
vendored
4
wally-pipelined/src/cache/cacheway.sv
vendored
@ -124,7 +124,7 @@ module cacheway #(parameter NUMLINES=512, parameter BLOCKLEN = 256, TAGLEN = 26,
|
||||
assign Valid = ValidBits[RAdrD];
|
||||
|
||||
generate
|
||||
if(DIRTY_BITS) begin
|
||||
if(DIRTY_BITS) begin:dirty
|
||||
always_ff @(posedge clk) begin
|
||||
if (reset)
|
||||
DirtyBits <= {NUMLINES{1'b0}};
|
||||
@ -139,7 +139,7 @@ module cacheway #(parameter NUMLINES=512, parameter BLOCKLEN = 256, TAGLEN = 26,
|
||||
|
||||
assign Dirty = DirtyBits[RAdrD];
|
||||
|
||||
end else begin
|
||||
end else begin:dirty
|
||||
assign Dirty = 1'b0;
|
||||
end
|
||||
endgenerate
|
||||
|
6
wally-pipelined/src/cache/dcache.sv
vendored
6
wally-pipelined/src/cache/dcache.sv
vendored
@ -142,7 +142,7 @@ module dcache
|
||||
.InvalidateAll(1'b0));
|
||||
|
||||
generate
|
||||
if(NUMWAYS > 1) begin
|
||||
if(NUMWAYS > 1) begin:vict
|
||||
cachereplacementpolicy #(NUMWAYS, INDEXLEN, OFFSETLEN, NUMLINES)
|
||||
cachereplacementpolicy(.clk, .reset,
|
||||
.WayHit,
|
||||
@ -150,7 +150,7 @@ module dcache
|
||||
.LsuPAdrM(LsuPAdrM[INDEXLEN+OFFSETLEN-1:OFFSETLEN]),
|
||||
.RAdr,
|
||||
.LRUWriteEn);
|
||||
end else begin
|
||||
end else begin:vict
|
||||
assign VictimWay = 1'b1; // one hot.
|
||||
end
|
||||
endgenerate
|
||||
@ -171,7 +171,7 @@ module dcache
|
||||
// *** consider using a limited range shift to do this final muxing.
|
||||
genvar index;
|
||||
generate
|
||||
for (index = 0; index < WORDSPERLINE; index++) begin
|
||||
for (index = 0; index < WORDSPERLINE; index++) begin:readdatablocksetsmux
|
||||
assign ReadDataBlockSetsM[index] = ReadDataLineM[((index+1)*`XLEN)-1: (index*`XLEN)];
|
||||
end
|
||||
endgenerate
|
||||
|
6
wally-pipelined/src/cache/icache.sv
vendored
6
wally-pipelined/src/cache/icache.sv
vendored
@ -140,7 +140,7 @@ module icache
|
||||
.InvalidateAll(InvalidateICacheM));
|
||||
|
||||
generate
|
||||
if(NUMWAYS > 1) begin
|
||||
if(NUMWAYS > 1) begin:vict
|
||||
cachereplacementpolicy #(NUMWAYS, INDEXLEN, OFFSETLEN, NUMLINES)
|
||||
cachereplacementpolicy(.clk, .reset,
|
||||
.WayHit,
|
||||
@ -148,7 +148,7 @@ module icache
|
||||
.LsuPAdrM(FinalPCPF[INDEXLEN+OFFSETLEN-1:OFFSETLEN]),
|
||||
.RAdr,
|
||||
.LRUWriteEn);
|
||||
end else begin
|
||||
end else begin:vict
|
||||
assign VictimWay = 1'b1; // one hot.
|
||||
end
|
||||
endgenerate
|
||||
@ -162,7 +162,7 @@ module icache
|
||||
|
||||
genvar index;
|
||||
generate
|
||||
for(index = 0; index < BLOCKLEN / 16 - 1; index++) begin
|
||||
for(index = 0; index < BLOCKLEN / 16 - 1; index++) begin:readlinesetsmux
|
||||
assign ReadLineSetsF[index] = ReadLineF[((index+1)*16)+16-1 : (index*16)];
|
||||
end
|
||||
assign ReadLineSetsF[BLOCKLEN/16-1] = {16'b0, ReadLineF[BLOCKLEN-1:BLOCKLEN-16]};
|
||||
|
@ -57,11 +57,11 @@ module amoalu (
|
||||
|
||||
// sign extend if necessary
|
||||
generate
|
||||
if (`XLEN == 32) begin
|
||||
if (`XLEN == 32) begin:sext
|
||||
assign a = srca;
|
||||
assign b = srcb;
|
||||
assign result = y;
|
||||
end else begin // `XLEN = 64
|
||||
end else begin:sext // `XLEN = 64
|
||||
always_comb
|
||||
if (width == 2'b10) begin // sign-extend word-length operations
|
||||
// *** it would be more efficient to look at carry out of bit 31 to determine comparisons than do this big mux on and b
|
||||
|
@ -809,11 +809,12 @@ module resultselect(
|
||||
);
|
||||
logic [`FLEN-1:0] XNaNResult, YNaNResult, ZNaNResult, InvalidResult, OverflowResult, KillProdResult, UnderflowResult; // possible results
|
||||
|
||||
generate if(`IEEE754) begin
|
||||
generate
|
||||
if(`IEEE754) begin:nan
|
||||
assign XNaNResult = FmtM ? {XSgnM, XExpM, 1'b1, XManM[`NF-2:0]} : {{32{1'b1}}, XSgnM, XExpM[7:0], 1'b1, XManM[50:29]};
|
||||
assign YNaNResult = FmtM ? {YSgnM, YExpM, 1'b1, YManM[`NF-2:0]} : {{32{1'b1}}, YSgnM, YExpM[7:0], 1'b1, YManM[50:29]};
|
||||
assign ZNaNResult = FmtM ? {ZSgnEffM, ZExpM, 1'b1, ZManM[`NF-2:0]} : {{32{1'b1}}, ZSgnEffM, ZExpM[7:0], 1'b1, ZManM[50:29]};
|
||||
end else begin
|
||||
end else begin:nan
|
||||
assign XNaNResult = FmtM ? {1'b0, XExpM, 1'b1, 51'b0} : {{32{1'b1}}, 1'b0, XExpM[7:0], 1'b1, 22'b0};
|
||||
assign YNaNResult = FmtM ? {1'b0, YExpM, 1'b1, 51'b0} : {{32{1'b1}}, 1'b0, YExpM[7:0], 1'b1, 22'b0};
|
||||
assign ZNaNResult = FmtM ? {1'b0, ZExpM, 1'b1, 51'b0} : {{32{1'b1}}, 1'b0, ZExpM[7:0], 1'b1, 22'b0};
|
||||
|
@ -182,12 +182,12 @@ module controller(
|
||||
// Ordinary fence is presently a nop
|
||||
// FENCE.I flushes the D$ and invalidates the I$ if Zifencei is supported and I$ is implemented
|
||||
generate
|
||||
if (`ZIFENCEI_SUPPORTED & `MEM_ICACHE) begin
|
||||
if (`ZIFENCEI_SUPPORTED & `MEM_ICACHE) begin:fencei
|
||||
logic FenceID;
|
||||
assign FenceID = FenceD & (Funct3D == 3'b001); // is it a FENCE.I instruction?
|
||||
assign InvalidateICacheD = FenceID;
|
||||
assign FlushDCacheD = FenceID;
|
||||
end else begin
|
||||
end else begin:fencei
|
||||
assign InvalidateICacheD = 0;
|
||||
assign FlushDCacheD = 0;
|
||||
end
|
||||
|
@ -128,7 +128,7 @@ module datapath (
|
||||
if (`F_SUPPORTED) begin:fpmux
|
||||
mux2 #(`XLEN) resultmuxM(IEUResultM, FIntResM, FWriteIntM, ResultM);
|
||||
mux2 #(`XLEN) writedatamux(ForwardedSrcBE, FWriteDataE, ~IllegalFPUInstrE, WriteDataE);
|
||||
end else begin
|
||||
end else begin:fpmux
|
||||
assign ResultM = IEUResultM;
|
||||
assign WriteDataE = ForwardedSrcBE;
|
||||
end
|
||||
|
@ -39,10 +39,10 @@ module decompress (
|
||||
|
||||
// if the system handles compressed instructions, decode appropriately
|
||||
generate
|
||||
if (!(`C_SUPPORTED)) begin // no compressed mode
|
||||
if (!(`C_SUPPORTED)) begin:decompress // no compressed mode
|
||||
assign InstrD = InstrRawD;
|
||||
assign IllegalCompInstrD = 0;
|
||||
end else begin // COMPRESSED mode supported
|
||||
end else begin : decompress // COMPRESSED mode supported
|
||||
assign instr16 = InstrRawD[15:0]; // instruction is alreay aligned
|
||||
assign op = instr16[1:0];
|
||||
assign rds1 = instr16[11:7];
|
||||
|
@ -109,10 +109,10 @@ module ifu (
|
||||
|
||||
|
||||
generate
|
||||
if (`XLEN==32) begin
|
||||
if (`XLEN==32) begin:pcnextfphys
|
||||
//assign PCPF = PCPFmmu[31:0];
|
||||
assign PCNextFPhys = {{(`PA_BITS-`XLEN){1'b0}}, PCNextF};
|
||||
end else begin
|
||||
end else begin:pcnextfphys
|
||||
//assign PCPF = {8'b0, PCPFmmu};
|
||||
assign PCNextFPhys = PCNextF[`PA_BITS-1:0];
|
||||
end
|
||||
|
@ -257,11 +257,11 @@ module lsu
|
||||
// Move generate from lrsc to outside this module.
|
||||
// use PreLsu as prefix for lrsc
|
||||
generate
|
||||
if (`A_SUPPORTED) begin
|
||||
if (`A_SUPPORTED) begin:lrsc
|
||||
assign MemReadM = PreLsuRWM[1] & ~(IgnoreRequest) & ~DTLBMissM;
|
||||
lrsc lrsc(.clk, .reset, .FlushW, .CPUBusy, .MemReadM, .PreLsuRWM, .LsuAtomicM, .LsuPAdrM,
|
||||
.SquashSCW, .LsuRWM);
|
||||
end else begin
|
||||
end else begin:lrsc
|
||||
assign SquashSCW = 0;
|
||||
assign LsuRWM = PreLsuRWM;
|
||||
end
|
||||
|
@ -39,7 +39,7 @@ module subwordread
|
||||
// Funct3M[1:0] is the size of the memory access.
|
||||
|
||||
generate
|
||||
if (`XLEN == 64) begin
|
||||
if (`XLEN == 64) begin:swrmux
|
||||
// ByteMe mux
|
||||
always_comb
|
||||
case(LsuPAdrM[2:0])
|
||||
@ -82,7 +82,7 @@ module subwordread
|
||||
3'b110: ReadDataM = {32'b0, WordM[31:0]}; // lwu
|
||||
default: ReadDataM = ReadDataWordMuxM; // Shouldn't happen
|
||||
endcase
|
||||
end else begin // 32-bit
|
||||
end else begin :swrmux // 32-bit
|
||||
// byte mux
|
||||
always_comb
|
||||
case(LsuPAdrM[1:0])
|
||||
|
@ -55,7 +55,7 @@ module hptw
|
||||
LEAF, IDLE} statetype; // *** placed outside generate statement to remove synthesis errors
|
||||
|
||||
generate
|
||||
if (`MEM_VIRTMEM) begin
|
||||
if (`MEM_VIRTMEM) begin:virtmem
|
||||
logic DTLBWalk; // register TLBs translation miss requests
|
||||
logic [`PPN_BITS-1:0] BasePageTablePPN;
|
||||
logic [`PPN_BITS-1:0] CurrentPPN;
|
||||
|
@ -91,7 +91,7 @@ module mmu #(parameter TLB_ENTRIES = 8, // number of TLB Entries
|
||||
|
||||
// only instantiate TLB if Virtual Memory is supported
|
||||
generate
|
||||
if (`MEM_VIRTMEM) begin
|
||||
if (`MEM_VIRTMEM) begin:tlb
|
||||
logic ReadAccess, WriteAccess;
|
||||
assign ReadAccess = ExecuteAccessF | ReadAccessM; // execute also acts as a TLB read. Execute and Read are never active for the same MMU, so safe to mix pipestages
|
||||
assign WriteAccess = WriteAccessM;
|
||||
@ -101,7 +101,7 @@ module mmu #(parameter TLB_ENTRIES = 8, // number of TLB Entries
|
||||
.VAdr,
|
||||
.*);
|
||||
|
||||
end else begin // just pass address through as physical
|
||||
end else begin:tlb// just pass address through as physical
|
||||
assign Translate = 0;
|
||||
assign TLBMiss = 0;
|
||||
assign TLBHit = 1; // *** is this necessary
|
||||
@ -117,18 +117,7 @@ module mmu #(parameter TLB_ENTRIES = 8, // number of TLB Entries
|
||||
///////////////////////////////////////////
|
||||
|
||||
pmachecker pmachecker(.*);
|
||||
|
||||
// if the number of entries is zero or no csr no pmp checker
|
||||
generate
|
||||
if(`PMP_ENTRIES > 0) begin : pmpchecker
|
||||
pmpchecker pmpchecker(.*);
|
||||
end else begin
|
||||
assign PMPInstrAccessFaultF = 1'b0;
|
||||
assign PMPLoadAccessFaultM = 1'b0;
|
||||
assign PMPStoreAccessFaultM = 1'b0;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
pmpchecker pmpchecker(.*);
|
||||
|
||||
// If TLB miss and translating we want to not have faults from the PMA and PMP checkers.
|
||||
// assign SquashBusAccess = PMASquashBusAccess | PMPSquashBusAccess;
|
||||
|
@ -73,6 +73,10 @@ module pmpchecker (
|
||||
assign PMPInstrAccessFaultF = EnforcePMP && ExecuteAccessF && ~|X;
|
||||
assign PMPStoreAccessFaultM = EnforcePMP && WriteAccessM && ~|W;
|
||||
assign PMPLoadAccessFaultM = EnforcePMP && ReadAccessM && ~|R;
|
||||
end else begin: pmpchecker // no checker
|
||||
assign PMPInstrAccessFaultF = 0;
|
||||
assign PMPLoadAccessFaultM = 0;
|
||||
assign PMPStoreAccessFaultM = 0;
|
||||
end
|
||||
endgenerate
|
||||
//assign PMPSquashBusAccess = PMPInstrAccessFaultF | PMPLoadAccessFaultM | PMPStoreAccessFaultM;
|
||||
|
@ -61,7 +61,7 @@ module tlbcamline #(parameter KEY_BITS = 20,
|
||||
assign MatchASID = (SATP_ASID == Key_ASID) | PTE_G;
|
||||
|
||||
generate
|
||||
if (`XLEN == 32) begin
|
||||
if (`XLEN == 32) begin:match
|
||||
|
||||
assign {Key_ASID, Key1, Key0} = Key;
|
||||
assign {Query1, Query0} = VPN;
|
||||
@ -73,7 +73,7 @@ module tlbcamline #(parameter KEY_BITS = 20,
|
||||
assign Match1 = (Query1 == Key1);
|
||||
|
||||
assign Match = Match0 & Match1 & MatchASID & Valid;
|
||||
end else begin
|
||||
end else begin:match
|
||||
|
||||
logic [SEGMENT_BITS-1:0] Key2, Key3, Query2, Query3;
|
||||
logic Match2, Match3;
|
||||
|
@ -65,7 +65,7 @@ module tlbcontrol #(parameter ITLB = 0) (
|
||||
assign EffectivePrivilegeMode = (ITLB == 1) ? PrivilegeModeW : (STATUS_MPRV ? STATUS_MPP : PrivilegeModeW); // DTLB uses MPP mode when MPRV is 1
|
||||
assign Translate = (SATP_MODE != `NO_TRANSLATE) & (EffectivePrivilegeMode != `M_MODE) & ~DisableTranslation;
|
||||
generate
|
||||
if (`XLEN==64) begin
|
||||
if (`XLEN==64) begin:rv64
|
||||
assign SV39Mode = (SATP_MODE == `SV39);
|
||||
// generate page fault if upper bits aren't all the same
|
||||
logic UpperEqual39, UpperEqual48;
|
||||
@ -90,7 +90,7 @@ module tlbcontrol #(parameter ITLB = 0) (
|
||||
|
||||
// Check whether the access is allowed, page faulting if not.
|
||||
generate
|
||||
if (ITLB == 1) begin // Instruction TLB fault checking
|
||||
if (ITLB == 1) begin:itlb // Instruction TLB fault checking
|
||||
logic ImproperPrivilege;
|
||||
|
||||
// User mode may only execute user mode pages, and supervisor mode may
|
||||
@ -100,7 +100,7 @@ module tlbcontrol #(parameter ITLB = 0) (
|
||||
// fault for software handling if access bit is off
|
||||
assign DAPageFault = ~PTE_A;
|
||||
assign TLBPageFault = (Translate && TLBHit && (ImproperPrivilege || ~PTE_X || DAPageFault || UpperBitsUnequalPageFault | Misaligned | ~PTE_V));
|
||||
end else begin // Data TLB fault checking
|
||||
end else begin:dtlb // Data TLB fault checking
|
||||
logic ImproperPrivilege, InvalidRead, InvalidWrite;
|
||||
|
||||
// User mode may only load/store from user mode pages, and supervisor mode
|
||||
|
@ -61,7 +61,7 @@ module intdivrestoring (
|
||||
|
||||
// Handle sign extension for W-type instructions
|
||||
generate
|
||||
if (`XLEN == 64) begin // RV64 has W-type instructions
|
||||
if (`XLEN == 64) begin:rv64 // RV64 has W-type instructions
|
||||
mux2 #(`XLEN) xinmux(ForwardedSrcAE, {ForwardedSrcAE[31:0], 32'b0}, W64E, XinE);
|
||||
mux2 #(`XLEN) dinmux(ForwardedSrcBE, {{32{ForwardedSrcBE[31]&DivSignedE}}, ForwardedSrcBE[31:0]}, W64E, DinE);
|
||||
end else begin // RV32 has no W-type instructions
|
||||
|
@ -39,21 +39,20 @@ module redundantmul #(parameter WIDTH =8)(
|
||||
|
||||
//
|
||||
|
||||
generate
|
||||
if (`DESIGN_COMPILER == 1)
|
||||
begin
|
||||
logic [2*WIDTH-1+2:0] tmp_out0; // DW02_
|
||||
logic [2*WIDTH-1+2:0] tmp_out1;
|
||||
DW02_multp #(WIDTH, WIDTH, 2*WIDTH+2) mul(.a, .b, .tc(1'b0), .out0(tmp_out0), .out1(tmp_out1));
|
||||
assign out0 = tmp_out0[2*WIDTH-1:0];
|
||||
assign out1 = tmp_out1[2*WIDTH-1:0];
|
||||
end
|
||||
else if (`DESIGN_COMPILER == 2)
|
||||
mult_cs #(WIDTH) mul(.a, .b, .tc(1'b0), .sum(out0), .carry(out1));
|
||||
else begin // force a nonredunant multipler. This will simulate properly and also is appropriate for FPGAs.
|
||||
assign out0 = a * b;
|
||||
assign out1 = 0;
|
||||
end
|
||||
generate
|
||||
if (`DESIGN_COMPILER == 1) begin:mul
|
||||
logic [2*WIDTH-1+2:0] tmp_out0;
|
||||
logic [2*WIDTH-1+2:0] tmp_out1;
|
||||
|
||||
DW02_multp #(WIDTH, WIDTH, 2*WIDTH+2) mul(.a, .b, .tc(1'b0), .out0(tmp_out0), .out1(tmp_out1));
|
||||
assign out0 = tmp_out0[2*WIDTH-1:0];
|
||||
assign out1 = tmp_out1[2*WIDTH-1:0];
|
||||
end else if (`DESIGN_COMPILER == 2) begin:mul // *** need to remove this
|
||||
mult_cs #(WIDTH) mul(.a, .b, .tc(1'b0), .sum(out0), .carry(out1));
|
||||
end else begin:mul // force a nonredunant multipler. This will simulate properly and also is appropriate for FPGAs.
|
||||
assign out0 = a * b;
|
||||
assign out1 = 0;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
||||
|
@ -91,7 +91,7 @@ module csrc #(parameter
|
||||
);
|
||||
|
||||
generate
|
||||
if (`ZICOUNTERS_SUPPORTED) begin
|
||||
if (`ZICOUNTERS_SUPPORTED) begin:counters
|
||||
(* mark_debug = "true" *) logic [63:0] CYCLE_REGW, INSTRET_REGW;
|
||||
logic [63:0] CYCLEPlusM, INSTRETPlusM;
|
||||
logic [`XLEN-1:0] NextCYCLEM, NextINSTRETM;
|
||||
@ -114,7 +114,7 @@ module csrc #(parameter
|
||||
assign NextINSTRETM = WriteINSTRETM ? CSRWriteValM : INSTRETPlusM[`XLEN-1:0];
|
||||
|
||||
// parameterized number of additional counters
|
||||
if (`COUNTERS > 3) begin
|
||||
if (`COUNTERS > 3) begin:cntarry
|
||||
logic [`COUNTERS-1:3] WriteHPMCOUNTERM;
|
||||
logic [`COUNTERS-1:0] CounterEvent;
|
||||
logic [63:0] /*HPMCOUNTER_REGW[`COUNTERS-1:3], */ HPMCOUNTERPlusM[`COUNTERS-1:3];
|
||||
@ -171,10 +171,10 @@ module csrc #(parameter
|
||||
|
||||
// Write / update counters
|
||||
// Only the Machine mode versions of the counter CSRs are writable
|
||||
if (`XLEN==64) begin// 64-bit counters
|
||||
if (`XLEN==64) begin:cntreg// 64-bit counters
|
||||
flopr #(64) CYCLEreg(clk, reset, NextCYCLEM, CYCLE_REGW);
|
||||
flopr #(64) INSTRETreg(clk, reset, NextINSTRETM, INSTRET_REGW);
|
||||
end else begin // 32-bit low and high counters
|
||||
end else begin:cntreg // 32-bit low and high counters
|
||||
logic WriteTIMEHM, WriteTIMECMPHM, WriteCYCLEHM, WriteINSTRETHM;
|
||||
logic [`XLEN-1:0] NextCYCLEHM, NextTIMEHM, NextINSTRETHM;
|
||||
|
||||
|
@ -71,10 +71,10 @@ module csri #(parameter
|
||||
// SEIP, STIP, SSIP is writable in MIP if S mode exists
|
||||
// SSIP is writable in SIP if S mode exists
|
||||
generate
|
||||
if (`S_SUPPORTED) begin
|
||||
if (`S_SUPPORTED) begin:mask
|
||||
assign MIP_WRITE_MASK = 12'h222; // SEIP, STIP, SSIP are writable in MIP (20210108-draft 3.1.9)
|
||||
assign SIP_WRITE_MASK = 12'h002; // SSIP is writable in SIP (privileged 20210108-draft 4.1.3)
|
||||
end else begin
|
||||
end else begin:mask
|
||||
assign MIP_WRITE_MASK = 12'h000;
|
||||
assign SIP_WRITE_MASK = 12'h000;
|
||||
end
|
||||
@ -93,7 +93,7 @@ module csri #(parameter
|
||||
|
||||
// restricted views of registers
|
||||
generate
|
||||
always_comb begin
|
||||
always_comb begin:regs
|
||||
// Add MEIP read-only signal
|
||||
IP_REGW = {IntInM[11],1'b0,IP_REGW_writeable};
|
||||
|
||||
|
@ -50,7 +50,7 @@ module csrn #(parameter
|
||||
|
||||
// User mode CSRs below only needed when user mode traps are supported
|
||||
generate
|
||||
if (`N_SUPPORTED) begin
|
||||
if (`N_SUPPORTED) begin:nmode
|
||||
logic WriteUTVECM;
|
||||
logic WriteUSCRATCHM, WriteUEPCM;
|
||||
logic WriteUCAUSEM, WriteUTVALM;
|
||||
|
@ -70,7 +70,7 @@ module csrs #(parameter
|
||||
|
||||
// Supervisor mode CSRs sometimes supported
|
||||
generate
|
||||
if (`S_SUPPORTED) begin
|
||||
if (`S_SUPPORTED) begin:csrs
|
||||
logic WriteSTVECM;
|
||||
logic WriteSSCRATCHM, WriteSEPCM;
|
||||
logic WriteSCAUSEM, WriteSTVALM, WriteSATPM, WriteSCOUNTERENM;
|
||||
@ -96,13 +96,14 @@ module csrs #(parameter
|
||||
flopenr #(`XLEN) SATPreg(clk, reset, WriteSATPM, CSRWriteValM, SATP_REGW);
|
||||
else
|
||||
assign SATP_REGW = 0; // hardwire to zero if virtual memory not supported
|
||||
if (`BUSYBEAR == 1)
|
||||
if (`BUSYBEAR == 1) begin:scounteren
|
||||
flopenr #(32) SCOUNTERENreg(clk, reset, WriteSCOUNTERENM, {CSRWriteValM[31:2],1'b0,CSRWriteValM[0]}, SCOUNTEREN_REGW);
|
||||
else if (`BUILDROOT == 1)
|
||||
end else if (`BUILDROOT == 1) begin:scounteren
|
||||
flopenr #(32) SCOUNTERENreg(clk, reset, WriteSCOUNTERENM, CSRWriteValM[31:0], SCOUNTEREN_REGW);
|
||||
else
|
||||
end else begin:scounteren
|
||||
flopens #(32) SCOUNTERENreg(clk, reset, WriteSCOUNTERENM, CSRWriteValM[31:0], SCOUNTEREN_REGW);
|
||||
if (`N_SUPPORTED) begin
|
||||
end
|
||||
if (`N_SUPPORTED) begin:nregs
|
||||
logic WriteSEDELEGM, WriteSIDELEGM;
|
||||
assign WriteSEDELEGM = CSRSWriteM && (CSRAdrM == SEDELEG);
|
||||
assign WriteSIDELEGM = CSRSWriteM && (CSRAdrM == SIDELEG);
|
||||
@ -114,7 +115,7 @@ module csrs #(parameter
|
||||
end
|
||||
|
||||
// CSR Reads
|
||||
always_comb begin
|
||||
always_comb begin:csrr
|
||||
IllegalCSRSAccessM = !(`N_SUPPORTED) && (CSRAdrM == SEDELEG || CSRAdrM == SIDELEG); // trap on DELEG register access when no N-mode
|
||||
case (CSRAdrM)
|
||||
SSTATUS: CSRSReadValM = SSTATUS_REGW;
|
||||
|
@ -45,7 +45,7 @@ module csru #(parameter
|
||||
|
||||
// Floating Point CSRs in User Mode only needed if Floating Point is supported
|
||||
generate
|
||||
if (`F_SUPPORTED | `D_SUPPORTED) begin
|
||||
if (`F_SUPPORTED | `D_SUPPORTED) begin:csru
|
||||
logic [4:0] FFLAGS_REGW;
|
||||
logic [2:0] NextFRMM;
|
||||
logic [4:0] NextFFLAGSM;
|
||||
|
@ -104,7 +104,7 @@ module trap (
|
||||
// For example, we could require m/stvec be aligned on 7 bits to let us replace the adder directly below with
|
||||
// [untested] PrivilegedVectoredTrapVector = {PrivilegedTrapVector[`XLEN-1:7], CauseM[3:0], 4'b0000}
|
||||
generate
|
||||
if(`VECTORED_INTERRUPTS_SUPPORTED) begin
|
||||
if(`VECTORED_INTERRUPTS_SUPPORTED) begin:vec
|
||||
always_comb
|
||||
if (PrivilegedTrapVector[1:0] == 2'b01 && CauseM[`XLEN-1] == 1)
|
||||
PrivilegedVectoredTrapVector = {PrivilegedTrapVector[`XLEN-1:2] + {CauseM[`XLEN-5:0], 2'b00}, 2'b00};
|
||||
|
@ -69,7 +69,7 @@ module clint (
|
||||
|
||||
// register access
|
||||
generate
|
||||
if (`XLEN==64) begin
|
||||
if (`XLEN==64) begin:clint
|
||||
always @(posedge HCLK) begin
|
||||
case(entry)
|
||||
16'h0000: HREADCLINT <= {63'b0, MSIP};
|
||||
@ -97,7 +97,7 @@ module clint (
|
||||
// MTIME Counter. Eventually change this to run off separate clock. Synchronization then needed
|
||||
MTIME <= HWDATA;
|
||||
end else MTIME <= MTIME + 1;
|
||||
end else begin // 32-bit
|
||||
end else begin:clint // 32-bit
|
||||
always @(posedge HCLK) begin
|
||||
case(entry)
|
||||
16'h0000: HREADCLINT <= {31'b0, MSIP};
|
||||
|
@ -62,7 +62,7 @@ module gpio (
|
||||
// -- Note GPIO registers are 32 bits no matter what; access them with LW SW.
|
||||
// (At least that's what I think when FE310 spec says "only naturally aligned 32-bit accesses are supported")
|
||||
generate
|
||||
if (`XLEN == 64) begin
|
||||
if (`XLEN == 64) begin:gpio
|
||||
always_comb
|
||||
if (entryd[2]) begin
|
||||
Din = HWDATA[63:32];
|
||||
@ -71,7 +71,7 @@ module gpio (
|
||||
Din = HWDATA[31:0];
|
||||
HREADGPIO = {32'b0,Dout};
|
||||
end
|
||||
end else begin // 32-bit
|
||||
end else begin:gpio // 32-bit
|
||||
always_comb begin
|
||||
Din = HWDATA[31:0];
|
||||
HREADGPIO = Dout;
|
||||
|
@ -78,7 +78,7 @@ module plic (
|
||||
// account for subword read/write circuitry
|
||||
// -- Note PLIC registers are 32 bits no matter what; access them with LW SW.
|
||||
generate
|
||||
if (`XLEN == 64) begin
|
||||
if (`XLEN == 64) begin:plic
|
||||
always_comb
|
||||
if (entryd[2]) begin
|
||||
Din = HWDATA[63:32];
|
||||
@ -87,7 +87,7 @@ module plic (
|
||||
Din = HWDATA[31:0];
|
||||
HREADPLIC = {32'b0,Dout};
|
||||
end
|
||||
end else begin // 32-bit
|
||||
end else begin:plic // 32-bit
|
||||
always_comb begin
|
||||
Din = HWDATA[31:0];
|
||||
HREADPLIC = Dout;
|
||||
|
@ -50,7 +50,7 @@ module ram #(parameter BASE=0, RANGE = 65535) (
|
||||
logic [3:0] busycount;
|
||||
|
||||
generate
|
||||
if(`FPGA) begin
|
||||
if(`FPGA) begin:ram
|
||||
initial begin
|
||||
//$readmemh(PRELOAD, RAM);
|
||||
// FPGA only
|
||||
@ -145,14 +145,14 @@ module ram #(parameter BASE=0, RANGE = 65535) (
|
||||
|
||||
/* verilator lint_off WIDTH */
|
||||
generate
|
||||
if (`XLEN == 64) begin
|
||||
if (`XLEN == 64) begin:ramrd
|
||||
always_ff @(posedge HCLK) begin
|
||||
HWADDR <= #1 A;
|
||||
HREADRam0 <= #1 RAM[A[31:3]];
|
||||
if (memwrite & risingHREADYRam) RAM[HWADDR[31:3]] <= #1 HWDATA;
|
||||
end
|
||||
end else begin
|
||||
always_ff @(posedge HCLK) begin
|
||||
always_ff @(posedge HCLK) begin:ramrd
|
||||
HWADDR <= #1 A;
|
||||
HREADRam0 <= #1 RAM[A[31:2]];
|
||||
if (memwrite & risingHREADYRam) RAM[HWADDR[31:2]] <= #1 HWDATA;
|
||||
|
@ -36,7 +36,7 @@ module subwordwrite (
|
||||
logic [`XLEN-1:0] WriteDataSubwordDuplicated;
|
||||
|
||||
generate
|
||||
if (`XLEN == 64) begin
|
||||
if (`XLEN == 64) begin:sww
|
||||
logic [7:0] ByteMaskM;
|
||||
// Compute write mask
|
||||
always_comb
|
||||
@ -74,7 +74,7 @@ module subwordwrite (
|
||||
if (ByteMaskM[7]) HWDATA[63:56] = WriteDataSubwordDuplicated[63:56];
|
||||
end
|
||||
|
||||
end else begin // 32-bit
|
||||
end else begin:sww // 32-bit
|
||||
logic [3:0] ByteMaskM;
|
||||
// Compute write mask
|
||||
always_comb
|
||||
|
@ -55,7 +55,7 @@ module uart (
|
||||
assign HREADYUART = 1; // should idle high during address phase and respond high when done; will need to be modified if UART ever needs more than 1 cycle to do something
|
||||
|
||||
generate
|
||||
if (`XLEN == 64) begin
|
||||
if (`XLEN == 64) begin:uart
|
||||
always_comb begin
|
||||
HREADUART = {Dout, Dout, Dout, Dout, Dout, Dout, Dout, Dout};
|
||||
case (A)
|
||||
@ -69,7 +69,7 @@ module uart (
|
||||
3'b111: Din = HWDATA[63:56];
|
||||
endcase
|
||||
end
|
||||
end else begin // 32-bit
|
||||
end else begin:uart // 32-bit
|
||||
always_comb begin
|
||||
HREADUART = {Dout, Dout, Dout, Dout};
|
||||
case (A[1:0])
|
||||
|
@ -174,7 +174,7 @@ module testbench();
|
||||
`define RF dut.hart.ieu.dp.regf.rf
|
||||
`define PC dut.hart.ifu.pcreg.q
|
||||
`define CSR_BASE dut.hart.priv.priv.csr
|
||||
`define HPMCOUNTER `CSR_BASE.counters.genblk1.HPMCOUNTER_REGW
|
||||
`define HPMCOUNTER `CSR_BASE.counters.counters.HPMCOUNTER_REGW
|
||||
`define PMP_BASE `CSR_BASE.csrm.pmp
|
||||
`define PMPCFG genblk2.PMPCFGreg.q
|
||||
`define PMPADDR PMPADDRreg.q
|
||||
@ -183,16 +183,16 @@ module testbench();
|
||||
`define MIE `CSR_BASE.csri.MIE_REGW
|
||||
`define MIP `CSR_BASE.csri.MIP_REGW
|
||||
`define MCAUSE `CSR_BASE.csrm.MCAUSEreg.q
|
||||
`define SCAUSE `CSR_BASE.csrs.genblk1.SCAUSEreg.q
|
||||
`define SCAUSE `CSR_BASE.csrs.csrs.SCAUSEreg.q
|
||||
`define MEPC `CSR_BASE.csrm.MEPCreg.q
|
||||
`define SEPC `CSR_BASE.csrs.genblk1.SEPCreg.q
|
||||
`define SEPC `CSR_BASE.csrs.csrs.SEPCreg.q
|
||||
`define MCOUNTEREN `CSR_BASE.csrm.counters.MCOUNTERENreg.q
|
||||
`define SCOUNTEREN `CSR_BASE.csrs.genblk1.genblk2.SCOUNTERENreg.q
|
||||
`define SCOUNTEREN `CSR_BASE.csrs.csrs.scounteren.SCOUNTERENreg.q
|
||||
`define MSCRATCH `CSR_BASE.csrm.MSCRATCHreg.q
|
||||
`define SSCRATCH `CSR_BASE.csrs.genblk1.SSCRATCHreg.q
|
||||
`define SSCRATCH `CSR_BASE.csrs.csrs.SSCRATCHreg.q
|
||||
`define MTVEC `CSR_BASE.csrm.MTVECreg.q
|
||||
`define STVEC `CSR_BASE.csrs.genblk1.STVECreg.q
|
||||
`define SATP `CSR_BASE.csrs.genblk1.genblk1.SATPreg.q
|
||||
`define STVEC `CSR_BASE.csrs.csrs.STVECreg.q
|
||||
`define SATP `CSR_BASE.csrs.csrs.genblk1.SATPreg.q
|
||||
`define MSTATUS `CSR_BASE.csrsr.MSTATUS_REGW
|
||||
`define STATUS_TSR `CSR_BASE.csrsr.STATUS_TSR_INT
|
||||
`define STATUS_TW `CSR_BASE.csrsr.STATUS_TW_INT
|
||||
@ -210,7 +210,7 @@ module testbench();
|
||||
`define STATUS_SIE `CSR_BASE.csrsr.STATUS_SIE
|
||||
`define STATUS_UIE `CSR_BASE.csrsr.STATUS_UIE
|
||||
`define PRIV dut.hart.priv.priv.privmodereg.q
|
||||
`define INSTRET dut.hart.priv.priv.csr.counters.genblk1.genblk2.INSTRETreg.q
|
||||
`define INSTRET dut.hart.priv.priv.csr.counters.counters.cntreg.INSTRETreg.q
|
||||
// Common Macros
|
||||
`define checkCSR(CSR) \
|
||||
begin \
|
||||
@ -577,7 +577,7 @@ module testbench();
|
||||
`checkEQ("PCW",PCW,ExpectedPCW)
|
||||
//`checkEQ("InstrW",InstrW,ExpectedInstrW) <-- not viable because of
|
||||
// compressed to uncompressed conversion
|
||||
`checkEQ("Instr Count",dut.hart.priv.priv.csr.counters.genblk1.INSTRET_REGW,InstrCountW)
|
||||
`checkEQ("Instr Count",dut.hart.priv.priv.csr.counters.counters.INSTRET_REGW,InstrCountW)
|
||||
#2; // delay 2 ns.
|
||||
if(`DEBUG_TRACE >= 5) begin
|
||||
$display("%tns, %d instrs: Reg Write Address %02d ? expected value: %02d", $time, InstrCountW, dut.hart.ieu.dp.regf.a3, ExpectedRegAdrW);
|
||||
@ -612,9 +612,9 @@ module testbench();
|
||||
"mepc": `checkCSR(dut.hart.priv.priv.csr.csrm.MEPC_REGW)
|
||||
"mtval": `checkCSR(dut.hart.priv.priv.csr.csrm.MTVAL_REGW)
|
||||
"sepc": `checkCSR(dut.hart.priv.priv.csr.csrs.SEPC_REGW)
|
||||
"scause": `checkCSR(dut.hart.priv.priv.csr.csrs.genblk1.SCAUSE_REGW)
|
||||
"scause": `checkCSR(dut.hart.priv.priv.csr.csrs.csrs.SCAUSE_REGW)
|
||||
"stvec": `checkCSR(dut.hart.priv.priv.csr.csrs.STVEC_REGW)
|
||||
"stval": `checkCSR(dut.hart.priv.priv.csr.csrs.genblk1.STVAL_REGW)
|
||||
"stval": `checkCSR(dut.hart.priv.priv.csr.csrs.csrs.STVAL_REGW)
|
||||
endcase
|
||||
end
|
||||
if (fault == 1) begin
|
||||
|
@ -26,7 +26,8 @@
|
||||
`define IMPERASTEST "0"
|
||||
`define RISCVARCHTEST "1"
|
||||
`define WALLYTEST "2"
|
||||
`define MYIMPERASTEST "3"
|
||||
`define MYIMPERASTEST "3"
|
||||
// *** remove MYIMPERASTEST cases when ported
|
||||
|
||||
string tvpaths[] = '{
|
||||
"../../addins/imperas-riscv-tests/work/",
|
||||
@ -1484,7 +1485,11 @@ string imperas32f[] = '{
|
||||
};
|
||||
|
||||
string wally64priv[] = '{
|
||||
`WALLYTEST
|
||||
`WALLYTEST,
|
||||
"rv64i_m/privilege/WALLY-MMU-SV39", "30A0",
|
||||
"rv64i_m/privilege/WALLY-MMU-SV48", "30A0",
|
||||
"rv64i_m/privilege/WALLY-PMA", "30A0",
|
||||
"rv64i_m/privilege/WALLY-PMP", "30A0"
|
||||
};
|
||||
|
||||
string wally64periph[] = '{
|
||||
@ -1497,7 +1502,10 @@ string wally32i[] = '{
|
||||
};
|
||||
|
||||
string wally32priv[] = '{
|
||||
`WALLYTEST
|
||||
`WALLYTEST,
|
||||
"rv32i_m/privilege/WALLY-MMU-SV32", "3080",
|
||||
"rv32i_m/privilege/WALLY-PMA", "3080",
|
||||
"rv32i_m/privilege/WALLY-PMP", "3080"
|
||||
};
|
||||
|
||||
string wally32periph[] = '{
|
||||
|
Loading…
Reference in New Issue
Block a user