Removed generate statements

This commit is contained in:
David Harris 2022-01-05 14:35:25 +00:00
parent 98be8201b2
commit d66f7c841b
38 changed files with 929 additions and 2662 deletions

View File

@ -3,11 +3,14 @@ make all:
make -C ../../addins/riscv-arch-test make -C ../../addins/riscv-arch-test
make -C ../../addins/riscv-arch-test XLEN=32 make -C ../../addins/riscv-arch-test XLEN=32
exe2memfile.pl ../../addins/riscv-arch-test/work/*/*/*.elf exe2memfile.pl ../../addins/riscv-arch-test/work/*/*/*.elf
# extractFunctionRadix. ***
# Build wally-riscv-arch-test # Build wally-riscv-arch-test
make -C ../../tests/wally-riscv-arch-test/ make -C ../../tests/wally-riscv-arch-test/
make -C ../../tests/wally-riscv-arch-test/ XLEN=32 make -C ../../tests/wally-riscv-arch-test/ XLEN=32
exe2memfile.pl ../../tests/wally-riscv-arch-test/work/*/*/*.elf exe2memfile.pl ../../tests/wally-riscv-arch-test/work/*/*/*.elf
# ***extractFunctionRadix
# *** use elf2hex
# *** add optional imperas tests # *** add optional imperas tests

View File

@ -1,3 +1,3 @@
vsim -c <<! vsim -c <<!
do wally-pipelined-batch.do rv64gc imperas64i do wally-pipelined-batch.do rv32gc wally32priv
! !

View File

@ -174,3 +174,22 @@ module divconv_pipe (q1, qm1, qp1, q0, qm0, qp0, rega_out, regb_out, regc_out, r
flopenr #(60) regk (clk, reset, regs_pipe2, {qp_out0[59:35], (qp_out0[34:6] & {29{~P_pipe}}), 6'h0}, qp0); flopenr #(60) regk (clk, reset, regs_pipe2, {qp_out0[59:35], (qp_out0[34:6] & {29{~P_pipe}}), 6'h0}, qp0);
endmodule // divconv endmodule // divconv
// *** rewrote behaviorally dh 5 Jan 2021 for speed
module csa #(parameter WIDTH=8) (
input logic [WIDTH-1:0] a, b, c,
output logic [WIDTH-1:0] sum, carry);
assign sum = a ^ b ^ c;
assign carry = (a & (b | c)) | (b & c);
/*
logic [WIDTH:0] carry_temp;
genvar i;
generate
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
assign carry = {carry_temp[WIDTH-1:1], 1'b0};
*/
endmodule // csa

View File

@ -37,9 +37,6 @@ module redundantmul #(parameter WIDTH =8)(
input logic [WIDTH-1:0] a,b, input logic [WIDTH-1:0] a,b,
output logic [2*WIDTH-1:0] out0, out1); output logic [2*WIDTH-1:0] out0, out1);
//
generate
if (`DESIGN_COMPILER == 1) begin:mul if (`DESIGN_COMPILER == 1) begin:mul
logic [2*WIDTH-1+2:0] tmp_out0; logic [2*WIDTH-1+2:0] tmp_out0;
logic [2*WIDTH-1+2:0] tmp_out1; logic [2*WIDTH-1+2:0] tmp_out1;
@ -51,8 +48,6 @@ module redundantmul #(parameter WIDTH =8)(
assign out0 = a * b; assign out0 = a * b;
assign out1 = 0; assign out1 = 0;
end end
endgenerate
endmodule endmodule

View File

@ -1,195 +0,0 @@
///////////////////////////////////////////
// lzd.sv
//
// Written: James.Stine@okstate.edu 1 February 2021
// Modified:
//
// Purpose: Integer Divide instructions
//
// A component of the Wally configurable RISC-V project.
//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
// is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
///////////////////////////////////////////
`include "wally-config.vh"
/* verilator lint_off DECLFILENAME */
// Original idea came from V. G. Oklobdzija, "An algorithmic and novel
// design of a leading zero detector circuit: comparison with logic
// synthesis," in IEEE Transactions on Very Large Scale Integration
// (VLSI) Systems, vol. 2, no. 1, pp. 124-128, March 1994, doi:
// 10.1109/92.273153.
// Modified to be more hierarchical
module lzd2 (P, V, B);
input logic [1:0] B;
output logic P;
output logic V;
assign V = B[0] | B[1];
assign P = B[0] & ~B[1];
endmodule // lzd2
module lzd_hier #(parameter WIDTH=8)
(input logic [WIDTH-1:0] B,
output logic [$clog2(WIDTH)-1:0] ZP,
output logic ZV);
if (WIDTH == 128)
lzd128 lz127 (ZP, ZV, B);
else if (WIDTH == 64)
lzd64 lz64 (ZP, ZV, B);
else if (WIDTH == 32)
lzd32 lz32 (ZP, ZV, B);
else if (WIDTH == 16)
lzd16 lz16 (ZP, ZV, B);
else if (WIDTH == 8)
lzd8 lz8 (ZP, ZV, B);
else if (WIDTH == 4)
lzd4 lz4 (ZP, ZV, B);
endmodule // lzd_hier
module lzd4 (ZP, ZV, B);
input logic [3:0] B;
logic ZPa;
logic ZPb;
logic ZVa;
logic ZVb;
output logic [1:0] ZP;
output logic ZV;
lzd2 l1(ZPa, ZVa, B[1:0]);
lzd2 l2(ZPb, ZVb, B[3:2]);
assign ZP[0] = ZVb ? ZPb : ZPa;
assign ZP[1] = ~ZVb;
assign ZV = ZVa | ZVb;
endmodule // lzd4
module lzd8 (ZP, ZV, B);
input logic [7:0] B;
logic [1:0] ZPa;
logic [1:0] ZPb;
logic ZVa;
logic ZVb;
output logic [2:0] ZP;
output logic ZV;
lzd4 l1(ZPa, ZVa, B[3:0]);
lzd4 l2(ZPb, ZVb, B[7:4]);
assign ZP[1:0] = ZVb ? ZPb : ZPa;
assign ZP[2] = ~ZVb;
assign ZV = ZVa | ZVb;
endmodule // lzd8
module lzd16 (ZP, ZV, B);
input logic [15:0] B;
logic [2:0] ZPa;
logic [2:0] ZPb;
logic ZVa;
logic ZVb;
output logic [3:0] ZP;
output logic ZV;
lzd8 l1(ZPa, ZVa, B[7:0]);
lzd8 l2(ZPb, ZVb, B[15:8]);
assign ZP[2:0] = ZVb ? ZPb : ZPa;
assign ZP[3] = ~ZVb;
assign ZV = ZVa | ZVb;
endmodule // lzd16
module lzd32 (ZP, ZV, B);
input logic [31:0] B;
logic [3:0] ZPa;
logic [3:0] ZPb;
logic ZVa;
logic ZVb;
output logic [4:0] ZP;
output logic ZV;
lzd16 l1(ZPa, ZVa, B[15:0]);
lzd16 l2(ZPb, ZVb, B[31:16]);
assign ZP[3:0] = ZVb ? ZPb : ZPa;
assign ZP[4] = ~ZVb;
assign ZV = ZVa | ZVb;
endmodule // lzd32
module lzd64 (ZP, ZV, B);
input logic [63:0] B;
logic [4:0] ZPa;
logic [4:0] ZPb;
logic ZVa;
logic ZVb;
output logic [5:0] ZP;
output logic ZV;
lzd32 l1(ZPa, ZVa, B[31:0]);
lzd32 l2(ZPb, ZVb, B[63:32]);
assign ZP[4:0] = ZVb ? ZPb : ZPa;
assign ZP[5] = ~ZVb;
assign ZV = ZVa | ZVb;
endmodule // lzd64
module lzd128 (ZP, ZV, B);
input logic [127:0] B;
logic [5:0] ZPa;
logic [5:0] ZPb;
logic ZVa;
logic ZVb;
output logic [6:0] ZP;
output logic ZV;
lzd64 l1(ZPa, ZVa, B[64:0]);
lzd64 l2(ZPb, ZVb, B[127:63]);
assign ZP[5:0] = ZVb ? ZPb : ZPa;
assign ZP[6] = ~ZVb;
assign ZV = ZVa | ZVb;
endmodule // lzd128
/* verilator lint_on DECLFILENAME */

View File

@ -33,18 +33,16 @@ module or_rows #(parameter ROWS = 8, COLS=2) (
input var logic [COLS-1:0] a[ROWS-1:0], input var logic [COLS-1:0] a[ROWS-1:0],
output logic [COLS-1:0] y); output logic [COLS-1:0] y);
logic [COLS-1:0] mid[ROWS-1:1]; genvar row;
genvar row, col;
generate
if(ROWS == 1) if(ROWS == 1)
assign y = a[0]; assign y = a[0];
else begin else begin
logic [COLS-1:0] mid[ROWS-1:1];
assign mid[1] = a[0] | a[1]; assign mid[1] = a[0] | a[1];
for (row=2; row < ROWS; row++) for (row=2; row < ROWS; row++)
assign mid[row] = mid[row-1] | a[row]; assign mid[row] = mid[row-1] | a[row];
assign y = mid[ROWS-1]; assign y = mid[ROWS-1];
end end
endgenerate
endmodule endmodule
/* verilator lint_on UNOPTFLAT */ /* verilator lint_on UNOPTFLAT */

View File

@ -1,74 +0,0 @@
///////////////////////////////////////////
// shifters.sv
//
// Written: James.Stine@okstate.edu 1 February 2021
// Modified:
//
// Purpose: Integer Divide instructions
//
// A component of the Wally configurable RISC-V project.
//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
// is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
///////////////////////////////////////////
`include "wally-config.vh"
/* verilator lint_off DECLFILENAME */
/* verilator lint_off UNOPTFLAT */
module shift_right #(parameter WIDTH=8)
(input logic [WIDTH-1:0] A,
input logic [$clog2(WIDTH)-1:0] Shift,
output logic [WIDTH-1:0] Z);
logic [WIDTH-1:0] stage [$clog2(WIDTH):0];
logic sign;
genvar i;
assign stage[0] = A;
generate
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],
stage[i+1]);
end
endgenerate
assign Z = stage[$clog2(WIDTH)];
endmodule // shift_right
module shift_left #(parameter WIDTH=8)
(input logic [WIDTH-1:0] A,
input logic [$clog2(WIDTH)-1:0] Shift,
output logic [WIDTH-1:0] Z);
logic [WIDTH-1:0] stage [$clog2(WIDTH):0];
genvar i;
assign stage[0] = A;
generate
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],
stage[i+1]);
end
endgenerate
assign Z = stage[$clog2(WIDTH)];
endmodule // shift_left
/* verilator lint_on DECLFILENAME */
/* verilator lint_on UNOPTFLAT */

