mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Removed generate statements
This commit is contained in:
parent
98be8201b2
commit
d66f7c841b
@ -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
|
||||||
|
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
vsim -c <<!
|
vsim -c <<!
|
||||||
do wally-pipelined-batch.do rv64gc imperas64i
|
do wally-pipelined-batch.do rv32gc wally32priv
|
||||||
!
|
!
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
|
@ -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 */
|
|
@ -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 */
|
||||||
|
@ -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 */
|
|
@ -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
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -93,10 +93,8 @@ 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
|
||||||
@ -104,7 +102,6 @@ module SRAM2P1R1W
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
endgenerate
|
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
@ -110,5 +109,4 @@ module subwordread
|
|||||||
default: ReadDataM = ReadDataWordMuxM;
|
default: ReadDataM = ReadDataWordMuxM;
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
endgenerate
|
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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.
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
@ -60,7 +60,6 @@ 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;
|
||||||
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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
@ -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);
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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:
|
||||||
|
@ -70,7 +70,6 @@ module csri #(parameter
|
|||||||
// 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
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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)
|
||||||
@ -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
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user