forked from Github_Repos/cvw
Merge branch 'main' of https://github.com/davidharrishmc/riscv-wally into main
This commit is contained in:
commit
64b4981ca1
@ -153,7 +153,7 @@ fma2 UUT2(.XSgnM(XSgnE), .YSgnM(YSgnE), .XExpM(XExpE), .YExpM(YExpE), .ZExpM(ZEx
|
||||
.FmtM(FmtE), .FrmM(FrmE), .FMAFlgM, .FMAResM);
|
||||
|
||||
|
||||
// generate clock
|
||||
// produce clock
|
||||
always
|
||||
begin
|
||||
clk = 1; #5; clk = 0; #5;
|
||||
|
||||
@ -45,14 +45,12 @@ endmodule
|
||||
|
||||
|
||||
module INVX2(input logic a, output logic y);
|
||||
generate
|
||||
if (LIB == SKY130)
|
||||
sky130_osu_sc_12T_ms__inv_2 inv(a, y);
|
||||
else if (LIB == SKL90)
|
||||
scc9gena_inv_2 inv(a, y)
|
||||
else if (LIB == GF14)
|
||||
INV_X2N_A10P5PP84TSL_C14(a, y)
|
||||
endgenerate
|
||||
endmodule
|
||||
|
||||
module driver #(parameter WDITH=1) (
|
||||
|
||||
@ -3,11 +3,14 @@ make all:
|
||||
make -C ../../addins/riscv-arch-test
|
||||
make -C ../../addins/riscv-arch-test XLEN=32
|
||||
exe2memfile.pl ../../addins/riscv-arch-test/work/*/*/*.elf
|
||||
# extractFunctionRadix. ***
|
||||
|
||||
# Build wally-riscv-arch-test
|
||||
make -C ../../tests/wally-riscv-arch-test/
|
||||
make -C ../../tests/wally-riscv-arch-test/ XLEN=32
|
||||
exe2memfile.pl ../../tests/wally-riscv-arch-test/work/*/*/*.elf
|
||||
# ***extractFunctionRadix
|
||||
# *** use elf2hex
|
||||
|
||||
# *** add optional imperas tests
|
||||
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
vsim -c <<!
|
||||
do wally-pipelined-batch.do rv64gc imperas64i
|
||||
do wally-pipelined-batch.do rv32gc wally32priv
|
||||
!
|
||||
|
||||
22
pipelined/src/cache/cache.sv
vendored
22
pipelined/src/cache/cache.sv
vendored
@ -143,7 +143,6 @@ module cache #(parameter integer LINELEN,
|
||||
.WayHit, .VictimDirtyWay, .VictimTagWay,
|
||||
.InvalidateAll(InvalidateCacheM));
|
||||
|
||||
generate
|
||||
if(NUMWAYS > 1) begin:vict
|
||||
cachereplacementpolicy #(NUMWAYS, INDEXLEN, OFFSETLEN, NUMLINES)
|
||||
cachereplacementpolicy(.clk, .reset,
|
||||
@ -155,7 +154,6 @@ module cache #(parameter integer LINELEN,
|
||||
end else begin:vict
|
||||
assign VictimWay = 1'b1; // one hot.
|
||||
end
|
||||
endgenerate
|
||||
|
||||
assign CacheHit = | WayHit;
|
||||
assign VictimDirty = | VictimDirtyWay;
|
||||
@ -172,33 +170,23 @@ module cache #(parameter integer LINELEN,
|
||||
// easily build a variable input mux.
|
||||
// *** consider using a limited range shift to do this final muxing.
|
||||
genvar index;
|
||||
generate
|
||||
if(DCACHE == 1) begin
|
||||
if(DCACHE == 1) begin: readdata
|
||||
for (index = 0; index < WORDSPERLINE; index++) begin:readdatalinesetsmux
|
||||
assign ReadDataLineSets[index] = ReadDataLineM[((index+1)*`XLEN)-1: (index*`XLEN)];
|
||||
end
|
||||
// variable input mux
|
||||
assign ReadDataWord = ReadDataLineSets[LsuPAdrM[LOGWPL + LOGXLENBYTES - 1 : LOGXLENBYTES]];
|
||||
|
||||
end else begin
|
||||
end else begin: readdata
|
||||
logic [31:0] ReadLineSetsF [LINELEN/16-1:0];
|
||||
logic [31:0] FinalInstrRawF;
|
||||
for(index = 0; index < LINELEN / 16 - 1; index++) begin:readlinesetsmux
|
||||
for(index = 0; index < LINELEN / 16 - 1; index++)
|
||||
assign ReadLineSetsF[index] = ReadDataLineM[((index+1)*16)+16-1 : (index*16)];
|
||||
end
|
||||
assign ReadLineSetsF[LINELEN/16-1] = {16'b0, ReadDataLineM[LINELEN-1:LINELEN-16]};
|
||||
|
||||
assign FinalInstrRawF = ReadLineSetsF[LsuPAdrM[$clog2(LINELEN / 32) + 1 : 1]];
|
||||
if (`XLEN == 64) begin
|
||||
assign ReadDataWord = {32'b0, FinalInstrRawF};
|
||||
end else begin
|
||||
assign ReadDataWord = FinalInstrRawF;
|
||||
if (`XLEN == 64) assign ReadDataWord = {32'b0, FinalInstrRawF};
|
||||
else assign ReadDataWord = FinalInstrRawF;
|
||||
end
|
||||
|
||||
end
|
||||
endgenerate
|
||||
|
||||
|
||||
// Write Path CPU (IEU) side
|
||||
|
||||
onehotdecoder #(LOGWPL)
|
||||
|
||||
@ -72,7 +72,6 @@ module cachereplacementpolicy
|
||||
assign LineReplacementBits = ReplacementBits[RAdrD];
|
||||
|
||||
genvar index;
|
||||
generate
|
||||
if(NUMWAYS == 2) begin : TwoWay
|
||||
|
||||
assign LRUEn[0] = 1'b0;
|
||||
@ -173,8 +172,6 @@ module cachereplacementpolicy
|
||||
.decoded({VictimWay[0], VictimWay[1], VictimWay[2], VictimWay[3],
|
||||
VictimWay[4], VictimWay[5], VictimWay[6], VictimWay[7]}));
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
|
||||
13
pipelined/src/cache/cacheway.sv
vendored
13
pipelined/src/cache/cacheway.sv
vendored
@ -72,8 +72,6 @@ module cacheway #(parameter NUMLINES=512, parameter LINELEN = 256, TAGLEN = 26,
|
||||
|
||||
|
||||
genvar words;
|
||||
|
||||
generate
|
||||
for(words = 0; words < LINELEN/`XLEN; words++) begin: word
|
||||
sram1rw #(.DEPTH(`XLEN), .WIDTH(NUMLINES))
|
||||
CacheDataMem(.clk(clk), .Addr(RAdr),
|
||||
@ -81,7 +79,6 @@ module cacheway #(parameter NUMLINES=512, parameter LINELEN = 256, TAGLEN = 26,
|
||||
.WriteData(WriteData[(words+1)*`XLEN-1:words*`XLEN]),
|
||||
.WriteEnable(WriteEnable & WriteWordEnable[words]));
|
||||
end
|
||||
endgenerate
|
||||
|
||||
sram1rw #(.DEPTH(TAGLEN), .WIDTH(NUMLINES))
|
||||
CacheTagMem(.clk(clk),
|
||||
@ -123,27 +120,21 @@ module cacheway #(parameter NUMLINES=512, parameter LINELEN = 256, TAGLEN = 26,
|
||||
|
||||
assign Valid = ValidBits[RAdrD];
|
||||
|
||||
generate
|
||||
// Dirty bits
|
||||
if(DIRTY_BITS) begin:dirty
|
||||
always_ff @(posedge clk) begin
|
||||
if (reset)
|
||||
DirtyBits <= {NUMLINES{1'b0}};
|
||||
if (reset) DirtyBits <= {NUMLINES{1'b0}};
|
||||
else if (SetDirtyD & (WriteEnableD | VDWriteEnableD)) DirtyBits[RAdrD] <= 1'b1;
|
||||
else if (ClearDirtyD & (WriteEnableD | VDWriteEnableD)) DirtyBits[RAdrD] <= 1'b0;
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
SetDirtyD <= SetDirty;
|
||||
ClearDirtyD <= ClearDirty;
|
||||
end
|
||||
|
||||
assign Dirty = DirtyBits[RAdrD];
|
||||
|
||||
end else begin:dirty
|
||||
assign Dirty = 1'b0;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule // DCacheMemWay
|
||||
|
||||
|
||||
|
||||
7
pipelined/src/cache/dcache.sv
vendored
7
pipelined/src/cache/dcache.sv
vendored
@ -143,7 +143,6 @@ module dcache #(parameter integer LINELEN,
|
||||
.WayHit, .VictimDirtyWay, .VictimTagWay,
|
||||
.InvalidateAll(1'b0));
|
||||
|
||||
generate
|
||||
if(NUMWAYS > 1) begin:vict
|
||||
cachereplacementpolicy #(NUMWAYS, INDEXLEN, OFFSETLEN, NUMLINES)
|
||||
cachereplacementpolicy(.clk, .reset,
|
||||
@ -155,7 +154,6 @@ module dcache #(parameter integer LINELEN,
|
||||
end else begin:vict
|
||||
assign VictimWay = 1'b1; // one hot.
|
||||
end
|
||||
endgenerate
|
||||
|
||||
assign CacheHit = | WayHit;
|
||||
assign VictimDirty = | VictimDirtyWay;
|
||||
@ -172,11 +170,8 @@ module dcache #(parameter integer LINELEN,
|
||||
// easily build a variable input mux.
|
||||
// *** consider using a limited range shift to do this final muxing.
|
||||
genvar index;
|
||||
generate
|
||||
for (index = 0; index < WORDSPERLINE; index++) begin:readdatalinesetsmux
|
||||
for (index = 0; index < WORDSPERLINE; index++)
|
||||
assign ReadDataLineSetsM[index] = ReadDataLineM[((index+1)*`XLEN)-1: (index*`XLEN)];
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// variable input mux
|
||||
|
||||
|
||||
7
pipelined/src/cache/icache.sv
vendored
7
pipelined/src/cache/icache.sv
vendored
@ -114,7 +114,6 @@ module icache #(parameter integer LINELEN,
|
||||
.VictimDirtyWay(), .VictimTagWay(),
|
||||
.InvalidateAll(InvalidateICacheM));
|
||||
|
||||
generate
|
||||
if(NUMWAYS > 1) begin:vict
|
||||
cachereplacementpolicy #(NUMWAYS, INDEXLEN, OFFSETLEN, NUMLINES)
|
||||
cachereplacementpolicy(.clk, .reset,
|
||||
@ -126,7 +125,6 @@ module icache #(parameter integer LINELEN,
|
||||
end else begin:vict
|
||||
assign VictimWay = 1'b1; // one hot.
|
||||
end
|
||||
endgenerate
|
||||
|
||||
assign hit = | WayHit;
|
||||
|
||||
@ -136,12 +134,9 @@ module icache #(parameter integer LINELEN,
|
||||
or_rows #(NUMWAYS, LINELEN) ReadDataAOMux(.a(ReadDataLineWayMasked), .y(ReadLineF));
|
||||
|
||||
genvar index;
|
||||
generate
|
||||
for(index = 0; index < LINELEN / 16 - 1; index++) begin:readlinesetsmux
|
||||
for(index = 0; index < LINELEN / 16 - 1; index++)
|
||||
assign ReadLineSetsF[index] = ReadLineF[((index+1)*16)+16-1 : (index*16)];
|
||||
end
|
||||
assign ReadLineSetsF[LINELEN/16-1] = {16'b0, ReadLineF[LINELEN-1:LINELEN-16]};
|
||||
endgenerate
|
||||
|
||||
assign FinalInstrRawF = ReadLineSetsF[PCPF[$clog2(LINELEN / 32) + 1 : 1]];
|
||||
|
||||
|
||||
@ -56,7 +56,6 @@ module amoalu (
|
||||
endcase
|
||||
|
||||
// sign extend if necessary
|
||||
generate
|
||||
if (`XLEN == 32) begin:sext
|
||||
assign a = srca;
|
||||
assign b = srcb;
|
||||
@ -74,7 +73,5 @@ module amoalu (
|
||||
result = y;
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
@ -157,7 +157,7 @@ module cvtfp (
|
||||
// Result Selection
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
generate if(`IEEE754) begin
|
||||
if(`IEEE754) begin
|
||||
// select the double to single precision result
|
||||
assign DSRes = XNaNE ? {XSgnE, {8{1'b1}}, 1'b1, XManE[50:29]} :
|
||||
Underflow & ~Denorm ? {XSgnE, 30'b0, CalcPlus1&(|FrmE[1:0]|Shift)} :
|
||||
@ -178,8 +178,6 @@ module cvtfp (
|
||||
// select the final result based on the opperation
|
||||
assign CvtFpResE = FmtE ? {{32{1'b1}},DSRes} : {XSgnE&~XNaNE, SDExp, SDFrac[51]|XNaNE, SDFrac[50:0]&{51{~XNaNE}}};
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule // fpadd
|
||||
|
||||
|
||||
|
||||
@ -174,3 +174,20 @@ 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);
|
||||
|
||||
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;
|
||||
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
|
||||
assign carry = {carry_temp[WIDTH-1:1], 1'b0};
|
||||
*/
|
||||
endmodule // csa
|
||||
|
||||
@ -71,14 +71,13 @@ module fcmp (
|
||||
// - return 0 if comparison with NaN (unordered)
|
||||
|
||||
logic [`FLEN-1:0] QNaNX, QNaNY;
|
||||
generate if(`IEEE754) begin
|
||||
if(`IEEE754) begin
|
||||
assign QNaNX = FmtE ? {XSgnE, XExpE, 1'b1, XManE[`NF-2:0]} : {{32{1'b1}}, XSgnE, XExpE[7:0], 1'b1, XManE[50:29]};
|
||||
assign QNaNY = FmtE ? {YSgnE, YExpE, 1'b1, YManE[`NF-2:0]} : {{32{1'b1}}, YSgnE, YExpE[7:0], 1'b1, YManE[50:29]};
|
||||
end else begin
|
||||
assign QNaNX = FmtE ? {1'b0, XExpE, 1'b1, 51'b0} : {{32{1'b1}}, 1'b0, XExpE[7:0], 1'b1, 22'b0};
|
||||
assign QNaNY = FmtE ? {1'b0, YExpE, 1'b1, 51'b0} : {{32{1'b1}}, 1'b0, YExpE[7:0], 1'b1, 22'b0};
|
||||
end
|
||||
endgenerate
|
||||
|
||||
always_comb begin
|
||||
case (FOpCtrlE[2:0])
|
||||
|
||||
@ -173,7 +173,7 @@ module fcvt (
|
||||
// - only set invalid flag for out-of-range vales
|
||||
// - set inexact if in representable range and not exact
|
||||
|
||||
generate if(`IEEE754) begin // checks before rounding
|
||||
if(`IEEE754) begin // checks before rounding
|
||||
assign Invalid = (Of | Uf)&FOpCtrlE[0];
|
||||
assign Inexact = (Guard|Round|Sticky)&~(&FOpCtrlE[1:0]&(XSgnE|Of))&~((Of|Uf)&~FOpCtrlE[1]&FOpCtrlE[0]);
|
||||
assign CvtFlgE = {Invalid&~Inexact, 3'b0, Inexact};
|
||||
@ -182,10 +182,6 @@ module fcvt (
|
||||
assign Inexact = (Guard|Round|Sticky)&~(&FOpCtrlE[1:0]&((XSgnE&~(ShiftCnt[12]&~Plus1))|Of))&~((Of|Uf)&~FOpCtrlE[1]&FOpCtrlE[0]);
|
||||
assign CvtFlgE = {Invalid&~Inexact, 3'b0, Inexact};
|
||||
end
|
||||
endgenerate
|
||||
|
||||
|
||||
|
||||
endmodule // fpadd
|
||||
|
||||
|
||||
|
||||
@ -814,20 +814,17 @@ module resultselect(
|
||||
);
|
||||
logic [`FLEN-1:0] XNaNResult, YNaNResult, ZNaNResult, InvalidResult, OverflowResult, KillProdResult, UnderflowResult; // possible results
|
||||
|
||||
generate
|
||||
if(`IEEE754) begin:nan
|
||||
if(`IEEE754) begin
|
||||
assign XNaNResult = FmtM ? {XSgnM, XExpM, 1'b1, XManM[`NF-2:0]} : {{32{1'b1}}, XSgnM, XExpM[7:0], 1'b1, XManM[50:29]};
|
||||
assign YNaNResult = FmtM ? {YSgnM, YExpM, 1'b1, YManM[`NF-2:0]} : {{32{1'b1}}, YSgnM, YExpM[7:0], 1'b1, YManM[50:29]};
|
||||
assign ZNaNResult = FmtM ? {ZSgnEffM, ZExpM, 1'b1, ZManM[`NF-2:0]} : {{32{1'b1}}, ZSgnEffM, ZExpM[7:0], 1'b1, ZManM[50:29]};
|
||||
assign InvalidResult = FmtM ? {ResultSgn, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}} : {{32{1'b1}}, ResultSgn, 8'hff, 1'b1, 22'b0};
|
||||
end else begin:nan
|
||||
end else begin
|
||||
assign XNaNResult = FmtM ? {1'b0, XExpM, 1'b1, 51'b0} : {{32{1'b1}}, 1'b0, XExpM[7:0], 1'b1, 22'b0};
|
||||
assign YNaNResult = FmtM ? {1'b0, YExpM, 1'b1, 51'b0} : {{32{1'b1}}, 1'b0, YExpM[7:0], 1'b1, 22'b0};
|
||||
assign ZNaNResult = FmtM ? {1'b0, ZExpM, 1'b1, 51'b0} : {{32{1'b1}}, 1'b0, ZExpM[7:0], 1'b1, 22'b0};
|
||||
assign InvalidResult = FmtM ? {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}} : {{32{1'b1}}, 1'b0, 8'hff, 1'b1, 22'b0};
|
||||
end
|
||||
endgenerate
|
||||
|
||||
|
||||
assign OverflowResult = FmtM ? ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {ResultSgn, {`NE-1{1'b1}}, 1'b0, {`NF{1'b1}}} :
|
||||
{ResultSgn, {`NE{1'b1}}, {`NF{1'b0}}} :
|
||||
|
||||
@ -37,9 +37,6 @@ module redundantmul #(parameter WIDTH =8)(
|
||||
input logic [WIDTH-1:0] a,b,
|
||||
output logic [2*WIDTH-1:0] out0, out1);
|
||||
|
||||
//
|
||||
|
||||
generate
|
||||
if (`DESIGN_COMPILER == 1) begin:mul
|
||||
logic [2*WIDTH-1+2:0] tmp_out0;
|
||||
logic [2*WIDTH-1+2:0] tmp_out1;
|
||||
@ -51,8 +48,6 @@ module redundantmul #(parameter WIDTH =8)(
|
||||
assign out0 = a * b;
|
||||
assign out1 = 0;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
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],
|
||||
output logic [COLS-1:0] y);
|
||||
|
||||
logic [COLS-1:0] mid[ROWS-1:1];
|
||||
genvar row, col;
|
||||
generate
|
||||
genvar row;
|
||||
if(ROWS == 1)
|
||||
assign y = a[0];
|
||||
else begin
|
||||
logic [COLS-1:0] mid[ROWS-1:1];
|
||||
assign mid[1] = a[0] | a[1];
|
||||
for (row=2; row < ROWS; row++)
|
||||
assign mid[row] = mid[row-1] | a[row];
|
||||
assign y = mid[ROWS-1];
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
||||
|
||||
/* 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
|
||||
|
||||
// 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;
|
||||
else assign Result = FullResult;
|
||||
endgenerate
|
||||
endmodule
|
||||
|
||||
|
||||
@ -109,7 +109,6 @@ module controller(
|
||||
assign Rs1D = InstrD[19:15];
|
||||
|
||||
// Main Instruction Decoder
|
||||
generate
|
||||
always_comb
|
||||
case(OpD)
|
||||
// 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
|
||||
default: ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_1; // non-implemented instruction
|
||||
endcase
|
||||
endgenerate
|
||||
|
||||
// unswizzle control bits
|
||||
// squash control signals if coming from an illegal compressed instruction
|
||||
@ -181,7 +179,6 @@ module controller(
|
||||
// Fences
|
||||
// Ordinary fence is presently a nop
|
||||
// FENCE.I flushes the D$ and invalidates the I$ if Zifencei is supported and I$ is implemented
|
||||
generate
|
||||
if (`ZIFENCEI_SUPPORTED & `MEM_ICACHE) begin:fencei
|
||||
logic FenceID;
|
||||
assign FenceID = FenceD & (Funct3D == 3'b001); // is it a FENCE.I instruction?
|
||||
@ -191,7 +188,6 @@ module controller(
|
||||
assign InvalidateICacheD = 0;
|
||||
assign FlushDCacheD = 0;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// Decocde stage pipeline control register
|
||||
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);
|
||||
|
||||
// floating point interactions: fcvt, fp stores
|
||||
generate
|
||||
if (`F_SUPPORTED) begin:fpmux
|
||||
mux2 #(`XLEN) resultmuxM(IEUResultM, FIntResM, FWriteIntM, ResultM);
|
||||
mux2 #(`XLEN) writedatamux(ForwardedSrcBE, FWriteDataE, ~IllegalFPUInstrE, WriteDataE);
|
||||
@ -132,11 +131,8 @@ module datapath (
|
||||
assign ResultM = IEUResultM;
|
||||
assign WriteDataE = ForwardedSrcBE;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// handle Store Conditional result if atomic extension supported
|
||||
generate
|
||||
if (`A_SUPPORTED) assign SCResultW = {{(`XLEN-1){1'b0}}, SquashSCW};
|
||||
else assign SCResultW = 0;
|
||||
endgenerate
|
||||
endmodule
|
||||
|
||||
@ -32,7 +32,6 @@ module extend (
|
||||
|
||||
localparam [`XLEN-1:0] undefined = {(`XLEN){1'bx}}; // could change to 0 after debug
|
||||
|
||||
// generate
|
||||
always_comb
|
||||
case(ImmSrcD)
|
||||
// I-type
|
||||
@ -48,7 +47,9 @@ module extend (
|
||||
// Store Conditional: zero offset
|
||||
3'b101: if (`A_SUPPORTED) ExtImmD = 0;
|
||||
else ExtImmD = undefined;
|
||||
default: ExtImmD = undefined; // undefined
|
||||
default: begin
|
||||
ExtImmD = undefined; // undefined
|
||||
$error("Invalid ImmSrcD in extend");
|
||||
end
|
||||
endcase
|
||||
// endgenerate
|
||||
endmodule
|
||||
|
||||
@ -39,7 +39,6 @@ module shifter (
|
||||
// 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)
|
||||
generate
|
||||
if (`XLEN==32) begin:shifter // RV32
|
||||
always_comb // funnel mux
|
||||
if (Right)
|
||||
@ -62,7 +61,6 @@ module shifter (
|
||||
end
|
||||
assign amttrunc = W64 ? {1'b0, Amt[4:0]} : Amt; // 32 or 64-bit shift
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// opposite offset for right shfits
|
||||
assign offset = Right ? amttrunc : ~amttrunc;
|
||||
|
||||
@ -93,10 +93,8 @@ module SRAM2P1R1W
|
||||
// read port
|
||||
assign RD1 = mem[RA1Q];
|
||||
|
||||
genvar index;
|
||||
|
||||
// write port
|
||||
generate
|
||||
genvar index;
|
||||
for (index = 0; index < WIDTH; index = index + 1) begin:bitwrite
|
||||
always_ff @(posedge clk) begin
|
||||
if (WEN1Q & BitWEN1[index]) begin
|
||||
@ -104,7 +102,6 @@ module SRAM2P1R1W
|
||||
end
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
@ -70,7 +70,6 @@ module bpred
|
||||
|
||||
// Part 1 branch direction prediction
|
||||
|
||||
generate
|
||||
if (`BPTYPE == "BPTWOBIT") begin:Predictor
|
||||
twoBitPredictor DirPredictor(.clk(clk),
|
||||
.reset(reset),
|
||||
@ -137,7 +136,6 @@ module bpred
|
||||
.PCSrcE(PCSrcE),
|
||||
.UpdatePrediction(UpdateBPPredE));
|
||||
end
|
||||
endgenerate
|
||||
|
||||
|
||||
// this predictor will have two pieces of data,
|
||||
|
||||
@ -38,7 +38,6 @@ module decompress (
|
||||
logic [1:0] op;
|
||||
|
||||
// if the system handles compressed instructions, decode appropriately
|
||||
generate
|
||||
if (!(`C_SUPPORTED)) begin:decompress // no compressed mode
|
||||
assign InstrD = InstrRawD;
|
||||
assign IllegalCompInstrD = 0;
|
||||
@ -173,6 +172,5 @@ module decompress (
|
||||
endcase
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
||||
|
||||
|
||||
@ -111,7 +111,6 @@ module ifu (
|
||||
logic [31:0] PostSpillInstrRawF;
|
||||
|
||||
|
||||
generate
|
||||
if(`C_SUPPORTED) begin : SpillSupport
|
||||
logic [`XLEN-1:0] PCFp2;
|
||||
logic Spill;
|
||||
@ -166,7 +165,6 @@ module ifu (
|
||||
assign SelNextSpill = 0;
|
||||
assign PostSpillInstrRawF = InstrRawF;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
|
||||
assign PCFExt = {2'b00, PCFMux};
|
||||
@ -235,10 +233,6 @@ module ifu (
|
||||
logic [`PA_BITS-1:0] ICacheBusAdr;
|
||||
logic SelUncachedAdr;
|
||||
|
||||
|
||||
|
||||
|
||||
generate
|
||||
if(`MEM_ICACHE) begin : icache
|
||||
logic [1:0] IfuRWF;
|
||||
assign IfuRWF = CacheableF ? 2'b10 : 2'b00;
|
||||
@ -280,17 +274,13 @@ module ifu (
|
||||
.InvalidateCacheM(InvalidateICacheM));
|
||||
|
||||
assign FinalInstrRawF = FinalInstrRawF_FIXME[31:0];
|
||||
|
||||
|
||||
|
||||
end else begin : passthrough
|
||||
end else begin
|
||||
assign ICacheFetchLine = 0;
|
||||
assign ICacheBusAdr = 0;
|
||||
//assign CompressedF = 0; //?
|
||||
assign ICacheStallF = 0;
|
||||
assign FinalInstrRawF = 0;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// select between dcache and direct from the BUS. Always selected if no dcache.
|
||||
// handled in the busfsm.
|
||||
@ -301,14 +291,12 @@ module ifu (
|
||||
|
||||
// always present
|
||||
genvar index;
|
||||
generate
|
||||
for (index = 0; index < WORDSPERLINE; index++) begin:fetchbuffer
|
||||
flopen #(`XLEN) fb(.clk(clk),
|
||||
.en(IfuBusAck & IfuBusRead & (index == WordCount)),
|
||||
.d(IfuBusHRDATA),
|
||||
.q(ICacheMemWriteData[(index+1)*`XLEN-1:index*`XLEN]));
|
||||
end
|
||||
endgenerate
|
||||
|
||||
assign LocalIfuBusAdr = SelUncachedAdr ? PCPF : ICacheBusAdr;
|
||||
assign IfuBusAdr = ({{`PA_BITS-LOGWPL{1'b0}}, WordCount} << $clog2(`XLEN/8)) + LocalIfuBusAdr;
|
||||
@ -382,7 +370,6 @@ module ifu (
|
||||
flopenl #(`XLEN) pcreg(clk, reset, ~StallF & ~ICacheStallF, PCNextF, `RESET_VECTOR, PCF);
|
||||
|
||||
// branch and jump predictor
|
||||
generate
|
||||
if (`BPRED_ENABLED == 1) begin : bpred
|
||||
bpred bpred(.clk, .reset,
|
||||
.StallF, .StallD, .StallE,
|
||||
@ -400,7 +387,6 @@ module ifu (
|
||||
assign RASPredPCWrongE = 1'b0;
|
||||
assign BPPredClassNonCFIWrongE = 1'b0;
|
||||
end
|
||||
endgenerate
|
||||
// The true correct target is IEUAdrE if PCSrcE is 1 else it is the fall through PCLinkE.
|
||||
assign PCCorrectE = PCSrcE ? IEUAdrE : PCLinkE;
|
||||
|
||||
|
||||
@ -66,16 +66,10 @@ module localHistoryPredictor
|
||||
// .BitWEN1(2'b11));
|
||||
|
||||
genvar index;
|
||||
generate
|
||||
for (index = 0; index < 2**m; index = index +1) begin:localhist
|
||||
|
||||
flopenr #(k) LocalHistoryRegister(.clk(clk),
|
||||
.reset(reset),
|
||||
.en(UpdateEN & (index == UpdatePCIndex)),
|
||||
.d(LHRFNext),
|
||||
.q(LHRNextF[index]));
|
||||
flopenr #(k) LocalHistoryRegister(.clk, .reset, .en(UpdateEN & (index == UpdatePCIndex)),
|
||||
.d(LHRFNext), .q(LHRNextF[index]));
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// need to forward when updating to the same address as reading.
|
||||
// first we compare to see if the update and lookup addreses are the same
|
||||
|
||||
@ -120,7 +120,6 @@ module lsu
|
||||
flopenrc #(`XLEN) AddressMReg(clk, reset, FlushM, ~StallM, IEUAdrE, IEUAdrM);
|
||||
assign IEUAdrExtM = {2'b00, IEUAdrM};
|
||||
|
||||
generate
|
||||
if(`MEM_VIRTMEM) begin : MEM_VIRTMEM
|
||||
logic AnyCPUReqM;
|
||||
logic [`PA_BITS-1:0] HPTWAdr;
|
||||
@ -188,7 +187,6 @@ module lsu
|
||||
assign DTLBLoadPageFaultM = 1'b0;
|
||||
assign DTLBStorePageFaultM = 1'b0;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// **** look into this confusing signal.
|
||||
// This signal is confusing. CommittedM tells the CPU's trap unit the current instruction
|
||||
@ -200,7 +198,6 @@ module lsu
|
||||
// to flush the memory operation at that time.
|
||||
assign CommittedM = SelHPTW | DCacheCommittedM | BusCommittedM;
|
||||
|
||||
generate
|
||||
if(`ZICSR_SUPPORTED == 1) begin : dmmu
|
||||
logic DataMisalignedM;
|
||||
|
||||
@ -249,14 +246,10 @@ module lsu
|
||||
assign LoadMisalignedFaultM = 0;
|
||||
assign StoreMisalignedFaultM = 0;
|
||||
end
|
||||
endgenerate
|
||||
assign LSUStall = DCacheStall | InterlockStall | BusStall;
|
||||
|
||||
|
||||
|
||||
// Move generate from lrsc to outside this module.
|
||||
// use PreLsu as prefix for lrsc
|
||||
generate
|
||||
if (`A_SUPPORTED) begin:lrsc
|
||||
assign MemReadM = PreLsuRWM[1] & ~(IgnoreRequest) & ~DTLBMissM;
|
||||
lrsc lrsc(.clk, .reset, .FlushW, .CPUBusy, .MemReadM, .PreLsuRWM, .LsuAtomicM, .LsuPAdrM,
|
||||
@ -265,7 +258,6 @@ module lsu
|
||||
assign SquashSCW = 0;
|
||||
assign LsuRWM = PreLsuRWM;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
|
||||
// conditional
|
||||
@ -304,7 +296,6 @@ module lsu
|
||||
|
||||
logic SelUncachedAdr;
|
||||
|
||||
generate
|
||||
if(`MEM_DCACHE) begin : dcache
|
||||
cache #(.LINELEN(`DCACHE_LINELENINBITS), .NUMLINES(`DCACHE_WAYSIZEINBYTES*8/LINELEN),
|
||||
.NUMWAYS(`DCACHE_NUMWAYS), .DCACHE(1))
|
||||
@ -327,7 +318,6 @@ module lsu
|
||||
assign DCacheBusAdr = 0;
|
||||
assign ReadDataLineSetsM[0] = 0;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
|
||||
// select between dcache and direct from the BUS. Always selected if no dcache.
|
||||
@ -343,7 +333,6 @@ module lsu
|
||||
.Funct3M(LsuFunct3M),
|
||||
.ReadDataM);
|
||||
|
||||
generate
|
||||
if (`A_SUPPORTED) begin : amo
|
||||
logic [`XLEN-1:0] AMOResult;
|
||||
amoalu amoalu(.srca(ReadDataM), .srcb(WriteDataM), .funct(Funct7M), .width(LsuFunct3M[1:0]),
|
||||
@ -351,7 +340,6 @@ module lsu
|
||||
mux2 #(`XLEN) wdmux(WriteDataM, AMOResult, LsuAtomicM[1], FinalAMOWriteDataM);
|
||||
end else
|
||||
assign FinalAMOWriteDataM = WriteDataM;
|
||||
endgenerate
|
||||
|
||||
// this might only get instantiated if there is a dcache or dtim.
|
||||
// There is a copy in the ebu.
|
||||
@ -368,24 +356,20 @@ module lsu
|
||||
logic [LOGWPL-1:0] WordCount;
|
||||
|
||||
genvar index;
|
||||
generate
|
||||
for (index = 0; index < WORDSPERLINE; index++) begin:fetchbuffer
|
||||
flopen #(`XLEN) fb(.clk(clk),
|
||||
flopen #(`XLEN) fb(.clk,
|
||||
.en(LsuBusAck & LsuBusRead & (index == WordCount)),
|
||||
.d(LsuBusHRDATA),
|
||||
.q(DCacheMemWriteData[(index+1)*`XLEN-1:index*`XLEN]));
|
||||
end
|
||||
endgenerate
|
||||
|
||||
assign LocalLsuBusAdr = SelUncachedAdr ? LsuPAdrM : DCacheBusAdr ;
|
||||
assign LsuBusAdr = ({{`PA_BITS-LOGWPL{1'b0}}, WordCount} << $clog2(`XLEN/8)) + LocalLsuBusAdr;
|
||||
assign PreLsuBusHWDATA = ReadDataLineSetsM[WordCount];
|
||||
assign LsuBusHWDATA = SelUncachedAdr ? WriteDataM : PreLsuBusHWDATA; // *** why is this not FinalWriteDataM? which does not work.
|
||||
|
||||
generate
|
||||
if (`XLEN == 32) assign LsuBusSize = SelUncachedAdr ? LsuFunct3M : 3'b010;
|
||||
else assign LsuBusSize = SelUncachedAdr ? LsuFunct3M : 3'b011;
|
||||
endgenerate;
|
||||
|
||||
busfsm #(WordCountThreshold, LOGWPL, `MEM_DCACHE)
|
||||
busfsm(.clk, .reset, .IgnoreRequest, .LsuRWM, .DCacheFetchLine, .DCacheWriteLine,
|
||||
|
||||
@ -38,7 +38,6 @@ module subwordread
|
||||
// Funct3M[2] is the unsigned bit. mask upper bits.
|
||||
// Funct3M[1:0] is the size of the memory access.
|
||||
|
||||
generate
|
||||
if (`XLEN == 64) begin:swrmux
|
||||
// ByteMe mux
|
||||
always_comb
|
||||
@ -110,5 +109,4 @@ module subwordread
|
||||
default: ReadDataM = ReadDataWordMuxM;
|
||||
endcase
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
||||
|
||||
@ -52,7 +52,7 @@ module hptw
|
||||
L1_ADR, L1_RD,
|
||||
L2_ADR, L2_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 [`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
|
||||
generate
|
||||
if (`MEM_VIRTMEM) begin:tlb
|
||||
logic ReadAccess, WriteAccess;
|
||||
assign ReadAccess = ExecuteAccessF | ReadAccessM; // execute also acts as a TLB read. Execute and Read are never active for the same MMU, so safe to mix pipestages
|
||||
@ -110,7 +109,6 @@ module mmu #(parameter TLB_ENTRIES = 8, // number of TLB Entries
|
||||
assign TLBHit = 1; // *** is this necessary
|
||||
assign TLBPageFault = 0;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// If translation is occuring, select translated physical address from TLB
|
||||
mux2 #(`PA_BITS) addressmux(PAdr, TLBPAdr, Translate, PhysicalAddress);
|
||||
|
||||
@ -68,7 +68,7 @@ module pmpadrdec (
|
||||
|
||||
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];
|
||||
// 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.
|
||||
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
|
||||
);
|
||||
|
||||
generate
|
||||
if (`PMP_ENTRIES > 0) begin: pmpchecker
|
||||
// Bit i is high when the address falls in PMP region i
|
||||
logic EnforcePMP;
|
||||
@ -78,6 +77,4 @@ module pmpchecker (
|
||||
assign PMPLoadAccessFaultM = 0;
|
||||
assign PMPStoreAccessFaultM = 0;
|
||||
end
|
||||
endgenerate
|
||||
//assign PMPSquashBusAccess = PMPInstrAccessFaultF | PMPLoadAccessFaultM | PMPStoreAccessFaultM;
|
||||
endmodule
|
||||
|
||||
@ -34,25 +34,9 @@ module priorityonehot #(parameter ENTRIES = 8) (
|
||||
input logic [ENTRIES-1:0] a,
|
||||
output logic [ENTRIES-1:0] y
|
||||
);
|
||||
|
||||
/* verilator lint_off UNOPTFLAT */
|
||||
|
||||
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));
|
||||
// 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;
|
||||
|
||||
/* verilator lint_on UNOPTFLAT */
|
||||
|
||||
endmodule
|
||||
|
||||
@ -37,20 +37,15 @@ module prioritythermometer #(parameter N = 8) (
|
||||
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.
|
||||
|
||||
// generate thermometer code mask
|
||||
// create thermometer code mask
|
||||
genvar i;
|
||||
generate
|
||||
assign y[0] = a[0];
|
||||
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
|
||||
endgenerate
|
||||
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
|
||||
@ -60,7 +60,6 @@ module tlbcamline #(parameter KEY_BITS = 20,
|
||||
|
||||
assign MatchASID = (SATP_ASID == Key_ASID) | PTE_G;
|
||||
|
||||
generate
|
||||
if (`XLEN == 32) begin: match
|
||||
|
||||
assign {Key_ASID, Key1, Key0} = Key;
|
||||
@ -91,7 +90,6 @@ module tlbcamline #(parameter KEY_BITS = 20,
|
||||
|
||||
assign Match = Match0 & Match1 & Match2 & Match3 & MatchASID & Valid;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// On a write, update the type of the page referred to by this line.
|
||||
flopenr #(2) pagetypeflop(clk, reset, WriteEnable, PageTypeWriteVal, PageType);
|
||||
|
||||
@ -60,14 +60,14 @@ module tlbcontrol #(parameter ITLB = 0) (
|
||||
logic UpperBitsUnequalPageFault;
|
||||
logic DAPageFault;
|
||||
logic TLBAccess;
|
||||
logic ImproperPrivilege;
|
||||
|
||||
// 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 Translate = (SATP_MODE != `NO_TRANSLATE) & (EffectivePrivilegeMode != `M_MODE) & ~DisableTranslation;
|
||||
generate
|
||||
if (`XLEN==64) begin:rv64
|
||||
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;
|
||||
assign UpperEqual39 = &(VAdr[63:38]) | ~|(VAdr[63:38]);
|
||||
assign UpperEqual48 = &(VAdr[63:47]) | ~|(VAdr[63:47]);
|
||||
@ -76,23 +76,18 @@ module tlbcontrol #(parameter ITLB = 0) (
|
||||
assign SV39Mode = 0;
|
||||
assign UpperBitsUnequalPageFault = 0;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// Determine whether TLB is being used
|
||||
assign TLBAccess = ReadAccess | WriteAccess;
|
||||
|
||||
// Check whether upper bits of virtual addresss are all equal
|
||||
|
||||
|
||||
// unswizzle useful PTE bits
|
||||
assign {PTE_D, PTE_A} = PTEAccessBits[7:6];
|
||||
assign {PTE_U, PTE_X, PTE_W, PTE_R, PTE_V} = PTEAccessBits[4:0];
|
||||
|
||||
// Check whether the access is allowed, page faulting if not.
|
||||
generate
|
||||
if (ITLB == 1) begin:itlb // Instruction TLB fault checking
|
||||
logic ImproperPrivilege;
|
||||
|
||||
// User mode may only execute user mode pages, and supervisor mode may
|
||||
// only execute non-user mode pages.
|
||||
assign ImproperPrivilege = ((EffectivePrivilegeMode == `U_MODE) & ~PTE_U) |
|
||||
@ -101,7 +96,7 @@ module tlbcontrol #(parameter ITLB = 0) (
|
||||
assign DAPageFault = ~PTE_A;
|
||||
assign TLBPageFault = (Translate & TLBHit & (ImproperPrivilege | ~PTE_X | DAPageFault | UpperBitsUnequalPageFault | Misaligned | ~PTE_V));
|
||||
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
|
||||
// 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 TLBPageFault = (Translate & TLBHit & (ImproperPrivilege | InvalidRead | InvalidWrite | DAPageFault | UpperBitsUnequalPageFault | Misaligned | ~PTE_V));
|
||||
end
|
||||
endgenerate
|
||||
|
||||
assign TLBHit = CAMHit & TLBAccess;
|
||||
assign TLBMiss = (~CAMHit | TLBFlush) & Translate & TLBAccess;
|
||||
|
||||
@ -43,7 +43,6 @@ module tlbmixer (
|
||||
logic [`PPN_BITS-1:0] PPNMixed;
|
||||
|
||||
// produce PageNumberMask with 1s where virtual page number bits should be untranslaetd for superpages
|
||||
generate
|
||||
if (`XLEN == 32)
|
||||
// kilopage: 22 bits of PPN, 0 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
|
||||
// terapage: 17 bits of PPN, 27 bits of VPN
|
||||
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.
|
||||
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;
|
||||
|
||||
// Handle sign extension for W-type instructions
|
||||
generate
|
||||
if (`XLEN == 64) begin:rv64 // RV64 has W-type instructions
|
||||
mux2 #(`XLEN) xinmux(ForwardedSrcAE, {ForwardedSrcAE[31:0], 32'b0}, W64E, XinE);
|
||||
mux2 #(`XLEN) dinmux(ForwardedSrcBE, {{32{ForwardedSrcBE[31]&DivSignedE}}, ForwardedSrcBE[31:0]}, W64E, DinE);
|
||||
@ -68,7 +67,6 @@ module intdivrestoring (
|
||||
assign XinE = ForwardedSrcAE;
|
||||
assign DinE = ForwardedSrcBE;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// Extract sign bits and check fo division by zero
|
||||
assign SignDE = DivSignedE & DinE[`XLEN-1];
|
||||
@ -97,11 +95,9 @@ module intdivrestoring (
|
||||
flopen #(3) Div0eMReg(clk, DivStartE, {Div0E, NegQE, SignXE}, {Div0M, NegQM, NegWM});
|
||||
|
||||
// one copy of divstep for each bit produced per cycle
|
||||
generate
|
||||
genvar i;
|
||||
for (i=0; i<`DIV_BITSPERCYCLE; i = 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
|
||||
neg #(`XLEN) qneg(XQM[0], XQnM);
|
||||
|
||||
@ -49,8 +49,8 @@ module mul (
|
||||
// Signed * 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] PP0M, PP1M, PP2M, PP3M, PP4M;
|
||||
logic [`XLEN*2-1:0] PP1E, PP2E, PP3E, PP4E;
|
||||
logic [`XLEN*2-1:0] PP1M, PP2M, PP3M, PP4M;
|
||||
logic [`XLEN-2:0] PA, PB;
|
||||
logic PP;
|
||||
logic MULH, MULHSU;
|
||||
@ -62,7 +62,7 @@ module mul (
|
||||
|
||||
assign Aprime = {1'b0, ForwardedSrcAE[`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 PB = {(`XLEN-1){ForwardedSrcBE[`XLEN-1]}} & ForwardedSrcAE[`XLEN-2:0];
|
||||
assign PP = ForwardedSrcAE[`XLEN-1] & ForwardedSrcBE[`XLEN-1];
|
||||
@ -83,12 +83,11 @@ module mul (
|
||||
// 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) PP2Reg(clk, reset, FlushM, ~StallM, PP2E, PP2M);
|
||||
flopenrc #(`XLEN*2) PP3Reg(clk, reset, FlushM, ~StallM, PP3E, PP3M);
|
||||
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
|
||||
|
||||
|
||||
@ -74,13 +74,11 @@ module muldiv (
|
||||
|
||||
// Handle sign extension for W-type instructions
|
||||
flopenrc #(1) W64MReg(clk, reset, FlushM, ~StallM, W64E, W64M);
|
||||
generate
|
||||
if (`XLEN == 64) begin:resmux // RV64 has W-type instructions
|
||||
assign MulDivResultM = W64M ? {{32{PrelimResultM[31]}}, PrelimResultM[31:0]} : PrelimResultM;
|
||||
end else begin:resmux // RV32 has no W-type instructions
|
||||
assign MulDivResultM = PrelimResultM;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// Writeback stage pipeline register
|
||||
flopenrc #(`XLEN) MulDivResultWReg(clk, reset, FlushW, ~StallW, MulDivResultM, MulDivResultW);
|
||||
|
||||
@ -56,7 +56,6 @@ module csrc #(parameter
|
||||
output logic IllegalCSRCAccessM
|
||||
);
|
||||
|
||||
generate
|
||||
if (`ZICOUNTERS_SUPPORTED) begin:counters
|
||||
(* mark_debug = "true" *) logic [63:0] CYCLE_REGW, INSTRET_REGW;
|
||||
logic [63:0] CYCLEPlusM, INSTRETPlusM;
|
||||
@ -82,9 +81,9 @@ module csrc #(parameter
|
||||
assign CounterEvent[0] = 1'b1; // MCYCLE always increments
|
||||
assign CounterEvent[1] = 1'b0; // Counter 0 doesn't exist
|
||||
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;
|
||||
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[4] = BPPredDirWrongM & InstrValidNotFlushedM;
|
||||
assign CounterEvent[5] = InstrClassM[0] & InstrValidNotFlushedM;
|
||||
@ -99,7 +98,7 @@ module csrc #(parameter
|
||||
end
|
||||
|
||||
// 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 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
|
||||
@ -160,7 +159,6 @@ module csrc #(parameter
|
||||
assign CSRCReadValM = 0;
|
||||
assign IllegalCSRCAccessM = 1; // counters aren't enabled
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
||||
|
||||
// To Do:
|
||||
|
||||
@ -70,7 +70,6 @@ module csri #(parameter
|
||||
// MEIP, MTIP, MSIP are read-only
|
||||
// SEIP, STIP, SSIP is writable in MIP if S mode exists
|
||||
// SSIP is writable in SIP if S mode exists
|
||||
generate
|
||||
if (`S_SUPPORTED) begin:mask
|
||||
assign MIP_WRITE_MASK = 12'h222; // SEIP, STIP, SSIP are writable in MIP (20210108-draft 3.1.9)
|
||||
assign SIP_WRITE_MASK = 12'h002; // SSIP is writable in SIP (privileged 20210108-draft 4.1.3)
|
||||
@ -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 (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
|
||||
endgenerate
|
||||
|
||||
// restricted views of registers
|
||||
generate
|
||||
always_comb begin:regs
|
||||
// Add MEIP read-only signal
|
||||
IP_REGW = {IntInM[11],1'b0,IP_REGW_writeable};
|
||||
@ -119,5 +116,4 @@ module csri #(parameter
|
||||
UIE_REGW = 12'b0;
|
||||
end */
|
||||
end
|
||||
endgenerate
|
||||
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
|
||||
genvar i;
|
||||
generate
|
||||
if (`PMP_ENTRIES > 0) begin:pmp
|
||||
logic [`PMP_ENTRIES-1:0] WritePMPCFGM;
|
||||
logic [`PMP_ENTRIES-1:0] WritePMPADDRM ;
|
||||
@ -117,7 +116,6 @@ module csrm #(parameter
|
||||
end
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
localparam MISA_26 = (`MISA) & 32'h03ffffff;
|
||||
|
||||
@ -143,7 +141,6 @@ module csrm #(parameter
|
||||
|
||||
// CSRs
|
||||
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
|
||||
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);
|
||||
@ -151,20 +148,17 @@ module csrm #(parameter
|
||||
assign MEDELEG_REGW = 0;
|
||||
assign MIDELEG_REGW = 0;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
flopenr #(`XLEN) MSCRATCHreg(clk, reset, WriteMSCRATCHM, CSRWriteValM, MSCRATCH_REGW);
|
||||
flopenr #(`XLEN) MEPCreg(clk, reset, WriteMEPCM, NextEPCM, MEPC_REGW);
|
||||
flopenr #(`XLEN) MCAUSEreg(clk, reset, WriteMCAUSEM, NextCauseM, MCAUSE_REGW);
|
||||
if(`QEMU) assign MTVAL_REGW = `XLEN'b0;
|
||||
else flopenr #(`XLEN) MTVALreg(clk, reset, WriteMTVALM, NextMtvalM, MTVAL_REGW);
|
||||
generate // *** needs comment about bit 1
|
||||
if (`BUSYBEAR == 1) begin:counters
|
||||
if (`BUSYBEAR == 1) begin:counters // counter 1 (TIME) enable tied to 0 to match simulator***
|
||||
flopenr #(32) MCOUNTERENreg(clk, reset, WriteMCOUNTERENM, {CSRWriteValM[31:2],1'b0,CSRWriteValM[0]}, MCOUNTEREN_REGW);
|
||||
end else begin:counters
|
||||
flopenr #(32) MCOUNTERENreg(clk, reset, WriteMCOUNTERENM, CSRWriteValM[31:0], MCOUNTEREN_REGW);
|
||||
end
|
||||
endgenerate
|
||||
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
|
||||
generate
|
||||
if (`N_SUPPORTED) begin:nmode
|
||||
if (`N_SUPPORTED) begin:nmode // depricated; consider removing***
|
||||
logic WriteUTVECM;
|
||||
logic WriteUSCRATCHM, WriteUEPCM;
|
||||
logic WriteUCAUSEM, WriteUTVALM;
|
||||
@ -96,5 +95,4 @@ module csrn #(parameter
|
||||
assign UTVEC_REGW = 0;
|
||||
assign IllegalCSRNAccessM = 1;
|
||||
end
|
||||
endgenerate
|
||||
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
|
||||
|
||||
// Supervisor mode CSRs sometimes supported
|
||||
generate
|
||||
if (`S_SUPPORTED) begin:csrs
|
||||
logic WriteSTVECM;
|
||||
logic WriteSSCRATCHM, WriteSEPCM;
|
||||
@ -153,5 +152,4 @@ module csrs #(parameter
|
||||
assign SATP_REGW = 0;
|
||||
assign IllegalCSRSAccessM = 1;
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
||||
|
||||
@ -50,7 +50,6 @@ module csrsr (
|
||||
// See Privileged Spec Section 3.1.6
|
||||
// Lower privilege status registers are a subset of the full status register
|
||||
// *** consider adding MBE, SBE, UBE fields later from 20210108 draft spec
|
||||
generate
|
||||
if (`XLEN==64) begin: csrsr64 // RV64
|
||||
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,
|
||||
@ -83,10 +82,8 @@ module csrsr (
|
||||
/*STATUS_SPP, STATUS_MPIE, 1'b0 2'b0, STATUS_SPIE,*/ STATUS_UPIE,
|
||||
/*STATUS_MIE, 1'b0*/ 3'b0, /*STATUS_SIE, */STATUS_UIE};
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// harwired STATUS bits
|
||||
generate
|
||||
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_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_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
|
||||
endgenerate
|
||||
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
|
||||
|
||||
|
||||
@ -44,7 +44,6 @@ module csru #(parameter
|
||||
);
|
||||
|
||||
// Floating Point CSRs in User Mode only needed if Floating Point is supported
|
||||
generate
|
||||
if (`F_SUPPORTED | `D_SUPPORTED) begin:csru
|
||||
logic [4:0] FFLAGS_REGW;
|
||||
logic [2:0] NextFRMM;
|
||||
@ -81,5 +80,4 @@ module csru #(parameter
|
||||
assign CSRUReadValM = 0;
|
||||
assign IllegalCSRUAccessM = 1;
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
||||
|
||||
@ -103,7 +103,6 @@ module trap (
|
||||
// > 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
|
||||
// [untested] PrivilegedVectoredTrapVector = {PrivilegedTrapVector[`XLEN-1:7], CauseM[3:0], 4'b0000}
|
||||
generate
|
||||
if(`VECTORED_INTERRUPTS_SUPPORTED) begin:vec
|
||||
always_comb
|
||||
if (PrivilegedTrapVector[1:0] == 2'b01 & CauseM[`XLEN-1] == 1)
|
||||
@ -114,7 +113,6 @@ module trap (
|
||||
else begin
|
||||
assign PrivilegedVectoredTrapVector = {PrivilegedTrapVector[`XLEN-1:2], 2'b00};
|
||||
end
|
||||
endgenerate
|
||||
|
||||
always_comb
|
||||
if (mretM) PrivilegedNextPCM = MEPC_REGW;
|
||||
|
||||
@ -55,12 +55,8 @@ module clint (
|
||||
assign HREADYCLINT = 1'b1; // *** needs to depend on DONE during accesses
|
||||
|
||||
// word aligned reads
|
||||
generate
|
||||
if (`XLEN==64)
|
||||
assign #2 entry = {HADDR[15:3], 3'b000};
|
||||
else
|
||||
assign #2 entry = {HADDR[15:2], 2'b00};
|
||||
endgenerate
|
||||
if (`XLEN==64) assign #2 entry = {HADDR[15:3], 3'b000};
|
||||
else assign #2 entry = {HADDR[15:2], 2'b00};
|
||||
|
||||
// DH 2/20/21: Eventually allow MTIME to run off a separate 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.
|
||||
|
||||
// register access
|
||||
generate
|
||||
if (`XLEN==64) begin:clint // 64-bit
|
||||
always @(posedge HCLK) begin
|
||||
case(entry)
|
||||
@ -136,7 +131,6 @@ module clint (
|
||||
MTIME[63:32]<= HWDATA;
|
||||
end else MTIME <= MTIME + 1;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// Software interrupt when MSIP is set
|
||||
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
|
||||
// requires rippling through N-1 XOR gates
|
||||
generate
|
||||
begin
|
||||
genvar i;
|
||||
assign b[N-1] = g[N-1];
|
||||
for (i=N-2; i >= 0; i--) begin:g2b
|
||||
assign b[i] = g[i] ^ b[i+1];
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
||||
|
||||
@ -61,23 +61,13 @@ module gpio (
|
||||
// account for subword read/write circuitry
|
||||
// -- Note GPIO registers are 32 bits no matter what; access them with LW SW.
|
||||
// (At least that's what I think when FE310 spec says "only naturally aligned 32-bit accesses are supported")
|
||||
generate
|
||||
if (`XLEN == 64) begin:gpio
|
||||
always_comb
|
||||
if (entryd[2]) begin
|
||||
Din = HWDATA[63:32];
|
||||
HREADGPIO = {Dout,32'b0};
|
||||
end else begin
|
||||
Din = HWDATA[31:0];
|
||||
HREADGPIO = {32'b0,Dout};
|
||||
if (`XLEN == 64) begin
|
||||
assign Din = entryd[2] ? HWDATA[63:32] : HWDATA[31:0];
|
||||
assign HREADGPIO = entryd[2] ? {Dout,32'b0} : {32'b0,Dout};
|
||||
end else begin // 32-bit
|
||||
assign Din = HWDATA[31:0];
|
||||
assign HREADGPIO = Dout;
|
||||
end
|
||||
end else begin:gpio // 32-bit
|
||||
always_comb begin
|
||||
Din = HWDATA[31:0];
|
||||
HREADGPIO = Dout;
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// register access
|
||||
always_ff @(posedge HCLK, negedge HRESETn) begin
|
||||
@ -150,12 +140,9 @@ module gpio (
|
||||
end
|
||||
|
||||
// chip i/o
|
||||
generate
|
||||
if (`GPIO_LOOPBACK_TEST) // connect OUT to IN for loopback testing
|
||||
assign input0d = GPIOPinsOut & input_en & output_en;
|
||||
else
|
||||
assign input0d = GPIOPinsIn & input_en;
|
||||
endgenerate
|
||||
// connect OUT to IN for loopback testing
|
||||
if (`GPIO_LOOPBACK_TEST) assign input0d = GPIOPinsOut & input_en & output_en;
|
||||
else assign input0d = GPIOPinsIn & input_en;
|
||||
flop #(32) sync1(HCLK,input0d,input1d);
|
||||
flop #(32) sync2(HCLK,input1d,input2d);
|
||||
flop #(32) sync3(HCLK,input2d,input3d);
|
||||
|
||||
@ -77,23 +77,13 @@ module plic (
|
||||
|
||||
// account for subword read/write circuitry
|
||||
// -- Note PLIC registers are 32 bits no matter what; access them with LW SW.
|
||||
generate
|
||||
if (`XLEN == 64) begin:plic
|
||||
always_comb
|
||||
if (entryd[2]) begin
|
||||
Din = HWDATA[63:32];
|
||||
HREADPLIC = {Dout,32'b0};
|
||||
end else begin
|
||||
Din = HWDATA[31:0];
|
||||
HREADPLIC = {32'b0,Dout};
|
||||
if (`XLEN == 64) begin
|
||||
assign Din = entryd[2] ? HWDATA[63:32] : HWDATA[31:0];
|
||||
assign HREADPLIC = entryd[2] ? {Dout,32'b0} : {32'b0,Dout};
|
||||
end else begin // 32-bit
|
||||
assign Din = HWDATA[31:0];
|
||||
assign HREADPLIC = Dout;
|
||||
end
|
||||
end else begin:plic // 32-bit
|
||||
always_comb begin
|
||||
Din = HWDATA[31:0];
|
||||
HREADPLIC = Dout;
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// ==================
|
||||
// Register Interface
|
||||
@ -165,14 +155,11 @@ module plic (
|
||||
|
||||
// pending array - indexed by priority_lvl x source_ID
|
||||
genvar i, j;
|
||||
generate
|
||||
for (j=1; j<=7; j++) begin: pending
|
||||
for (i=1; i<=N; i=i+1) begin: pendingbit
|
||||
// *** make sure that this synthesizes into N decoders, not 7*N 3-bit equality comparators (right?)
|
||||
assign pendingArray[j][i] = (intPriority[i]==j) & intEn[i] & intPending[i];
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
// pending array, except grouped by priority
|
||||
assign pendingPGrouped[7:1] = {|pendingArray[7],
|
||||
|pendingArray[6],
|
||||
@ -200,8 +187,7 @@ module plic (
|
||||
| ({N{pendingMaxP[2]}} & pendingArray[2])
|
||||
| ({N{pendingMaxP[1]}} & pendingArray[1]);
|
||||
// find the lowest ID amongst active interrupts at the highest priority
|
||||
int k;
|
||||
// *** verify that this synthesizes to a reasonable priority encoder and that k doesn't actually exist in hardware
|
||||
int k; // *** rewrite as priority encoder
|
||||
always_comb begin
|
||||
intClaim = 6'b0;
|
||||
for(k=N; k>0; k=k-1) begin
|
||||
|
||||
@ -49,11 +49,9 @@ module ram #(parameter BASE=0, RANGE = 65535) (
|
||||
logic memwrite;
|
||||
logic [3:0] busycount;
|
||||
|
||||
generate
|
||||
if(`FPGA) begin:ram
|
||||
initial begin
|
||||
//$readmemh(PRELOAD, RAM);
|
||||
// FPGA only
|
||||
RAM[0] = 64'h94e1819300002197;
|
||||
RAM[1] = 64'h4281420141014081;
|
||||
RAM[2] = 64'h4481440143814301;
|
||||
@ -98,7 +96,6 @@ module ram #(parameter BASE=0, RANGE = 65535) (
|
||||
RAM[41] = 64'h0000808210a7a023;
|
||||
end // initial begin
|
||||
end // if (FPGA)
|
||||
endgenerate
|
||||
|
||||
assign initTrans = HREADY & HSELRam & (HTRANS != 2'b00);
|
||||
|
||||
@ -144,26 +141,23 @@ module ram #(parameter BASE=0, RANGE = 65535) (
|
||||
-----/\----- EXCLUDED -----/\----- */
|
||||
|
||||
/* verilator lint_off WIDTH */
|
||||
generate
|
||||
if (`XLEN == 64) begin:ramrd
|
||||
if (`XLEN == 64) begin:ramrw
|
||||
always_ff @(posedge HCLK) begin
|
||||
HWADDR <= #1 A;
|
||||
HREADRam0 <= #1 RAM[A[31:3]];
|
||||
if (memwrite & risingHREADYRam) RAM[HWADDR[31:3]] <= #1 HWDATA;
|
||||
end
|
||||
end else begin
|
||||
always_ff @(posedge HCLK) begin:ramrd
|
||||
always_ff @(posedge HCLK) begin:ramrw
|
||||
HWADDR <= #1 A;
|
||||
HREADRam0 <= #1 RAM[A[31:2]];
|
||||
if (memwrite & risingHREADYRam) RAM[HWADDR[31:2]] <= #1 HWDATA;
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
/* verilator lint_on WIDTH */
|
||||
|
||||
//assign HREADRam = HREADYRam ? HREADRam0 : `XLEN'bz;
|
||||
// *** Ross Thompson: removed tristate as fpga synthesis removes.
|
||||
assign HREADRam = HREADRam0;
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
@ -156,7 +156,6 @@ module SDC
|
||||
flopenl #(3) CommandReg(HCLK, ~HRESETn, (HADDRDelay == 'h8 & RegWrite) | (CommandCompleted),
|
||||
CommandCompleted ? '0 : HWDATA[2:0], '0, Command);
|
||||
|
||||
generate
|
||||
if (`XLEN == 64) begin
|
||||
flopenr #(64-9) AddressReg(HCLK, ~HRESETn, (HADDRDelay == 'h10 & RegWrite),
|
||||
HWDATA[`XLEN-1:9], Address);
|
||||
@ -166,7 +165,6 @@ module SDC
|
||||
flopenr #(32) AddressHighReg(HCLK, ~HRESETn, (HADDRDelay == 'h14 & RegWrite),
|
||||
HWDATA, Address[63:32]);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
flopen #(`XLEN) DataReg(HCLK, (HADDRDelay == 'h18 & RegWrite),
|
||||
HWDATA, SDCWriteData);
|
||||
@ -175,7 +173,6 @@ module SDC
|
||||
|
||||
assign Status = {ErrorCode, InvalidCommand, SDCBusy, SDCInitialized};
|
||||
|
||||
generate
|
||||
if(`XLEN == 64) begin
|
||||
always_comb
|
||||
case(HADDRDelay[4:0])
|
||||
@ -200,7 +197,6 @@ module SDC
|
||||
default: HREADSDC = {24'b0, CLKDiv};
|
||||
endcase
|
||||
end
|
||||
endgenerate
|
||||
|
||||
|
||||
for(index = 0; index < 4096/`XLEN; index++) begin
|
||||
@ -208,7 +204,6 @@ module SDC
|
||||
end
|
||||
|
||||
assign SDCReadDataPreNibbleSwap = ReadData512ByteWords[WordCount];
|
||||
generate
|
||||
if(`XLEN == 64) begin
|
||||
assign SDCReadData = {SDCReadDataPreNibbleSwap[59:56], SDCReadDataPreNibbleSwap[63:60],
|
||||
SDCReadDataPreNibbleSwap[51:48], SDCReadDataPreNibbleSwap[55:52],
|
||||
@ -224,7 +219,6 @@ module SDC
|
||||
SDCReadDataPreNibbleSwap[11:8], SDCReadDataPreNibbleSwap[15:12],
|
||||
SDCReadDataPreNibbleSwap[3:0], SDCReadDataPreNibbleSwap[7:4]};
|
||||
end
|
||||
endgenerate
|
||||
|
||||
flopenr #($clog2(4096/`XLEN)) WordCountReg
|
||||
(.clk(HCLK),
|
||||
|
||||
@ -88,17 +88,6 @@ module clkdivider #(parameter integer g_COUNT_WIDTH)
|
||||
|
||||
assign w_fd_D = ~ r_fd_Q;
|
||||
|
||||
|
||||
generate
|
||||
if(`FPGA) begin
|
||||
BUFGMUX
|
||||
clkMux(.I1(r_fd_Q),
|
||||
.I0(i_CLK),
|
||||
.S(i_EN),
|
||||
.O(o_CLK));
|
||||
|
||||
end else begin
|
||||
assign o_CLK = i_EN ? r_fd_Q : i_CLK;
|
||||
end
|
||||
endgenerate
|
||||
if(`FPGA) BUFGMUX clkMux(.I1(r_fd_Q), .I0(i_CLK), .S(i_EN), .O(o_CLK));
|
||||
else assign o_CLK = i_EN ? r_fd_Q : i_CLK;
|
||||
endmodule
|
||||
|
||||
@ -35,7 +35,6 @@ module subwordwrite (
|
||||
|
||||
logic [`XLEN-1:0] WriteDataSubwordDuplicated;
|
||||
|
||||
generate
|
||||
if (`XLEN == 64) begin:sww
|
||||
logic [7:0] ByteMaskM;
|
||||
// Compute write mask
|
||||
@ -104,6 +103,4 @@ module subwordwrite (
|
||||
end
|
||||
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
||||
|
||||
@ -54,7 +54,6 @@ module uart (
|
||||
assign HRESPUART = 0; // OK
|
||||
assign HREADYUART = 1; // should idle high during address phase and respond high when done; will need to be modified if UART ever needs more than 1 cycle to do something
|
||||
|
||||
generate
|
||||
if (`XLEN == 64) begin:uart
|
||||
always_comb begin
|
||||
HREADUART = {Dout, Dout, Dout, Dout, Dout, Dout, Dout, Dout};
|
||||
@ -80,7 +79,6 @@ module uart (
|
||||
endcase
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
logic BAUDOUTb; // loop tx clock BAUDOUTb back to rx clock RCLK
|
||||
// *** make sure reads don't occur on UART unless fully selected because they could change state. This applies to all peripherals
|
||||
|
||||
@ -257,12 +257,9 @@ module uartPC16550D(
|
||||
else if (fifoenabled & ~rxfifoempty & rxbaudpulse & ~rxfifotimeout) rxtimeoutcnt <= #1 rxtimeoutcnt+1; // *** not right
|
||||
end
|
||||
|
||||
generate
|
||||
if(`QEMU)
|
||||
assign rxcentered = rxbaudpulse & (rxoversampledcnt[1:0] == 2'b10); // implies rxstate = UART_ACTIVE
|
||||
else
|
||||
assign rxcentered = rxbaudpulse & (rxoversampledcnt == 4'b1000); // implies rxstate = UART_ACTIVE
|
||||
endgenerate
|
||||
// ***explain why
|
||||
if(`QEMU) assign rxcentered = rxbaudpulse & (rxoversampledcnt[1:0] == 2'b10); // implies rxstate = UART_ACTIVE
|
||||
else assign rxcentered = rxbaudpulse & (rxoversampledcnt == 4'b1000); // implies rxstate = UART_ACTIVE
|
||||
|
||||
assign rxbitsexpected = 4'd1 + (4'd5 + {2'b00, LCR[1:0]}) + {3'b000, LCR[3]} + 4'd1; // start bit + data bits + (parity bit) + stop bit
|
||||
|
||||
@ -325,7 +322,6 @@ module uartPC16550D(
|
||||
// detect any errors in rx fifo
|
||||
// although rxfullbit looks like a combinational loop, in one bit rxfifotail == i and breaks the loop
|
||||
// tail is normally higher than head, but might wrap around. unwrapped variable adds 16 to eliminate wrapping
|
||||
generate
|
||||
assign rxfifotailunwrapped = rxfifotail < rxfifohead ? {1'b1, rxfifotail} : {1'b0, rxfifotail};
|
||||
genvar i;
|
||||
for (i=0; i<32; i++) begin:rxfull
|
||||
@ -340,7 +336,6 @@ module uartPC16550D(
|
||||
else
|
||||
assign rxfullbit[0] = ((rxfifohead==i) | rxfullbit[15]) & (rxfifotail != i);*/
|
||||
end
|
||||
endgenerate
|
||||
assign rxfifohaserr = |(RXerrbit & rxfullbit);
|
||||
|
||||
// receive buffer register and ready bit
|
||||
@ -383,13 +378,9 @@ module uartPC16550D(
|
||||
end
|
||||
|
||||
assign txbitsexpected = 4'd1 + (4'd5 + {2'b00, LCR[1:0]}) + {3'b000, LCR[3]} + 4'd1 + {3'b000, LCR[2]} - 4'd1; // start bit + data bits + (parity bit) + stop bit(s)
|
||||
generate
|
||||
if (`QEMU)
|
||||
assign txnextbit = txbaudpulse & (txoversampledcnt[1:0] == 2'b00); // implies txstate = UART_ACTIVE
|
||||
else
|
||||
assign txnextbit = txbaudpulse & (txoversampledcnt == 4'b0000); // implies txstate = UART_ACTIVE
|
||||
endgenerate
|
||||
|
||||
// *** explain; is this necessary?
|
||||
if (`QEMU) assign txnextbit = txbaudpulse & (txoversampledcnt[1:0] == 2'b00); // implies txstate = UART_ACTIVE
|
||||
else assign txnextbit = txbaudpulse & (txoversampledcnt == 4'b0000); // implies txstate = UART_ACTIVE
|
||||
|
||||
///////////////////////////////////////////
|
||||
// transmit holding register, shift register, FIFO
|
||||
|
||||
@ -304,7 +304,6 @@ module wallypipelinedhart (
|
||||
.FlushF, .FlushD, .FlushE, .FlushM, .FlushW
|
||||
); // global stall and flush control
|
||||
|
||||
generate
|
||||
if (`ZICSR_SUPPORTED) begin:priv
|
||||
privileged priv(
|
||||
.clk, .reset,
|
||||
@ -385,7 +384,4 @@ module wallypipelinedhart (
|
||||
assign IllegalFPUInstrD = 1;
|
||||
assign SetFflagsM = 0;
|
||||
end
|
||||
|
||||
endgenerate
|
||||
// Priveleged block operates in M and W stages, handling CSRs and exceptions
|
||||
endmodule
|
||||
|
||||
@ -121,11 +121,9 @@ module sdModel
|
||||
integer sdModel_file_desc;
|
||||
|
||||
genvar i;
|
||||
generate
|
||||
for(i=0; i<4; i=i+1) begin:CRC_16_gen
|
||||
sd_crc_16 CRC_16_i (crcDat_in[i],crcDat_en, sdClk, crcDat_rst, crcDat_out[i]);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
sd_crc_7 crc_7
|
||||
(
|
||||
|
||||
@ -763,17 +763,12 @@ string tests32f[] = '{
|
||||
.done(DCacheFlushDone));
|
||||
|
||||
|
||||
generate
|
||||
// initialize the branch predictor
|
||||
if (`BPRED_ENABLED == 1) begin : bpred
|
||||
|
||||
if (`BPRED_ENABLED == 1)
|
||||
initial begin
|
||||
$readmemb(`TWO_BIT_PRELOAD, dut.wallypipelinedsoc.hart.ifu.bpred.bpred.Predictor.DirPredictor.PHT.mem);
|
||||
$readmemb(`BTB_PRELOAD, dut.wallypipelinedsoc.hart.ifu.bpred.bpred.TargetPredictor.memory.mem);
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
||||
|
||||
module riscvassertions();
|
||||
@ -830,12 +825,10 @@ module DCacheFlushFSM
|
||||
|
||||
logic [`XLEN-1:0] ShadowRAM[`RAM_BASE>>(1+`XLEN/32):(`RAM_RANGE+`RAM_BASE)>>1+(`XLEN/32)];
|
||||
|
||||
generate
|
||||
for(index = 0; index < numlines; index++) begin
|
||||
for(way = 0; way < numways; way++) begin
|
||||
for(cacheWord = 0; cacheWord < numwords; cacheWord++) begin
|
||||
copyShadow #(.tagstart(tagstart),
|
||||
.loglinebytelen(loglinebytelen))
|
||||
copyShadow #(.tagstart(tagstart), .loglinebytelen(loglinebytelen))
|
||||
copyShadow(.clk,
|
||||
.start,
|
||||
.tag(testbench.dut.wallypipelinedsoc.hart.lsu.dcache.MemWay[way].CacheTagMem.StoredData[index]),
|
||||
@ -852,7 +845,6 @@ module DCacheFlushFSM
|
||||
end
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
integer i, j, k;
|
||||
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
// 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.
|
||||
|
||||
// When letting Wally go for it, let wally generate own interrupts
|
||||
// When letting Wally go for it, let wally make own interrupts
|
||||
///////////////////////////////////////////
|
||||
|
||||
`include "wally-config.vh"
|
||||
@ -36,7 +36,7 @@
|
||||
// 4: print memory accesses whenever they happen
|
||||
// 5: print everything
|
||||
|
||||
module testbench();
|
||||
module testbench;
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////// CONFIG ////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -280,13 +280,6 @@ module testbench();
|
||||
|
||||
`INIT_CHECKPOINT_SIMPLE_ARRAY(RF, [`XLEN-1:0],31,1);
|
||||
`INIT_CHECKPOINT_SIMPLE_ARRAY(HPMCOUNTER, [`XLEN-1:0],`COUNTERS-1,3);
|
||||
generate
|
||||
genvar i;
|
||||
/* -----\/----- EXCLUDED -----\/-----
|
||||
`INIT_CHECKPOINT_GENBLK_ARRAY(PMP_BASE, PMPCFG, [7:0],`PMP_ENTRIES-1,0);
|
||||
`INIT_CHECKPOINT_GENBLK_ARRAY(PMP_BASE, PMPADDR, [`XLEN-1:0],`PMP_ENTRIES-1,0);
|
||||
-----/\----- EXCLUDED -----/\----- */
|
||||
endgenerate
|
||||
`INIT_CHECKPOINT_VAL(PC, [`XLEN-1:0]);
|
||||
`INIT_CHECKPOINT_VAL(MEDELEG, [`XLEN-1:0]);
|
||||
`INIT_CHECKPOINT_VAL(MIDELEG, [`XLEN-1:0]);
|
||||
|
||||
@ -296,13 +296,8 @@ logic [3:0] dummy;
|
||||
// or sw gp, -56(t0)
|
||||
// or on a jump to self infinite loop (6f) for RISC-V Arch tests
|
||||
logic ecf; // remove this once we don't rely on old Imperas tests with Ecalls
|
||||
generate
|
||||
if (`ZICSR_SUPPORTED) begin
|
||||
assign ecf = dut.hart.priv.priv.EcallFaultM;
|
||||
end else begin
|
||||
assign ecf = 0;
|
||||
end
|
||||
endgenerate
|
||||
if (`ZICSR_SUPPORTED) assign ecf = dut.hart.priv.priv.EcallFaultM;
|
||||
else assign ecf = 0;
|
||||
assign DCacheFlushStart = ecf &
|
||||
(dut.hart.ieu.dp.regf.rf[3] == 1 |
|
||||
(dut.hart.ieu.dp.regf.we3 &
|
||||
@ -310,24 +305,17 @@ logic [3:0] dummy;
|
||||
dut.hart.ieu.dp.regf.wd3 == 1)) |
|
||||
(dut.hart.ifu.InstrM == 32'h6f | dut.hart.ifu.InstrM == 32'hfc32a423 | dut.hart.ifu.InstrM == 32'hfc32a823) & dut.hart.ieu.c.InstrValidM;
|
||||
|
||||
// **** Fix when the check in the shadow ram is fixed.
|
||||
DCacheFlushFSM DCacheFlushFSM(.clk(clk),
|
||||
.reset(reset),
|
||||
.start(DCacheFlushStart),
|
||||
.done(DCacheFlushDone));
|
||||
|
||||
|
||||
generate
|
||||
// initialize the branch predictor
|
||||
if (`BPRED_ENABLED == 1) begin : bpred
|
||||
|
||||
if (`BPRED_ENABLED == 1)
|
||||
initial begin
|
||||
$readmemb(`TWO_BIT_PRELOAD, dut.hart.ifu.bpred.bpred.Predictor.DirPredictor.PHT.mem);
|
||||
$readmemb(`BTB_PRELOAD, dut.hart.ifu.bpred.bpred.TargetPredictor.memory.mem);
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
||||
|
||||
module riscvassertions;
|
||||
@ -370,7 +358,6 @@ module DCacheFlushFSM
|
||||
|
||||
logic [`XLEN-1:0] ShadowRAM[`RAM_BASE>>(1+`XLEN/32):(`RAM_RANGE+`RAM_BASE)>>1+(`XLEN/32)];
|
||||
|
||||
generate
|
||||
if(`MEM_DCACHE) begin
|
||||
localparam integer numlines = testbench.dut.hart.lsu.dcache.dcache.NUMLINES;
|
||||
localparam integer numways = testbench.dut.hart.lsu.dcache.dcache.NUMWAYS;
|
||||
@ -430,15 +417,7 @@ module DCacheFlushFSM
|
||||
|
||||
|
||||
end
|
||||
endgenerate
|
||||
|
||||
|
||||
|
||||
|
||||
flop #(1) doneReg(.clk(clk),
|
||||
.d(start),
|
||||
.q(done));
|
||||
|
||||
flop #(1) doneReg(.clk, .d(start), .q(done));
|
||||
endmodule
|
||||
|
||||
module copyShadow
|
||||
|
||||
Loading…
Reference in New Issue
Block a user