View File

@ -78,9 +78,7 @@ module alu #(parameter WIDTH=32) (
endcase endcase
// support W-type RV64I ADDW/SUBW/ADDIW/Shifts that sign-extend 32-bit result to 64 bits // support W-type RV64I ADDW/SUBW/ADDIW/Shifts that sign-extend 32-bit result to 64 bits
generate
if (WIDTH==64) assign Result = W64 ? {{32{FullResult[31]}}, FullResult[31:0]} : FullResult; if (WIDTH==64) assign Result = W64 ? {{32{FullResult[31]}}, FullResult[31:0]} : FullResult;
else assign Result = FullResult; else assign Result = FullResult;
endgenerate
endmodule endmodule

View File

@ -109,7 +109,6 @@ module controller(
assign Rs1D = InstrD[19:15]; assign Rs1D = InstrD[19:15];
// Main Instruction Decoder // Main Instruction Decoder
generate
always_comb always_comb
case(OpD) case(OpD)
// RegWrite_ImmSrc_ALUSrc_MemRW_ResultSrc_Branch_ALUOp_Jump_ALUResultSrc_W64_CSRRead_Privileged_Fence_MulDiv_Atomic_Illegal // RegWrite_ImmSrc_ALUSrc_MemRW_ResultSrc_Branch_ALUOp_Jump_ALUResultSrc_W64_CSRRead_Privileged_Fence_MulDiv_Atomic_Illegal
@ -157,7 +156,6 @@ module controller(
ControlsD = `CTRLW'b1_000_00_00_010_0_0_0_0_0_1_0_0_0_00_0; // csrs ControlsD = `CTRLW'b1_000_00_00_010_0_0_0_0_0_1_0_0_0_00_0; // csrs
default: ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_1; // non-implemented instruction default: ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_1; // non-implemented instruction
endcase endcase
endgenerate
// unswizzle control bits // unswizzle control bits
// squash control signals if coming from an illegal compressed instruction // squash control signals if coming from an illegal compressed instruction
@ -181,7 +179,6 @@ module controller(
// Fences // Fences
// Ordinary fence is presently a nop // Ordinary fence is presently a nop
// FENCE.I flushes the D$ and invalidates the I$ if Zifencei is supported and I$ is implemented // FENCE.I flushes the D$ and invalidates the I$ if Zifencei is supported and I$ is implemented
generate
if (`ZIFENCEI_SUPPORTED & `MEM_ICACHE) begin:fencei if (`ZIFENCEI_SUPPORTED & `MEM_ICACHE) begin:fencei
logic FenceID; logic FenceID;
assign FenceID = FenceD & (Funct3D == 3'b001); // is it a FENCE.I instruction? assign FenceID = FenceD & (Funct3D == 3'b001); // is it a FENCE.I instruction?
@ -191,7 +188,6 @@ module controller(
assign InvalidateICacheD = 0; assign InvalidateICacheD = 0;
assign FlushDCacheD = 0; assign FlushDCacheD = 0;
end end
endgenerate
// Decocde stage pipeline control register // Decocde stage pipeline control register
flopenrc #(1) controlregD(clk, reset, FlushD, ~StallD, 1'b1, InstrValidD); flopenrc #(1) controlregD(clk, reset, FlushD, ~StallD, 1'b1, InstrValidD);

View File

@ -124,7 +124,6 @@ module datapath (
mux5 #(`XLEN) resultmuxW(ResultW, ReadDataW, CSRReadValW, MulDivResultW, SCResultW, ResultSrcW, WriteDataW); mux5 #(`XLEN) resultmuxW(ResultW, ReadDataW, CSRReadValW, MulDivResultW, SCResultW, ResultSrcW, WriteDataW);
// floating point interactions: fcvt, fp stores // floating point interactions: fcvt, fp stores
generate
if (`F_SUPPORTED) begin:fpmux if (`F_SUPPORTED) begin:fpmux
mux2 #(`XLEN) resultmuxM(IEUResultM, FIntResM, FWriteIntM, ResultM); mux2 #(`XLEN) resultmuxM(IEUResultM, FIntResM, FWriteIntM, ResultM);
mux2 #(`XLEN) writedatamux(ForwardedSrcBE, FWriteDataE, ~IllegalFPUInstrE, WriteDataE); mux2 #(`XLEN) writedatamux(ForwardedSrcBE, FWriteDataE, ~IllegalFPUInstrE, WriteDataE);
@ -132,11 +131,8 @@ module datapath (
assign ResultM = IEUResultM; assign ResultM = IEUResultM;
assign WriteDataE = ForwardedSrcBE; assign WriteDataE = ForwardedSrcBE;
end end
endgenerate
// handle Store Conditional result if atomic extension supported // handle Store Conditional result if atomic extension supported
generate
if (`A_SUPPORTED) assign SCResultW = {{(`XLEN-1){1'b0}}, SquashSCW}; if (`A_SUPPORTED) assign SCResultW = {{(`XLEN-1){1'b0}}, SquashSCW};
else assign SCResultW = 0; else assign SCResultW = 0;
endgenerate
endmodule endmodule

View File

@ -32,7 +32,6 @@ module extend (
localparam [`XLEN-1:0] undefined = {(`XLEN){1'bx}}; // could change to 0 after debug localparam [`XLEN-1:0] undefined = {(`XLEN){1'bx}}; // could change to 0 after debug
// generate
always_comb always_comb
case(ImmSrcD) case(ImmSrcD)
// I-type // I-type
@ -48,7 +47,9 @@ module extend (
// Store Conditional: zero offset // Store Conditional: zero offset
3'b101: if (`A_SUPPORTED) ExtImmD = 0; 3'b101: if (`A_SUPPORTED) ExtImmD = 0;
else ExtImmD = undefined; else ExtImmD = undefined;
default: ExtImmD = undefined; // undefined default: begin
ExtImmD = undefined; // undefined
$error("Invalid ImmSrcD in extend");
end
endcase endcase
// endgenerate
endmodule endmodule

View File

@ -39,7 +39,7 @@ module shifter (
// For RV64, 32 and 64-bit shifts are needed, with sign extension. // For RV64, 32 and 64-bit shifts are needed, with sign extension.
// funnel shifter input (see CMOS VLSI Design 4e Section 11.8.1, note Table 11.11 shift types wrong) // funnel shifter input (see CMOS VLSI Design 4e Section 11.8.1, note Table 11.11 shift types wrong)
generate // generate
if (`XLEN==32) begin:shifter // RV32 if (`XLEN==32) begin:shifter // RV32
always_comb // funnel mux always_comb // funnel mux
if (Right) if (Right)
@ -62,7 +62,7 @@ module shifter (
end end
assign amttrunc = W64 ? {1'b0, Amt[4:0]} : Amt; // 32 or 64-bit shift assign amttrunc = W64 ? {1'b0, Amt[4:0]} : Amt; // 32 or 64-bit shift
end end
endgenerate // endgenerate
// opposite offset for right shfits // opposite offset for right shfits
assign offset = Right ? amttrunc : ~amttrunc; assign offset = Right ? amttrunc : ~amttrunc;

View File

@ -93,18 +93,15 @@ module SRAM2P1R1W
// read port // read port
assign RD1 = mem[RA1Q]; assign RD1 = mem[RA1Q];
genvar index;
// write port // write port
generate genvar index;
for (index = 0; index < WIDTH; index = index + 1) begin:bitwrite for (index = 0; index < WIDTH; index = index + 1) begin:bitwrite
always_ff @ (posedge clk) begin always_ff @(posedge clk) begin
if (WEN1Q & BitWEN1[index]) begin if (WEN1Q & BitWEN1[index]) begin
mem[WA1Q][index] <= WD1Q[index]; mem[WA1Q][index] <= WD1Q[index];
end end
end end
end end
endgenerate
endmodule endmodule

View File

@ -38,7 +38,6 @@ module decompress (
logic [1:0] op; logic [1:0] op;
// if the system handles compressed instructions, decode appropriately // if the system handles compressed instructions, decode appropriately
generate
if (!(`C_SUPPORTED)) begin:decompress // no compressed mode if (!(`C_SUPPORTED)) begin:decompress // no compressed mode
assign InstrD = InstrRawD; assign InstrD = InstrRawD;
assign IllegalCompInstrD = 0; assign IllegalCompInstrD = 0;
@ -173,6 +172,5 @@ module decompress (
endcase endcase
end end
end end
endgenerate
endmodule endmodule

View File

@ -38,7 +38,6 @@ module subwordread
// Funct3M[2] is the unsigned bit. mask upper bits. // Funct3M[2] is the unsigned bit. mask upper bits.
// Funct3M[1:0] is the size of the memory access. // Funct3M[1:0] is the size of the memory access.
generate
if (`XLEN == 64) begin:swrmux if (`XLEN == 64) begin:swrmux
// ByteMe mux // ByteMe mux
always_comb always_comb
@ -82,7 +81,7 @@ module subwordread
3'b110: ReadDataM = {32'b0, WordM[31:0]}; // lwu 3'b110: ReadDataM = {32'b0, WordM[31:0]}; // lwu
default: ReadDataM = ReadDataWordMuxM; // Shouldn't happen default: ReadDataM = ReadDataWordMuxM; // Shouldn't happen
endcase endcase
end else begin :swrmux // 32-bit end else begin:swrmux // 32-bit
// byte mux // byte mux
always_comb always_comb
case(LsuPAdrM[1:0]) case(LsuPAdrM[1:0])
@ -110,5 +109,4 @@ module subwordread
default: ReadDataM = ReadDataWordMuxM; default: ReadDataM = ReadDataWordMuxM;
endcase endcase
end end
endgenerate
endmodule endmodule

View File

@ -52,7 +52,7 @@ module hptw
L1_ADR, L1_RD, L1_ADR, L1_RD,
L2_ADR, L2_RD, L2_ADR, L2_RD,
L3_ADR, L3_RD, L3_ADR, L3_RD,
LEAF, IDLE} statetype; // *** placed outside generate statement to remove synthesis errors LEAF, IDLE} statetype;
logic DTLBWalk; // register TLBs translation miss requests logic DTLBWalk; // register TLBs translation miss requests
logic [`PPN_BITS-1:0] BasePageTablePPN; logic [`PPN_BITS-1:0] BasePageTablePPN;

View File

@ -90,7 +90,6 @@ module mmu #(parameter TLB_ENTRIES = 8, // number of TLB Entries
// only instantiate TLB if Virtual Memory is supported // only instantiate TLB if Virtual Memory is supported
generate
if (`MEM_VIRTMEM) begin:tlb if (`MEM_VIRTMEM) begin:tlb
logic ReadAccess, WriteAccess; 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 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
@ -110,7 +109,6 @@ module mmu #(parameter TLB_ENTRIES = 8, // number of TLB Entries
assign TLBHit = 1; // *** is this necessary assign TLBHit = 1; // *** is this necessary
assign TLBPageFault = 0; assign TLBPageFault = 0;
end end
endgenerate
// If translation is occuring, select translated physical address from TLB // If translation is occuring, select translated physical address from TLB
mux2 #(`PA_BITS) addressmux(PAdr, TLBPAdr, Translate, PhysicalAddress); mux2 #(`PA_BITS) addressmux(PAdr, TLBPAdr, Translate, PhysicalAddress);

View File

@ -68,7 +68,7 @@ module pmpadrdec (
assign NAMask[1:0] = {2'b11}; assign NAMask[1:0] = {2'b11};
assign NAMask[`PA_BITS-1:2] = (PMPAdr[`PA_BITS-3:0] + {{(`PA_BITS-3){1'b0}}, (AdrMode == NAPOT)}) ^ PMPAdr[`PA_BITS-3:0]; assign NAMask[`PA_BITS-1:2] = (PMPAdr[`PA_BITS-3:0] + {{(`PA_BITS-3){1'b0}}, (AdrMode == NAPOT)}) ^ PMPAdr[`PA_BITS-3:0];
// generates a mask where the bottom k bits are 1, corresponding to a size of 2^k bytes for this memory region. // form a mask where the bottom k bits are 1, corresponding to a size of 2^k bytes for this memory region.
// This assumes we're using at least an NA4 region, but works for any size NAPOT region. // This assumes we're using at least an NA4 region, but works for any size NAPOT region.
assign NABase = {(PMPAdr[`PA_BITS-3:0] & ~NAMask[`PA_BITS-1:2]), 2'b00}; // base physical address of the pmp. assign NABase = {(PMPAdr[`PA_BITS-3:0] & ~NAMask[`PA_BITS-1:2]), 2'b00}; // base physical address of the pmp.

View File

@ -47,7 +47,6 @@ module pmpchecker (
output logic PMPStoreAccessFaultM output logic PMPStoreAccessFaultM
); );
generate
if (`PMP_ENTRIES > 0) begin: pmpchecker if (`PMP_ENTRIES > 0) begin: pmpchecker
// Bit i is high when the address falls in PMP region i // Bit i is high when the address falls in PMP region i
logic EnforcePMP; logic EnforcePMP;
@ -78,6 +77,4 @@ module pmpchecker (
assign PMPLoadAccessFaultM = 0; assign PMPLoadAccessFaultM = 0;
assign PMPStoreAccessFaultM = 0; assign PMPStoreAccessFaultM = 0;
end end
endgenerate
//assign PMPSquashBusAccess = PMPInstrAccessFaultF | PMPLoadAccessFaultM | PMPStoreAccessFaultM;
endmodule endmodule

View File

@ -34,25 +34,9 @@ module priorityonehot #(parameter ENTRIES = 8) (
input logic [ENTRIES-1:0] a, input logic [ENTRIES-1:0] a,
output logic [ENTRIES-1:0] y output logic [ENTRIES-1:0] y
); );
/* verilator lint_off UNOPTFLAT */
logic [ENTRIES-1:0] nolower; logic [ENTRIES-1:0] nolower;
// generate thermometer code mask // create thermometer code mask
prioritythermometer #(ENTRIES) maskgen(.a({a[ENTRIES-2:0], 1'b1}), .y(nolower)); prioritythermometer #(ENTRIES) maskgen(.a({a[ENTRIES-2:0], 1'b1}), .y(nolower));
// genvar i;
// generate
// assign nolower[0] = 1'b1;
// for (i=1; i<ENTRIES; i++) begin:therm
// assign nolower[i] = nolower[i-1] & ~a[i-1];
// end
// endgenerate
// *** replace mask generation logic ^^^ with priority thermometer
assign y = a & nolower; assign y = a & nolower;
/* verilator lint_on UNOPTFLAT */
endmodule endmodule

View File

@ -37,20 +37,15 @@ module prioritythermometer #(parameter N = 8) (
output logic [N-1:0] y output logic [N-1:0] y
); );
// Carefully crafted so design compiler would synthesize into a fast tree structure // Carefully crafted so design compiler will synthesize into a fast tree structure
// Rather than linear. // Rather than linear.
// generate thermometer code mask // create thermometer code mask
genvar i; genvar i;
generate
assign y[0] = a[0]; assign y[0] = a[0];
for (i=1; i<N; i++) begin:therm for (i=1; i<N; i++) begin:therm
assign y[i] = y[i-1] & ~a[i]; // *** made to be the same as onehot (without the inverter) to see if the probelme is something weird with synthesis assign y[i] = y[i-1] & ~a[i];
// assign y[i] = y[i-1] & a[i];
end end
endgenerate
endmodule endmodule

View File

@ -60,8 +60,7 @@ module tlbcamline #(parameter KEY_BITS = 20,
assign MatchASID = (SATP_ASID == Key_ASID) | PTE_G; assign MatchASID = (SATP_ASID == Key_ASID) | PTE_G;
generate if (`XLEN == 32) begin: match
if (`XLEN == 32) begin:match
assign {Key_ASID, Key1, Key0} = Key; assign {Key_ASID, Key1, Key0} = Key;
assign {Query1, Query0} = VPN; assign {Query1, Query0} = VPN;
@ -73,7 +72,7 @@ module tlbcamline #(parameter KEY_BITS = 20,
assign Match1 = (Query1 == Key1); assign Match1 = (Query1 == Key1);
assign Match = Match0 & Match1 & MatchASID & Valid; assign Match = Match0 & Match1 & MatchASID & Valid;
end else begin:match end else begin: match
logic [SEGMENT_BITS-1:0] Key2, Key3, Query2, Query3; logic [SEGMENT_BITS-1:0] Key2, Key3, Query2, Query3;
logic Match2, Match3; logic Match2, Match3;
@ -91,7 +90,6 @@ module tlbcamline #(parameter KEY_BITS = 20,
assign Match = Match0 & Match1 & Match2 & Match3 & MatchASID & Valid; assign Match = Match0 & Match1 & Match2 & Match3 & MatchASID & Valid;
end end
endgenerate
// On a write, update the type of the page referred to by this line. // On a write, update the type of the page referred to by this line.
flopenr #(2) pagetypeflop(clk, reset, WriteEnable, PageTypeWriteVal, PageType); flopenr #(2) pagetypeflop(clk, reset, WriteEnable, PageTypeWriteVal, PageType);

View File

@ -60,14 +60,14 @@ module tlbcontrol #(parameter ITLB = 0) (
logic UpperBitsUnequalPageFault; logic UpperBitsUnequalPageFault;
logic DAPageFault; logic DAPageFault;
logic TLBAccess; logic TLBAccess;
logic ImproperPrivilege;
// Grab the sv mode from SATP and determine whether translation should occur // Grab the sv mode from SATP and determine whether translation should occur
assign EffectivePrivilegeMode = (ITLB == 1) ? PrivilegeModeW : (STATUS_MPRV ? STATUS_MPP : PrivilegeModeW); // DTLB uses MPP mode when MPRV is 1 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; assign Translate = (SATP_MODE != `NO_TRANSLATE) & (EffectivePrivilegeMode != `M_MODE) & ~DisableTranslation;
generate
if (`XLEN==64) begin:rv64 if (`XLEN==64) begin:rv64
assign SV39Mode = (SATP_MODE == `SV39); assign SV39Mode = (SATP_MODE == `SV39);
// generate page fault if upper bits aren't all the same // page fault if upper bits aren't all the same
logic UpperEqual39, UpperEqual48; logic UpperEqual39, UpperEqual48;
assign UpperEqual39 = &(VAdr[63:38]) | ~|(VAdr[63:38]); assign UpperEqual39 = &(VAdr[63:38]) | ~|(VAdr[63:38]);
assign UpperEqual48 = &(VAdr[63:47]) | ~|(VAdr[63:47]); assign UpperEqual48 = &(VAdr[63:47]) | ~|(VAdr[63:47]);
@ -76,23 +76,18 @@ module tlbcontrol #(parameter ITLB = 0) (
assign SV39Mode = 0; assign SV39Mode = 0;
assign UpperBitsUnequalPageFault = 0; assign UpperBitsUnequalPageFault = 0;
end end
endgenerate
// Determine whether TLB is being used // Determine whether TLB is being used
assign TLBAccess = ReadAccess | WriteAccess; assign TLBAccess = ReadAccess | WriteAccess;
// Check whether upper bits of virtual addresss are all equal // Check whether upper bits of virtual addresss are all equal
// unswizzle useful PTE bits // unswizzle useful PTE bits
assign {PTE_D, PTE_A} = PTEAccessBits[7:6]; assign {PTE_D, PTE_A} = PTEAccessBits[7:6];
assign {PTE_U, PTE_X, PTE_W, PTE_R, PTE_V} = PTEAccessBits[4:0]; assign {PTE_U, PTE_X, PTE_W, PTE_R, PTE_V} = PTEAccessBits[4:0];
// Check whether the access is allowed, page faulting if not. // Check whether the access is allowed, page faulting if not.
generate
if (ITLB == 1) begin:itlb // 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 // User mode may only execute user mode pages, and supervisor mode may
// only execute non-user mode pages. // only execute non-user mode pages.
assign ImproperPrivilege = ((EffectivePrivilegeMode == `U_MODE) & ~PTE_U) | assign ImproperPrivilege = ((EffectivePrivilegeMode == `U_MODE) & ~PTE_U) |
@ -101,7 +96,7 @@ module tlbcontrol #(parameter ITLB = 0) (
assign DAPageFault = ~PTE_A; assign DAPageFault = ~PTE_A;
assign TLBPageFault = (Translate & TLBHit & (ImproperPrivilege | ~PTE_X | DAPageFault | UpperBitsUnequalPageFault | Misaligned | ~PTE_V)); assign TLBPageFault = (Translate & TLBHit & (ImproperPrivilege | ~PTE_X | DAPageFault | UpperBitsUnequalPageFault | Misaligned | ~PTE_V));
end else begin:dtlb // Data TLB fault checking end else begin:dtlb // Data TLB fault checking
logic ImproperPrivilege, InvalidRead, InvalidWrite; logic InvalidRead, InvalidWrite;
// User mode may only load/store from user mode pages, and supervisor mode // User mode may only load/store from user mode pages, and supervisor mode
// may only access user mode pages when STATUS_SUM is low. // may only access user mode pages when STATUS_SUM is low.
@ -118,7 +113,6 @@ module tlbcontrol #(parameter ITLB = 0) (
assign DAPageFault = ~PTE_A | WriteAccess & ~PTE_D; assign DAPageFault = ~PTE_A | WriteAccess & ~PTE_D;
assign TLBPageFault = (Translate & TLBHit & (ImproperPrivilege | InvalidRead | InvalidWrite | DAPageFault | UpperBitsUnequalPageFault | Misaligned | ~PTE_V)); assign TLBPageFault = (Translate & TLBHit & (ImproperPrivilege | InvalidRead | InvalidWrite | DAPageFault | UpperBitsUnequalPageFault | Misaligned | ~PTE_V));
end end
endgenerate
assign TLBHit = CAMHit & TLBAccess; assign TLBHit = CAMHit & TLBAccess;
assign TLBMiss = (~CAMHit | TLBFlush) & Translate & TLBAccess; assign TLBMiss = (~CAMHit | TLBFlush) & Translate & TLBAccess;

View File

@ -43,7 +43,6 @@ module tlbmixer (
logic [`PPN_BITS-1:0] PPNMixed; logic [`PPN_BITS-1:0] PPNMixed;
// produce PageNumberMask with 1s where virtual page number bits should be untranslaetd for superpages // produce PageNumberMask with 1s where virtual page number bits should be untranslaetd for superpages
generate
if (`XLEN == 32) if (`XLEN == 32)
// kilopage: 22 bits of PPN, 0 bits of VPN // kilopage: 22 bits of PPN, 0 bits of VPN
// megapage: 12 bits of PPN, 10 bits of VPN // megapage: 12 bits of PPN, 10 bits of VPN
@ -54,7 +53,6 @@ module tlbmixer (
// gigapage: 26 bits of PPN, 18 bits of VPN // gigapage: 26 bits of PPN, 18 bits of VPN
// terapage: 17 bits of PPN, 27 bits of VPN // terapage: 17 bits of PPN, 27 bits of VPN
mux4 #(44) pnm(44'h00000000000, 44'h000000001FF, 44'h0000003FFFF, 44'h00007FFFFFF, HitPageType, PageNumberMask); mux4 #(44) pnm(44'h00000000000, 44'h000000001FF, 44'h0000003FFFF, 44'h00007FFFFFF, HitPageType, PageNumberMask);
endgenerate
// merge low segments of VPN with high segments of PPN decided by the pagetype. // merge low segments of VPN with high segments of PPN decided by the pagetype.
assign ZeroExtendedVPN = {{EXTRA_BITS{1'b0}}, VPN}; // forces the VPN to be the same width as PPN. assign ZeroExtendedVPN = {{EXTRA_BITS{1'b0}}, VPN}; // forces the VPN to be the same width as PPN.

File diff suppressed because it is too large Load Diff

View File

@ -60,7 +60,6 @@ module intdivrestoring (
assign DivBusyE = (state == BUSY) | DivStartE; assign DivBusyE = (state == BUSY) | DivStartE;
// Handle sign extension for W-type instructions // Handle sign extension for W-type instructions
generate
if (`XLEN == 64) begin:rv64 // 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) xinmux(ForwardedSrcAE, {ForwardedSrcAE[31:0], 32'b0}, W64E, XinE);
mux2 #(`XLEN) dinmux(ForwardedSrcBE, {{32{ForwardedSrcBE[31]&DivSignedE}}, ForwardedSrcBE[31:0]}, W64E, DinE); mux2 #(`XLEN) dinmux(ForwardedSrcBE, {{32{ForwardedSrcBE[31]&DivSignedE}}, ForwardedSrcBE[31:0]}, W64E, DinE);
@ -68,7 +67,6 @@ module intdivrestoring (
assign XinE = ForwardedSrcAE; assign XinE = ForwardedSrcAE;
assign DinE = ForwardedSrcBE; assign DinE = ForwardedSrcBE;
end end
endgenerate
// Extract sign bits and check fo division by zero // Extract sign bits and check fo division by zero
assign SignDE = DivSignedE & DinE[`XLEN-1]; assign SignDE = DivSignedE & DinE[`XLEN-1];
@ -97,11 +95,9 @@ module intdivrestoring (
flopen #(3) Div0eMReg(clk, DivStartE, {Div0E, NegQE, SignXE}, {Div0M, NegQM, NegWM}); flopen #(3) Div0eMReg(clk, DivStartE, {Div0E, NegQE, SignXE}, {Div0M, NegQM, NegWM});
// one copy of divstep for each bit produced per cycle // one copy of divstep for each bit produced per cycle
generate
genvar i; genvar i;
for (i=0; i<`DIV_BITSPERCYCLE; i = i+1) for (i=0; i<`DIV_BITSPERCYCLE; i = i+1)
intdivrestoringstep divstep(WM[i], XQM[i], DAbsBM, WM[i+1], XQM[i+1]); intdivrestoringstep divstep(WM[i], XQM[i], DAbsBM, WM[i+1], XQM[i+1]);
endgenerate
// On final setp of signed operations, negate outputs as needed to get correct sign // On final setp of signed operations, negate outputs as needed to get correct sign
neg #(`XLEN) qneg(XQM[0], XQnM); neg #(`XLEN) qneg(XQM[0], XQnM);

View File

@ -49,8 +49,8 @@ module mul (
// Signed * Unsigned = P' + ( PA - PB)*2^(XLEN-1) - PP*2^(2XLEN-2) // Signed * Unsigned = P' + ( PA - PB)*2^(XLEN-1) - PP*2^(2XLEN-2)
// Unsigned * Unsigned = P' + ( PA + PB)*2^(XLEN-1) + PP*2^(2XLEN-2) // Unsigned * Unsigned = P' + ( PA + PB)*2^(XLEN-1) + PP*2^(2XLEN-2)
logic [`XLEN*2-1:0] PP0E, PP1E, PP2E, PP3E, PP4E; logic [`XLEN*2-1:0] PP1E, PP2E, PP3E, PP4E;
logic [`XLEN*2-1:0] PP0M, PP1M, PP2M, PP3M, PP4M; logic [`XLEN*2-1:0] PP1M, PP2M, PP3M, PP4M;
logic [`XLEN-2:0] PA, PB; logic [`XLEN-2:0] PA, PB;
logic PP; logic PP;
logic MULH, MULHSU; logic MULH, MULHSU;
@ -62,7 +62,7 @@ module mul (
assign Aprime = {1'b0, ForwardedSrcAE[`XLEN-2:0]}; assign Aprime = {1'b0, ForwardedSrcAE[`XLEN-2:0]};
assign Bprime = {1'b0, ForwardedSrcBE[`XLEN-2:0]}; assign Bprime = {1'b0, ForwardedSrcBE[`XLEN-2:0]};
redundantmul #(`XLEN) bigmul(.a(Aprime), .b(Bprime), .out0(PP0E), .out1(PP1E)); assign PP1E = Aprime * Bprime;
assign PA = {(`XLEN-1){ForwardedSrcAE[`XLEN-1]}} & ForwardedSrcBE[`XLEN-2:0]; assign PA = {(`XLEN-1){ForwardedSrcAE[`XLEN-1]}} & ForwardedSrcBE[`XLEN-2:0];
assign PB = {(`XLEN-1){ForwardedSrcBE[`XLEN-1]}} & ForwardedSrcAE[`XLEN-2:0]; assign PB = {(`XLEN-1){ForwardedSrcBE[`XLEN-1]}} & ForwardedSrcAE[`XLEN-2:0];
assign PP = ForwardedSrcAE[`XLEN-1] & ForwardedSrcBE[`XLEN-1]; assign PP = ForwardedSrcAE[`XLEN-1] & ForwardedSrcBE[`XLEN-1];
@ -83,12 +83,11 @@ module mul (
// Memory Stage: Sum partial proudcts // Memory Stage: Sum partial proudcts
////////////////////////////// //////////////////////////////
flopenrc #(`XLEN*2) PP0Reg(clk, reset, FlushM, ~StallM, PP0E, PP0M);
flopenrc #(`XLEN*2) PP1Reg(clk, reset, FlushM, ~StallM, PP1E, PP1M); flopenrc #(`XLEN*2) PP1Reg(clk, reset, FlushM, ~StallM, PP1E, PP1M);
flopenrc #(`XLEN*2) PP2Reg(clk, reset, FlushM, ~StallM, PP2E, PP2M); flopenrc #(`XLEN*2) PP2Reg(clk, reset, FlushM, ~StallM, PP2E, PP2M);
flopenrc #(`XLEN*2) PP3Reg(clk, reset, FlushM, ~StallM, PP3E, PP3M); flopenrc #(`XLEN*2) PP3Reg(clk, reset, FlushM, ~StallM, PP3E, PP3M);
flopenrc #(`XLEN*2) PP4Reg(clk, reset, FlushM, ~StallM, PP4E, PP4M); flopenrc #(`XLEN*2) PP4Reg(clk, reset, FlushM, ~StallM, PP4E, PP4M);
assign ProdM = PP0M + PP1M + PP2M + PP3M + PP4M; //ForwardedSrcAE * ForwardedSrcBE; assign ProdM = PP1M + PP2M + PP3M + PP4M; //ForwardedSrcAE * ForwardedSrcBE;
endmodule endmodule

View File

@ -74,13 +74,11 @@ module muldiv (
// Handle sign extension for W-type instructions // Handle sign extension for W-type instructions
flopenrc #(1) W64MReg(clk, reset, FlushM, ~StallM, W64E, W64M); flopenrc #(1) W64MReg(clk, reset, FlushM, ~StallM, W64E, W64M);
generate
if (`XLEN == 64) begin:resmux // RV64 has W-type instructions if (`XLEN == 64) begin:resmux // RV64 has W-type instructions
assign MulDivResultM = W64M ? {{32{PrelimResultM[31]}}, PrelimResultM[31:0]} : PrelimResultM; assign MulDivResultM = W64M ? {{32{PrelimResultM[31]}}, PrelimResultM[31:0]} : PrelimResultM;
end else begin:resmux // RV32 has no W-type instructions end else begin:resmux // RV32 has no W-type instructions
assign MulDivResultM = PrelimResultM; assign MulDivResultM = PrelimResultM;
end end
endgenerate
// Writeback stage pipeline register // Writeback stage pipeline register
flopenrc #(`XLEN) MulDivResultWReg(clk, reset, FlushW, ~StallW, MulDivResultM, MulDivResultW); flopenrc #(`XLEN) MulDivResultWReg(clk, reset, FlushW, ~StallW, MulDivResultM, MulDivResultW);

View File

@ -56,7 +56,6 @@ module csrc #(parameter
output logic IllegalCSRCAccessM output logic IllegalCSRCAccessM
); );
generate
if (`ZICOUNTERS_SUPPORTED) begin:counters if (`ZICOUNTERS_SUPPORTED) begin:counters
(* mark_debug = "true" *) logic [63:0] CYCLE_REGW, INSTRET_REGW; (* mark_debug = "true" *) logic [63:0] CYCLE_REGW, INSTRET_REGW;
logic [63:0] CYCLEPlusM, INSTRETPlusM; logic [63:0] CYCLEPlusM, INSTRETPlusM;
@ -82,9 +81,9 @@ module csrc #(parameter
assign CounterEvent[0] = 1'b1; // MCYCLE always increments assign CounterEvent[0] = 1'b1; // MCYCLE always increments
assign CounterEvent[1] = 1'b0; // Counter 0 doesn't exist assign CounterEvent[1] = 1'b0; // Counter 0 doesn't exist
assign CounterEvent[2] = InstrValidNotFlushedM; assign CounterEvent[2] = InstrValidNotFlushedM;
if(`QEMU) begin // No other performance counters in QEMU if(`QEMU) begin: cevent // No other performance counters in QEMU
assign CounterEvent[`COUNTERS-1:3] = 0; assign CounterEvent[`COUNTERS-1:3] = 0;
end else begin // User-defined counters end else begin: cevent // User-defined counters
assign CounterEvent[3] = LoadStallM; // don't want to suppress on flush as this only happens if flushed. assign CounterEvent[3] = LoadStallM; // don't want to suppress on flush as this only happens if flushed.
assign CounterEvent[4] = BPPredDirWrongM & InstrValidNotFlushedM; assign CounterEvent[4] = BPPredDirWrongM & InstrValidNotFlushedM;
assign CounterEvent[5] = InstrClassM[0] & InstrValidNotFlushedM; assign CounterEvent[5] = InstrClassM[0] & InstrValidNotFlushedM;
@ -99,7 +98,7 @@ module csrc #(parameter
end end
// Counter update and write logic // Counter update and write logic
for (i = 0; i < `COUNTERS; i = i+1) begin for (i = 0; i < `COUNTERS; i = i+1) begin:cntr
assign WriteHPMCOUNTERM[i] = CSRMWriteM & (CSRAdrM == MHPMCOUNTERBASE + i); assign WriteHPMCOUNTERM[i] = CSRMWriteM & (CSRAdrM == MHPMCOUNTERBASE + i);
assign NextHPMCOUNTERM[i][`XLEN-1:0] = WriteHPMCOUNTERM[i] ? CSRWriteValM : HPMCOUNTERPlusM[i][`XLEN-1:0]; assign NextHPMCOUNTERM[i][`XLEN-1:0] = WriteHPMCOUNTERM[i] ? CSRWriteValM : HPMCOUNTERPlusM[i][`XLEN-1:0];
always_ff @(posedge clk) //, posedge reset) // ModelSim doesn't like syntax of passing array element to flop always_ff @(posedge clk) //, posedge reset) // ModelSim doesn't like syntax of passing array element to flop
@ -160,7 +159,6 @@ module csrc #(parameter
assign CSRCReadValM = 0; assign CSRCReadValM = 0;
assign IllegalCSRCAccessM = 1; // counters aren't enabled assign IllegalCSRCAccessM = 1; // counters aren't enabled
end end
endgenerate
endmodule endmodule
// To Do: // To Do:

View File

@ -66,11 +66,10 @@ module csri #(parameter
assign WriteSIPM = CSRSWriteM & (CSRAdrM == SIP) & ~StallW; assign WriteSIPM = CSRSWriteM & (CSRAdrM == SIP) & ~StallW;
assign WriteSIEM = CSRSWriteM & (CSRAdrM == SIE) & ~StallW; assign WriteSIEM = CSRSWriteM & (CSRAdrM == SIE) & ~StallW;
// Interrupt Pending and Enable Registers // Interrupt Pending and Enable Registers
// MEIP, MTIP, MSIP are read-only // MEIP, MTIP, MSIP are read-only
// SEIP, STIP, SSIP is writable in MIP if S mode exists // SEIP, STIP, SSIP is writable in MIP if S mode exists
// SSIP is writable in SIP if S mode exists // SSIP is writable in SIP if S mode exists
generate
if (`S_SUPPORTED) begin:mask if (`S_SUPPORTED) begin:mask
assign MIP_WRITE_MASK = 12'h222; // SEIP, STIP, SSIP are writable in MIP (20210108-draft 3.1.9) 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) assign SIP_WRITE_MASK = 12'h002; // SSIP is writable in SIP (privileged 20210108-draft 4.1.3)
@ -89,10 +88,8 @@ module csri #(parameter
else if (WriteMIEM) IE_REGW <= (CSRWriteValM[11:0] & 12'hAAA); // MIE controls M and S fields else if (WriteMIEM) IE_REGW <= (CSRWriteValM[11:0] & 12'hAAA); // MIE controls M and S fields
else if (WriteSIEM) IE_REGW <= (CSRWriteValM[11:0] & 12'h222) | (IE_REGW & 12'h888); // only S fields else if (WriteSIEM) IE_REGW <= (CSRWriteValM[11:0] & 12'h222) | (IE_REGW & 12'h888); // only S fields
// else if (WriteUIEM) IE_REGW = (CSRWriteValM & 12'h111) | (IE_REGW & 12'hAAA); // only U field // else if (WriteUIEM) IE_REGW = (CSRWriteValM & 12'h111) | (IE_REGW & 12'hAAA); // only U field
endgenerate
// restricted views of registers // restricted views of registers
generate
always_comb begin:regs always_comb begin:regs
// Add MEIP read-only signal // Add MEIP read-only signal
IP_REGW = {IntInM[11],1'b0,IP_REGW_writeable}; IP_REGW = {IntInM[11],1'b0,IP_REGW_writeable};
@ -119,5 +116,4 @@ module csri #(parameter
UIE_REGW = 12'b0; UIE_REGW = 12'b0;
end */ end */
end end
endgenerate
endmodule endmodule

View File

@ -92,7 +92,6 @@ module csrm #(parameter
// There are PMP_ENTRIES = 0, 16, or 64 PMPADDR registers, each of which has its own flop // There are PMP_ENTRIES = 0, 16, or 64 PMPADDR registers, each of which has its own flop
genvar i; genvar i;
generate
if (`PMP_ENTRIES > 0) begin:pmp if (`PMP_ENTRIES > 0) begin:pmp
logic [`PMP_ENTRIES-1:0] WritePMPCFGM; logic [`PMP_ENTRIES-1:0] WritePMPCFGM;
logic [`PMP_ENTRIES-1:0] WritePMPADDRM ; logic [`PMP_ENTRIES-1:0] WritePMPADDRM ;
@ -117,7 +116,6 @@ module csrm #(parameter
end end
end end
end end
endgenerate
localparam MISA_26 = (`MISA) & 32'h03ffffff; localparam MISA_26 = (`MISA) & 32'h03ffffff;
@ -143,7 +141,6 @@ module csrm #(parameter
// CSRs // CSRs
flopenr #(`XLEN) MTVECreg(clk, reset, WriteMTVECM, {CSRWriteValM[`XLEN-1:2], 1'b0, CSRWriteValM[0]}, MTVEC_REGW); //busybear: changed reset value to 0 flopenr #(`XLEN) MTVECreg(clk, reset, WriteMTVECM, {CSRWriteValM[`XLEN-1:2], 1'b0, CSRWriteValM[0]}, MTVEC_REGW); //busybear: changed reset value to 0
generate
if (`S_SUPPORTED | (`U_SUPPORTED & `N_SUPPORTED)) begin:deleg // DELEG registers should exist if (`S_SUPPORTED | (`U_SUPPORTED & `N_SUPPORTED)) begin:deleg // DELEG registers should exist
flopenr #(`XLEN) MEDELEGreg(clk, reset, WriteMEDELEGM, CSRWriteValM & MEDELEG_MASK /*12'h7FF*/, MEDELEG_REGW); flopenr #(`XLEN) MEDELEGreg(clk, reset, WriteMEDELEGM, CSRWriteValM & MEDELEG_MASK /*12'h7FF*/, MEDELEG_REGW);
flopenr #(`XLEN) MIDELEGreg(clk, reset, WriteMIDELEGM, CSRWriteValM & MIDELEG_MASK /*12'h222*/, MIDELEG_REGW); flopenr #(`XLEN) MIDELEGreg(clk, reset, WriteMIDELEGM, CSRWriteValM & MIDELEG_MASK /*12'h222*/, MIDELEG_REGW);
@ -151,20 +148,17 @@ module csrm #(parameter
assign MEDELEG_REGW = 0; assign MEDELEG_REGW = 0;
assign MIDELEG_REGW = 0; assign MIDELEG_REGW = 0;
end end
endgenerate
flopenr #(`XLEN) MSCRATCHreg(clk, reset, WriteMSCRATCHM, CSRWriteValM, MSCRATCH_REGW); flopenr #(`XLEN) MSCRATCHreg(clk, reset, WriteMSCRATCHM, CSRWriteValM, MSCRATCH_REGW);
flopenr #(`XLEN) MEPCreg(clk, reset, WriteMEPCM, NextEPCM, MEPC_REGW); flopenr #(`XLEN) MEPCreg(clk, reset, WriteMEPCM, NextEPCM, MEPC_REGW);
flopenr #(`XLEN) MCAUSEreg(clk, reset, WriteMCAUSEM, NextCauseM, MCAUSE_REGW); flopenr #(`XLEN) MCAUSEreg(clk, reset, WriteMCAUSEM, NextCauseM, MCAUSE_REGW);
if(`QEMU) assign MTVAL_REGW = `XLEN'b0; if(`QEMU) assign MTVAL_REGW = `XLEN'b0;
else flopenr #(`XLEN) MTVALreg(clk, reset, WriteMTVALM, NextMtvalM, MTVAL_REGW); else flopenr #(`XLEN) MTVALreg(clk, reset, WriteMTVALM, NextMtvalM, MTVAL_REGW);
generate // *** needs comment about bit 1 if (`BUSYBEAR == 1) begin:counters // counter 1 (TIME) enable tied to 0 to match simulator***
if (`BUSYBEAR == 1) begin:counters
flopenr #(32) MCOUNTERENreg(clk, reset, WriteMCOUNTERENM, {CSRWriteValM[31:2],1'b0,CSRWriteValM[0]}, MCOUNTEREN_REGW); flopenr #(32) MCOUNTERENreg(clk, reset, WriteMCOUNTERENM, {CSRWriteValM[31:2],1'b0,CSRWriteValM[0]}, MCOUNTEREN_REGW);
end else begin:counters end else begin:counters
flopenr #(32) MCOUNTERENreg(clk, reset, WriteMCOUNTERENM, CSRWriteValM[31:0], MCOUNTEREN_REGW); flopenr #(32) MCOUNTERENreg(clk, reset, WriteMCOUNTERENM, CSRWriteValM[31:0], MCOUNTEREN_REGW);
end end
endgenerate
flopenr #(32) MCOUNTINHIBITreg(clk, reset, WriteMCOUNTINHIBITM, CSRWriteValM[31:0], MCOUNTINHIBIT_REGW); flopenr #(32) MCOUNTINHIBITreg(clk, reset, WriteMCOUNTINHIBITM, CSRWriteValM[31:0], MCOUNTINHIBIT_REGW);

View File

@ -49,8 +49,7 @@ module csrn #(parameter
); );
// User mode CSRs below only needed when user mode traps are supported // User mode CSRs below only needed when user mode traps are supported
generate if (`N_SUPPORTED) begin:nmode // depricated; consider removing***
if (`N_SUPPORTED) begin:nmode
logic WriteUTVECM; logic WriteUTVECM;
logic WriteUSCRATCHM, WriteUEPCM; logic WriteUSCRATCHM, WriteUEPCM;
logic WriteUCAUSEM, WriteUTVALM; logic WriteUCAUSEM, WriteUTVALM;
@ -96,5 +95,4 @@ module csrn #(parameter
assign UTVEC_REGW = 0; assign UTVEC_REGW = 0;
assign IllegalCSRNAccessM = 1; assign IllegalCSRNAccessM = 1;
end end
endgenerate endmodule
endmodule

View File

@ -69,7 +69,6 @@ module csrs #(parameter
//logic [`XLEN-1:0] SEDELEG_MASK = ~(zero | 3'b111 << 9); // sedeleg[11:9] hardwired to zero per Privileged Spec 3.1.8 //logic [`XLEN-1:0] SEDELEG_MASK = ~(zero | 3'b111 << 9); // sedeleg[11:9] hardwired to zero per Privileged Spec 3.1.8
// Supervisor mode CSRs sometimes supported // Supervisor mode CSRs sometimes supported
generate
if (`S_SUPPORTED) begin:csrs if (`S_SUPPORTED) begin:csrs
logic WriteSTVECM; logic WriteSTVECM;
logic WriteSSCRATCHM, WriteSEPCM; logic WriteSSCRATCHM, WriteSEPCM;
@ -153,5 +152,4 @@ module csrs #(parameter
assign SATP_REGW = 0; assign SATP_REGW = 0;
assign IllegalCSRSAccessM = 1; assign IllegalCSRSAccessM = 1;
end end
endgenerate
endmodule endmodule

View File

@ -50,7 +50,6 @@ module csrsr (
// See Privileged Spec Section 3.1.6 // See Privileged Spec Section 3.1.6
// Lower privilege status registers are a subset of the full status register // Lower privilege status registers are a subset of the full status register
// *** consider adding MBE, SBE, UBE fields later from 20210108 draft spec // *** consider adding MBE, SBE, UBE fields later from 20210108 draft spec
generate
if (`XLEN==64) begin: csrsr64 // RV64 if (`XLEN==64) begin: csrsr64 // RV64
assign MSTATUS_REGW = {STATUS_SD, 27'b0, STATUS_SXL, STATUS_UXL, 9'b0, assign MSTATUS_REGW = {STATUS_SD, 27'b0, STATUS_SXL, STATUS_UXL, 9'b0,
STATUS_TSR, STATUS_TW, STATUS_TVM, STATUS_MXR, STATUS_SUM, STATUS_MPRV, STATUS_TSR, STATUS_TW, STATUS_TVM, STATUS_MXR, STATUS_SUM, STATUS_MPRV,
@ -83,10 +82,8 @@ module csrsr (
/*STATUS_SPP, STATUS_MPIE, 1'b0 2'b0, STATUS_SPIE,*/ STATUS_UPIE, /*STATUS_SPP, STATUS_MPIE, 1'b0 2'b0, STATUS_SPIE,*/ STATUS_UPIE,
/*STATUS_MIE, 1'b0*/ 3'b0, /*STATUS_SIE, */STATUS_UIE}; /*STATUS_MIE, 1'b0*/ 3'b0, /*STATUS_SIE, */STATUS_UIE};
end end
endgenerate
// harwired STATUS bits // harwired STATUS bits
generate
assign STATUS_TSR = `S_SUPPORTED & STATUS_TSR_INT; // override reigster with 0 if supervisor mode not supported assign STATUS_TSR = `S_SUPPORTED & STATUS_TSR_INT; // override reigster with 0 if supervisor mode not supported
assign STATUS_TW = (`S_SUPPORTED | `U_SUPPORTED) & STATUS_TW_INT; // override reigster with 0 if only machine mode supported assign STATUS_TW = (`S_SUPPORTED | `U_SUPPORTED) & STATUS_TW_INT; // override reigster with 0 if only machine mode supported
assign STATUS_TVM = `S_SUPPORTED & STATUS_TVM_INT; // override reigster with 0 if supervisor mode not supported assign STATUS_TVM = `S_SUPPORTED & STATUS_TVM_INT; // override reigster with 0 if supervisor mode not supported
@ -97,7 +94,6 @@ module csrsr (
assign STATUS_SUM = `S_SUPPORTED & `MEM_VIRTMEM & STATUS_SUM_INT; // override reigster with 0 if supervisor mode not supported assign STATUS_SUM = `S_SUPPORTED & `MEM_VIRTMEM & STATUS_SUM_INT; // override reigster with 0 if supervisor mode not supported
assign STATUS_MPRV = `U_SUPPORTED & STATUS_MPRV_INT; // override with 0 if user mode not supported assign STATUS_MPRV = `U_SUPPORTED & STATUS_MPRV_INT; // override with 0 if user mode not supported
assign STATUS_FS = (`S_SUPPORTED & (`F_SUPPORTED | `D_SUPPORTED)) ? STATUS_FS_INT : 2'b00; // off if no FP assign STATUS_FS = (`S_SUPPORTED & (`F_SUPPORTED | `D_SUPPORTED)) ? STATUS_FS_INT : 2'b00; // off if no FP
endgenerate
assign STATUS_SD = (STATUS_FS == 2'b11) | (STATUS_XS == 2'b11); // dirty state logic assign STATUS_SD = (STATUS_FS == 2'b11) | (STATUS_XS == 2'b11); // dirty state logic
assign STATUS_XS = 2'b00; // No additional user-mode state to be dirty assign STATUS_XS = 2'b00; // No additional user-mode state to be dirty

View File

@ -44,7 +44,6 @@ module csru #(parameter
); );
// Floating Point CSRs in User Mode only needed if Floating Point is supported // Floating Point CSRs in User Mode only needed if Floating Point is supported
generate
if (`F_SUPPORTED | `D_SUPPORTED) begin:csru if (`F_SUPPORTED | `D_SUPPORTED) begin:csru
logic [4:0] FFLAGS_REGW; logic [4:0] FFLAGS_REGW;
logic [2:0] NextFRMM; logic [2:0] NextFRMM;
@ -81,5 +80,4 @@ module csru #(parameter
assign CSRUReadValM = 0; assign CSRUReadValM = 0;
assign IllegalCSRUAccessM = 1; assign IllegalCSRUAccessM = 1;
end end
endgenerate
endmodule endmodule

View File

@ -103,7 +103,6 @@ module trap (
// > implemented without a hardware adder circuit. // > implemented without a hardware adder circuit.
// For example, we could require m/stvec be aligned on 7 bits to let us replace the adder directly below with // 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} // [untested] PrivilegedVectoredTrapVector = {PrivilegedTrapVector[`XLEN-1:7], CauseM[3:0], 4'b0000}
generate
if(`VECTORED_INTERRUPTS_SUPPORTED) begin:vec if(`VECTORED_INTERRUPTS_SUPPORTED) begin:vec
always_comb always_comb
if (PrivilegedTrapVector[1:0] == 2'b01 & CauseM[`XLEN-1] == 1) if (PrivilegedTrapVector[1:0] == 2'b01 & CauseM[`XLEN-1] == 1)
@ -114,7 +113,6 @@ module trap (
else begin else begin
assign PrivilegedVectoredTrapVector = {PrivilegedTrapVector[`XLEN-1:2], 2'b00}; assign PrivilegedVectoredTrapVector = {PrivilegedTrapVector[`XLEN-1:2], 2'b00};
end end
endgenerate
always_comb always_comb
if (mretM) PrivilegedNextPCM = MEPC_REGW; if (mretM) PrivilegedNextPCM = MEPC_REGW;

View File

@ -55,12 +55,8 @@ module clint (
assign HREADYCLINT = 1'b1; // *** needs to depend on DONE during accesses assign HREADYCLINT = 1'b1; // *** needs to depend on DONE during accesses
// word aligned reads // word aligned reads
generate if (`XLEN==64) assign #2 entry = {HADDR[15:3], 3'b000};
if (`XLEN==64) else assign #2 entry = {HADDR[15:2], 2'b00};
assign #2 entry = {HADDR[15:3], 3'b000};
else
assign #2 entry = {HADDR[15:2], 2'b00};
endgenerate
// DH 2/20/21: Eventually allow MTIME to run off a separate clock // DH 2/20/21: Eventually allow MTIME to run off a separate clock
// This will require synchronizing MTIME to the system clock // This will require synchronizing MTIME to the system clock
@ -69,7 +65,6 @@ module clint (
// Use req and ack signals synchronized across the clock domains. // Use req and ack signals synchronized across the clock domains.
// register access // register access
generate
if (`XLEN==64) begin:clint // 64-bit if (`XLEN==64) begin:clint // 64-bit
always @(posedge HCLK) begin always @(posedge HCLK) begin
case(entry) case(entry)
@ -89,8 +84,8 @@ module clint (
if (entryd == 16'h4000) MTIMECMP <= HWDATA; if (entryd == 16'h4000) MTIMECMP <= HWDATA;
end end
// eventually replace MTIME logic below with timereg // eventually replace MTIME logic below with timereg
// timereg tr(HCLK, HRESETn, TIMECLK, memwrite & (entryd==16'hBFF8), 1'b0, HWDATA, MTIME, done); // timereg tr(HCLK, HRESETn, TIMECLK, memwrite & (entryd==16'hBFF8), 1'b0, HWDATA, MTIME, done);
always_ff @(posedge HCLK or negedge HRESETn) always_ff @(posedge HCLK or negedge HRESETn)
if (~HRESETn) begin if (~HRESETn) begin
@ -124,7 +119,7 @@ module clint (
end end
// eventually replace MTIME logic below with timereg // eventually replace MTIME logic below with timereg
// timereg tr(HCLK, HRESETn, TIMECLK, memwrite & (entryd==16'hBFF8), memwrite & (entryd == 16'hBFFC), HWDATA, MTIME, done); // timereg tr(HCLK, HRESETn, TIMECLK, memwrite & (entryd==16'hBFF8), memwrite & (entryd == 16'hBFFC), HWDATA, MTIME, done);
always_ff @(posedge HCLK or negedge HRESETn) always_ff @(posedge HCLK or negedge HRESETn)
if (~HRESETn) begin if (~HRESETn) begin
MTIME <= 0; MTIME <= 0;
@ -136,7 +131,6 @@ module clint (
MTIME[63:32]<= HWDATA; MTIME[63:32]<= HWDATA;
end else MTIME <= MTIME + 1; end else MTIME <= MTIME + 1;
end end
endgenerate
// Software interrupt when MSIP is set // Software interrupt when MSIP is set
assign SwIntM = MSIP; assign SwIntM = MSIP;
@ -234,13 +228,9 @@ module graytobinary #(parameter N = `XLEN) (
// B[N-1] = G[N-1]; B[i] = G[i] ^ B[i+1] for 0 <= i < N-1 // B[N-1] = G[N-1]; B[i] = G[i] ^ B[i+1] for 0 <= i < N-1
// requires rippling through N-1 XOR gates // requires rippling through N-1 XOR gates
generate
begin
genvar i; genvar i;
assign b[N-1] = g[N-1]; assign b[N-1] = g[N-1];
for (i=N-2; i >= 0; i--) begin:g2b for (i=N-2; i >= 0; i--) begin:g2b
assign b[i] = g[i] ^ b[i+1]; assign b[i] = g[i] ^ b[i+1];
end end
end
endgenerate
endmodule endmodule

View File

@ -61,23 +61,13 @@ module gpio (
// account for subword read/write circuitry // account for subword read/write circuitry
// -- Note GPIO registers are 32 bits no matter what; access them with LW SW. // -- 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") // (At least that's what I think when FE310 spec says "only naturally aligned 32-bit accesses are supported")
generate
if (`XLEN == 64) begin:gpio if (`XLEN == 64) begin:gpio
always_comb assign Din = entryd[2] ? HWDATA[63:32] : HWDATA[31:0];
if (entryd[2]) begin assign HREADGPIO = entryd[2] ? {Dout,32'b0} : {32'b0,Dout};
Din = HWDATA[63:32];
HREADGPIO = {Dout,32'b0};
end else begin
Din = HWDATA[31:0];
HREADGPIO = {32'b0,Dout};
end
end else begin:gpio // 32-bit end else begin:gpio // 32-bit
always_comb begin assign Din = HWDATA[31:0];
Din = HWDATA[31:0]; assign HREADGPIO = Dout;
HREADGPIO = Dout;
end end
end
endgenerate
// register access // register access
always_ff @(posedge HCLK, negedge HRESETn) begin always_ff @(posedge HCLK, negedge HRESETn) begin