Merge branch 'main' of github.com:davidharrishmc/riscv-wally into main

This commit is contained in:
Ross Thompson 2021-07-05 16:07:27 -05:00
commit 2a62ee2e70
30 changed files with 446 additions and 427 deletions

View File

@ -9,7 +9,8 @@ add wave /testbench/clk
add wave /testbench/reset
add wave -divider
add wave /testbench/dut/hart/DataStall
#add wave /testbench/dut/hart/DataStall
add wave /testbench/debug
add wave /testbench/dut/hart/StallF
add wave /testbench/dut/hart/StallD
add wave /testbench/dut/hart/StallE

View File

@ -115,7 +115,7 @@ module ICacheCntrl #(parameter BLOCKLEN = 256)
localparam STATE_INVALIDATE = 'h12; // *** not sure if invalidate or evict? invalidate by cache block or address?
localparam STATE_TLB_MISS = 'h13;
localparam STATE_TLB_MISS_DONE = 'h14;
localparam STATE_INSTR_PAGE_FAULT = 'h15;
localparam AHBByteLength = `XLEN / 8;
@ -370,7 +370,10 @@ module ICacheCntrl #(parameter BLOCKLEN = 256)
NextState = STATE_READY;
end
STATE_TLB_MISS: begin
if (ITLBWriteF | WalkerInstrPageFaultF) begin
if (WalkerInstrPageFaultF) begin
NextState = STATE_INSTR_PAGE_FAULT;
ICacheStallF = 1'b0;
end else if (ITLBWriteF) begin
NextState = STATE_TLB_MISS_DONE;
end else begin
NextState = STATE_TLB_MISS;
@ -379,6 +382,10 @@ module ICacheCntrl #(parameter BLOCKLEN = 256)
STATE_TLB_MISS_DONE: begin
NextState = STATE_READY;
end
STATE_INSTR_PAGE_FAULT: begin
ICacheStallF = 1'b0;
NextState = STATE_READY;
end
default: begin
PCMux = 2'b01;
NextState = STATE_READY;
@ -425,8 +432,8 @@ module ICacheCntrl #(parameter BLOCKLEN = 256)
// store read data from memory interface before writing into SRAM.
genvar i;
generate
for (i = 0; i < WORDSPERLINE; i++) begin
flopenr #(`XLEN) flop(.clk(clk),
for (i = 0; i < WORDSPERLINE; i++) begin:storebuffer
flopenr #(`XLEN) sb(.clk(clk),
.reset(reset),
.en(InstrAckF & (i == FetchCount)),
.d(InstrInF),

View File

@ -106,7 +106,7 @@ module rodirectmappedmem #(parameter NUMLINES=512, parameter LINESIZE = 256, par
assign DataWord = ReadLineTransformed[ReadOffset];
genvar i;
generate
for (i=0; i < LINESIZE/WORDSIZE; i++) begin
for (i=0; i < LINESIZE/WORDSIZE; i++) begin:readline
assign ReadLineTransformed[i] = ReadLine[(i+1)*WORDSIZE-1:i*WORDSIZE];
end
endgenerate
@ -214,7 +214,7 @@ module wtdirectmappedmem #(parameter NUMLINES=512, parameter LINESIZE = 256, par
assign DataWord = ReadLineTransformed[ReadOffset];
genvar i;
generate
for (i=0; i < LINESIZE/WORDSIZE; i++) begin
for (i=0; i < LINESIZE/WORDSIZE; i++) begin:readline
assign ReadLineTransformed[i] = ReadLine[(i+1)*WORDSIZE-1:i*WORDSIZE];
end
endgenerate

View File

@ -219,8 +219,6 @@ module ahblite (
generate
if (`A_SUPPORTED) begin
logic [`XLEN-1:0] AMOResult;
// amoalu amoalu(.a(HRDATA), .b(WriteDataM), .funct(Funct7M), .width(MemSizeM),
// .result(AMOResult));
amoalu amoalu(.srca(HRDATAW), .srcb(WriteDataM), .funct(Funct7M), .width(MemSizeM),
.result(AMOResult));
mux2 #(`XLEN) wdmux(WriteDataM, AMOResult, AtomicMaskedM[1], WriteData);

View File

@ -43,6 +43,9 @@ module fpu (
output logic [4:0] SetFflagsM, // FPU flags
output logic [`XLEN-1:0] FPUResultW); // FPU result
// *** change FMA to do 16 - 32 - 64 - 128 FEXPBITS
generate
if (`F_SUPPORTED) begin
// control logic signal instantiation
logic FWriteEnD, FWriteEnE, FWriteEnM, FWriteEnW; // FP register write enable
logic [2:0] FrmD, FrmE, FrmM; // FP rounding mode
@ -397,6 +400,19 @@ module fpu (
//*** put into mem stage
SetFflagsM = FPUFlagsW;
end
end else begin // no F_SUPPORTED; tie outputs low
assign FStallD = 0;
assign FWriteIntE = 0;
assign FWriteIntM = 0;
assign FWriteIntW = 0;
assign FWriteDataE = 0;
assign FIntResM = 0;
assign FDivBusyE = 0;
assign IllegalFPUInstrD = 1;
assign SetFflagsM = 0;
assign FPUResultW = 0;
end
endgenerate
endmodule // fpu

View File

@ -38,8 +38,7 @@ module shift_right #(parameter WIDTH=8)
assign stage[0] = A;
generate
for (i=0;i<$clog2(WIDTH);i=i+1)
begin : genbit
for (i=0;i<$clog2(WIDTH);i=i+1) begin : genbit
mux2 #(WIDTH) mux_inst (stage[i],
{{(WIDTH/(2**(i+1))){1'b0}}, stage[i][WIDTH-1:WIDTH/(2**(i+1))]},
Shift[$clog2(WIDTH)-i-1],
@ -60,8 +59,7 @@ module shift_left #(parameter WIDTH=8)
assign stage[0] = A;
generate
for (i=0;i<$clog2(WIDTH);i=i+1)
begin : genbit
for (i=0;i<$clog2(WIDTH);i=i+1) begin : genbit
mux2 #(WIDTH) mux_inst (stage[i],
{stage[i][WIDTH-1-WIDTH/(2**(i+1)):0], {(WIDTH/(2**(i+1))){1'b0}}},
Shift[$clog2(WIDTH)-i-1],

View File

@ -97,7 +97,7 @@ module SRAM2P1R1W
// write port
generate
for (index = 0; index < Width; index = index + 1) begin
for (index = 0; index < Width; index = index + 1) begin:mem
always_ff @ (posedge clk) begin
if (WEN1Q & BitWEN1[index]) begin
memory[WA1Q][index] <= WD1Q[index];

View File

@ -67,7 +67,7 @@ module localHistoryPredictor
genvar index;
generate
for (index = 0; index < 2**m; index = index +1) begin
for (index = 0; index < 2**m; index = index +1) begin:localhist
flopenr #(k) LocalHistoryRegister(.clk(clk),
.reset(reset),

View File

@ -151,7 +151,7 @@ module dcachecontroller #(parameter LINESIZE = 256) (
genvar i;
generate
for (i=0; i < WORDSPERLINE; i++) begin
for (i=0; i < WORDSPERLINE; i++) begin:sb
flopenr #(`XLEN) flop(clk, reset, FetchState & (i == FetchWordNum), ReadDataW, DCacheMemWriteData[(i+1)*`XLEN-1:i*`XLEN]);
end
endgenerate

View File

@ -64,7 +64,7 @@ module lsu (
output logic [1:0] AtomicMaskedM,
input logic MemAckW, // from ahb
input logic [`XLEN-1:0] HRDATAW, // from ahb
output logic [2:0] Funct3MfromLSU,
output logic [2:0] SizeFromLSU,
output logic StallWfromLSU,
@ -132,7 +132,7 @@ module lsu (
logic MMUTranslate;
logic HPTWRead;
logic [1:0] MemRWMtoLSU;
logic [2:0] Funct3MtoLSU;
logic [2:0] SizeToLSU;
logic [1:0] AtomicMtoLSU;
logic [`XLEN-1:0] MemAdrMtoLSU;
logic [`XLEN-1:0] WriteDataMtoLSU;
@ -204,7 +204,7 @@ module lsu (
// LSU
.DisableTranslation(DisableTranslation),
.MemRWMtoLSU(MemRWMtoLSU),
.Funct3MtoLSU(Funct3MtoLSU),
.SizeToLSU(SizeToLSU),
.AtomicMtoLSU(AtomicMtoLSU),
.MemAdrMtoLSU(MemAdrMtoLSU),
.WriteDataMtoLSU(WriteDataMtoLSU), // *** ??????????????
@ -220,7 +220,7 @@ module lsu (
mmu #(.TLB_ENTRIES(`DTLB_ENTRIES), .IMMU(0))
dmmu(.TLBAccessType(MemRWMtoLSU),
.VirtualAddress(MemAdrMtoLSU),
.Size(Funct3MtoLSU[1:0]),
.Size(SizeToLSU[1:0]),
.PTEWriteVal(PageTableEntryM),
.PageTypeWriteVal(PageTypeM),
.TLBWrite(DTLBWriteM),
@ -244,7 +244,7 @@ module lsu (
// Determine if an Unaligned access is taking place
always_comb
case(Funct3MtoLSU[1:0])
case(SizeToLSU[1:0])
2'b00: DataMisalignedMfromLSU = 0; // lb, sb, lbu
2'b01: DataMisalignedMfromLSU = MemAdrMtoLSU[0]; // lh, sh, lhu
2'b10: DataMisalignedMfromLSU = MemAdrMtoLSU[1] | MemAdrMtoLSU[0]; // lw, sw, flw, fsw, lwu
@ -400,7 +400,7 @@ module lsu (
end // always_comb
// *** for now just pass through size
assign Funct3MfromLSU = Funct3MtoLSU;
assign SizeFromLSU = SizeToLSU;
assign StallWfromLSU = StallWtoLSU;

View File

@ -54,7 +54,7 @@ module lsuArb
// to LSU
output logic DisableTranslation,
output logic [1:0] MemRWMtoLSU,
output logic [2:0] Funct3MtoLSU,
output logic [2:0] SizeToLSU,
output logic [1:0] AtomicMtoLSU,
output logic [`XLEN-1:0] MemAdrMtoLSU,
output logic [`XLEN-1:0] WriteDataMtoLSU,
@ -87,6 +87,7 @@ module lsuArb
statetype CurrState, NextState;
logic SelPTW;
logic HPTWStallD;
logic [2:0] PTWSize;
flopenl #(.TYPE(statetype)) StateReg(.clk(clk),
@ -138,12 +139,9 @@ module lsuArb
assign MemRWMtoLSU = SelPTW ? {HPTWRead, 1'b0} : MemRWM;
generate
if (`XLEN == 32) begin
assign Funct3MtoLSU = SelPTW ? 3'b010 : Funct3M;
end else begin
assign Funct3MtoLSU = SelPTW ? 3'b011 : Funct3M;
end
assign PTWSize = (`XLEN==32 ? 3'b010 : 3'b011); // 32 or 64-bit access from htpw
endgenerate
mux2 #(3) sizemux(Funct3M, PTWSize, SelPTW, SizeToLSU);
assign AtomicMtoLSU = SelPTW ? 2'b00 : AtomicM;
assign MemAdrMtoLSU = SelPTW ? HPTWPAdr : MemAdrM;

View File

@ -76,8 +76,9 @@ module pmpadrdec (
generate
assign Mask[1:0] = 2'b11;
assign Mask[2] = (AdrMode == NAPOT); // mask has 0s in upper bis for NA4 region
for (i=3; i < `PA_BITS; i=i+1)
for (i=3; i < `PA_BITS; i=i+1) begin:mask
assign Mask[i] = Mask[i-1] & PMPAdr[i-3]; // NAPOT mask: 1's indicate bits to ignore
end
endgenerate
// verilator lint_on UNOPTFLAT

View File

@ -63,12 +63,6 @@ module pmpchecker (
// verilator lint_on UNOPTFLAT
logic [`PMP_ENTRIES-1:0] PAgePMPAdr; // for TOR PMP matching, PhysicalAddress > PMPAdr[i]
genvar i,j;
/*
generate // extract 8-bit chunks from PMPCFG array
for (j=0; j<`PMP_ENTRIES; j = j+8)
assign {PMPCfg[j+7], PMPCfg[j+6], PMPCfg[j+5], PMPCfg[j+4],
PMPCfg[j+3], PMPCfg[j+2], PMPCfg[j+1], PMPCfg[j]} = PMPCFG_ARRAY_REGW[j/8];
endgenerate */
pmpadrdec pmpadrdecs[`PMP_ENTRIES-1:0](
.PhysicalAddress,
@ -80,7 +74,6 @@ module pmpchecker (
.NoLowerMatchOut(NoLowerMatch),
.Match, .Active, .L, .X, .W, .R);
// Only enforce PMP checking for S and U modes when at least one PMP is active or in Machine mode when L bit is set in selected region
assign EnforcePMP = (PrivilegeModeW == `M_MODE) ? |L : |Active;

View File

@ -111,6 +111,7 @@ module tlb #(parameter TLB_ENTRIES = 8,
logic [1:0] HitPageType;
logic CAMHit;
logic [`ASID_BITS-1:0] ASID;
logic DAFault;
// Grab the sv mode from SATP and determine whether translation should occur
assign SvMode = SATP_REGW[`XLEN-1:`XLEN-`SVMODE_BITS];
@ -165,7 +166,9 @@ module tlb #(parameter TLB_ENTRIES = 8,
// only execute non-user mode pages.
assign ImproperPrivilege = ((EffectivePrivilegeMode == `U_MODE) && ~PTE_U) ||
((EffectivePrivilegeMode == `S_MODE) && PTE_U);
assign TLBPageFault = Translate && TLBHit && (ImproperPrivilege || ~PTE_X);
// fault for software handling if access bit is off
assign DAFault = ~PTE_A;
assign TLBPageFault = Translate && TLBHit && (ImproperPrivilege || ~PTE_X || DAFault);
end else begin
logic ImproperPrivilege, InvalidRead, InvalidWrite;
@ -180,7 +183,9 @@ module tlb #(parameter TLB_ENTRIES = 8,
// Check for write error. Writes are invalid when the page's write bit is
// low.
assign InvalidWrite = WriteAccess && ~PTE_W;
assign TLBPageFault = Translate && TLBHit && (ImproperPrivilege || InvalidRead || InvalidWrite);
// Fault for software handling if access bit is off or writing a page with dirty bit off
assign DAFault = ~PTE_A | WriteAccess & ~PTE_D;
assign TLBPageFault = Translate && TLBHit && (ImproperPrivilege || InvalidRead || InvalidWrite || DAFault);
end
endgenerate

View File

@ -41,8 +41,9 @@ module tlbpriority #(parameter ENTRIES = 8) (
genvar i;
generate
assign nolower[0] = 1;
for (i=1; i<ENTRIES; i++)
for (i=1; i<ENTRIES; i++) begin:therm
assign nolower[i] = nolower[i-1] & ~a[i-1];
end
endgenerate
// verilator lint_on UNOPTFLAT
assign y = a & nolower;

View File

@ -299,8 +299,7 @@ module csa #(parameter WIDTH=8) (input logic [WIDTH-1:0] a, b, c,
logic [WIDTH:0] carry_temp;
genvar i;
generate
for (i=0;i<WIDTH;i=i+1)
begin : genbit
for (i=0;i<WIDTH;i=i+1) begin : genbit
fa fa_inst (a[i], b[i], c[i], sum[i], carry_temp[i+1]);
end
endgenerate

View File

@ -139,6 +139,8 @@ module muldiv (
end else begin // no M instructions supported
assign MulDivResultW = 0;
assign DivBusyE = 0;
assign DivDoneE = 0;
end
endgenerate

View File

@ -164,17 +164,13 @@ module plic (
flopr #(N) intPendingFlop(HCLK,~HRESETn,nextIntPending,intPending);
// pending array - indexed by priority_lvl x source_ID
genvar i;
genvar i, j;
generate
for (i=1; i<=N; i=i+1) begin
for (j=1; j<=7; j++) begin: pending
for (i=1; i<=N; i=i+1) begin: pendingbit
// *** make sure that this synthesizes into N decoders, not 7*N 3-bit equality comparators (right?)
assign pendingArray[7][i] = (intPriority[i]==7) & intEn[i] & intPending[i];
assign pendingArray[6][i] = (intPriority[i]==6) & intEn[i] & intPending[i];
assign pendingArray[5][i] = (intPriority[i]==5) & intEn[i] & intPending[i];
assign pendingArray[4][i] = (intPriority[i]==4) & intEn[i] & intPending[i];
assign pendingArray[3][i] = (intPriority[i]==3) & intEn[i] & intPending[i];
assign pendingArray[2][i] = (intPriority[i]==2) & intEn[i] & intPending[i];
assign pendingArray[1][i] = (intPriority[i]==1) & intEn[i] & intPending[i];
assign pendingArray[j][i] = (intPriority[i]==j) & intEn[i] & intPending[i];
end
end
endgenerate
// pending array, except grouped by priority
@ -185,6 +181,8 @@ module plic (
|pendingArray[3],
|pendingArray[2],
|pendingArray[1]};
//assign pendingPGrouped = pendingArray.or;
// pendingPGrouped, except only topmost priority is active
assign pendingMaxP[7:1] = {pendingPGrouped[7],
pendingPGrouped[6] & ~|pendingPGrouped[7],
@ -202,24 +200,24 @@ module plic (
| ({N{pendingMaxP[2]}} & pendingArray[2])
| ({N{pendingMaxP[1]}} & pendingArray[1]);
// find the lowest ID amongst active interrupts at the highest priority
integer j;
// *** verify that this synthesizes to a reasonable priority encoder and that j doesn't actually exist in hardware
int k;
// *** verify that this synthesizes to a reasonable priority encoder and that k doesn't actually exist in hardware
always_comb begin
intClaim = 6'b0;
for(j=N; j>0; j=j-1) begin
if(pendingRequestsAtMaxP[j]) intClaim = j[5:0];
for(k=N; k>0; k=k-1) begin
if(pendingRequestsAtMaxP[k]) intClaim = k[5:0];
end
end
// create threshold mask
always_comb begin
threshMask[7] = ~(7==intThreshold);
threshMask[6] = ~(6==intThreshold) & threshMask[7];
threshMask[5] = ~(5==intThreshold) & threshMask[6];
threshMask[4] = ~(4==intThreshold) & threshMask[5];
threshMask[3] = ~(3==intThreshold) & threshMask[4];
threshMask[2] = ~(2==intThreshold) & threshMask[3];
threshMask[1] = ~(1==intThreshold) & threshMask[2];
threshMask[7] = (intThreshold != 7);
threshMask[6] = (intThreshold != 6) & threshMask[7];
threshMask[5] = (intThreshold != 5) & threshMask[6];
threshMask[4] = (intThreshold != 4) & threshMask[5];
threshMask[3] = (intThreshold != 3) & threshMask[4];
threshMask[2] = (intThreshold != 2) & threshMask[3];
threshMask[1] = (intThreshold != 1) & threshMask[2];
end
// is the max priority > threshold?
// *** would it be any better to first priority encode maxPriority into binary and then ">" with threshold?

View File

@ -291,7 +291,7 @@ module uartPC16550D(
// although rxfullbit looks like a combinational loop, in one bit rxfifotail == i and breaks the loop
generate
genvar i;
for (i=0; i<16; i++) begin
for (i=0; i<16; i++) begin:rx
assign RXerrbit[i] = |rxfifo[i][10:8]; // are any of the error conditions set?
if (i > 0)
assign rxfullbit[i] = ((rxfifohead==i) | rxfullbit[i-1]) & (rxfifotail != i);

View File

@ -159,7 +159,7 @@ module wallypipelinedhart
// IEU vs HPTW arbitration signals to send to LSU
logic [1:0] MemRWMtoLSU;
logic [2:0] Funct3MtoLSU;
logic [2:0] SizeToLSU;
logic [1:0] AtomicMtoLSU;
logic [`XLEN-1:0] MemAdrMtoLSU;
logic [`XLEN-1:0] WriteDataMtoLSU;
@ -169,7 +169,7 @@ module wallypipelinedhart
logic DataMisalignedMfromLSU;
logic StallWtoLSU;
logic StallWfromLSU;
logic [2:0] Funct3MfromLSU;
logic [2:0] SizeFromLSU;
ifu ifu(.InstrInF(InstrRData),
@ -207,7 +207,7 @@ module wallypipelinedhart
.AtomicMaskedM(AtomicMaskedM),
.MemAckW(MemAckW),
.HRDATAW(HRDATAW),
.Funct3MfromLSU(Funct3MfromLSU), // stays the same
.SizeFromLSU(SizeFromLSU), // stays the same
.StallWfromLSU(StallWfromLSU), // stays the same
.DSquashBusAccessM(DSquashBusAccessM), // probalby removed after dcache implemenation?
// currently not connected (but will need to be used for lsu talking to ahb.
@ -261,7 +261,7 @@ module wallypipelinedhart
//.InstrRData(InstrF), // hook up InstrF later
.ISquashBusAccessF(1'b0), // *** temporary hack to disable PMP instruction fetch checking
.WriteDataM(WriteDataM),
.MemSizeM(Funct3MfromLSU[1:0]), .UnsignedLoadM(Funct3MfromLSU[2]),
.MemSizeM(SizeFromLSU[1:0]), .UnsignedLoadM(SizeFromLSU[2]),
.Funct7M(InstrM[31:25]),
.HRDATAW(HRDATAW),
.StallW(StallWfromLSU),

View File

@ -515,6 +515,9 @@ string tests32f[] = '{
logic HCLK, HRESETn;
logic [`XLEN-1:0] PCW;
logic [`XLEN-1:0] debug;
assign debug = dut.uncore.dtim.RAM[536872960];
flopenr #(`XLEN) PCWReg(clk, reset, ~dut.hart.ieu.dp.StallW, dut.hart.ifu.PCM, PCW);
flopenr #(32) InstrWReg(clk, reset, ~dut.hart.ieu.dp.StallW, dut.hart.ifu.InstrM, InstrW);
@ -656,10 +659,7 @@ string tests32f[] = '{
// Check errors
errors = (i == SIGNATURESIZE+1); // error if file is empty
i = 0;
if (`XLEN == 32)
testadr = (`TIM_BASE+tests[test+1].atohex())/4;
else
testadr = (`TIM_BASE+tests[test+1].atohex())/8;
testadr = (`TIM_BASE+tests[test+1].atohex())/(`XLEN/8);
/* verilator lint_off INFINITELOOP */
while (signature[i] !== 'bx) begin
//$display("signature[%h] = %h", i, signature[i]);
@ -669,14 +669,16 @@ string tests32f[] = '{
// kind of hacky test for garbage right now
errors = errors+1;
$display(" Error on test %s result %d: adr = %h sim = %h, signature = %h",
tests[test], i, (testadr+i)*`XLEN/8, dut.uncore.dtim.RAM[testadr+i], signature[i]);
tests[test], i, (testadr+i)*(`XLEN/8), dut.uncore.dtim.RAM[testadr+i], signature[i]);
$stop;//***debug
end
end
i = i + 1;
end
/* verilator lint_on INFINITELOOP */
if (errors == 0) $display("%s succeeded. Brilliant!!!", tests[test]);
if (errors == 0) begin
$display("%s succeeded. Brilliant!!!", tests[test]);
end
else begin
$display("%s failed with %d errors. :(", tests[test], errors);
totalerrors = totalerrors+1;