Removed more generate statements

This commit is contained in:
David Harris 2022-01-05 16:25:08 +00:00
parent f04856ee94
commit 32590d484c
20 changed files with 562 additions and 651 deletions

View File

@ -153,7 +153,7 @@ fma2 UUT2(.XSgnM(XSgnE), .YSgnM(YSgnE), .XExpM(XExpE), .YExpM(YExpE), .ZExpM(ZEx
.FmtM(FmtE), .FrmM(FrmE), .FMAFlgM, .FMAResM); .FmtM(FmtE), .FrmM(FrmE), .FMAFlgM, .FMAResM);
// generate clock // produce clock
always always
begin begin
clk = 1; #5; clk = 0; #5; clk = 1; #5; clk = 0; #5;

View File

@ -45,14 +45,12 @@ endmodule
module INVX2(input logic a, output logic y); module INVX2(input logic a, output logic y);
generate if (LIB == SKY130)
if (LIB == SKY130) sky130_osu_sc_12T_ms__inv_2 inv(a, y);
sky130_osu_sc_12T_ms__inv_2 inv(a, y); else if (LIB == SKL90)
else if (LIB == SKL90) scc9gena_inv_2 inv(a, y)
scc9gena_inv_2 inv(a, y) else if (LIB == GF14)
else if (LIB == GF14) INV_X2N_A10P5PP84TSL_C14(a, y)
INV_X2N_A10P5PP84TSL_C14(a, y)
endgenerate
endmodule endmodule
module driver #(parameter WDITH=1) ( module driver #(parameter WDITH=1) (

View File

@ -72,109 +72,106 @@ module cachereplacementpolicy
assign LineReplacementBits = ReplacementBits[RAdrD]; assign LineReplacementBits = ReplacementBits[RAdrD];
genvar index; genvar index;
generate if(NUMWAYS == 2) begin : TwoWay
if(NUMWAYS == 2) begin : TwoWay
assign LRUEn[0] = 1'b0; assign LRUEn[0] = 1'b0;
assign NewReplacement[0] = WayHit[1]; assign NewReplacement[0] = WayHit[1];
assign VictimWay[1] = ~LineReplacementBits[0]; assign VictimWay[1] = ~LineReplacementBits[0];
assign VictimWay[0] = LineReplacementBits[0]; assign VictimWay[0] = LineReplacementBits[0];
end else if (NUMWAYS == 4) begin : FourWay end else if (NUMWAYS == 4) begin : FourWay
// VictimWay is a function only of the current value of the LRU. // VictimWay is a function only of the current value of the LRU.
// binary encoding // binary encoding
//assign VictimWay[0] = LineReplacementBits[2] ? LineReplacementBits[1] : LineReplacementBits[0]; //assign VictimWay[0] = LineReplacementBits[2] ? LineReplacementBits[1] : LineReplacementBits[0];
//assign VictimWay[1] = LineReplacementBits[2]; //assign VictimWay[1] = LineReplacementBits[2];
// 1 hot encoding // 1 hot encoding
//| WayHit | LRU 2 | LRU 1 | LRU 0 | //| WayHit | LRU 2 | LRU 1 | LRU 0 |
//|--------+-------+-------+-------| //|--------+-------+-------+-------|
//| 0000 | - | - | - | //| 0000 | - | - | - |
//| 0001 | 1 | - | 1 | //| 0001 | 1 | - | 1 |
//| 0010 | 1 | - | 0 | //| 0010 | 1 | - | 0 |
//| 0100 | 0 | 1 | - | //| 0100 | 0 | 1 | - |
//| 1000 | 0 | 0 | - | //| 1000 | 0 | 0 | - |
assign VictimWay[0] = ~LineReplacementBits[2] & ~LineReplacementBits[0]; assign VictimWay[0] = ~LineReplacementBits[2] & ~LineReplacementBits[0];
assign VictimWay[1] = ~LineReplacementBits[2] & LineReplacementBits[0]; assign VictimWay[1] = ~LineReplacementBits[2] & LineReplacementBits[0];
assign VictimWay[2] = LineReplacementBits[2] & ~LineReplacementBits[1]; assign VictimWay[2] = LineReplacementBits[2] & ~LineReplacementBits[1];
assign VictimWay[3] = LineReplacementBits[2] & LineReplacementBits[1]; assign VictimWay[3] = LineReplacementBits[2] & LineReplacementBits[1];
// New LRU bits which are updated is function only of the WayHit. // New LRU bits which are updated is function only of the WayHit.
// However the not updated bits come from the old LRU. // However the not updated bits come from the old LRU.
assign LRUEn[2] = |WayHit; assign LRUEn[2] = |WayHit;
assign LRUEn[1] = WayHit[3] | WayHit[2]; assign LRUEn[1] = WayHit[3] | WayHit[2];
assign LRUEn[0] = WayHit[1] | WayHit[0]; assign LRUEn[0] = WayHit[1] | WayHit[0];
assign LRUMask[2] = WayHit[1] | WayHit[0]; assign LRUMask[2] = WayHit[1] | WayHit[0];
assign LRUMask[1] = WayHit[2]; assign LRUMask[1] = WayHit[2];
assign LRUMask[0] = WayHit[0]; assign LRUMask[0] = WayHit[0];
/* -----\/----- EXCLUDED -----\/----- /* -----\/----- EXCLUDED -----\/-----
// selects // selects
assign LRUEn[2] = 1'b1; assign LRUEn[2] = 1'b1;
assign LRUEn[1] = WayHit[3]; assign LRUEn[1] = WayHit[3];
assign LRUEn[0] = WayHit[3] | WayHit[2]; assign LRUEn[0] = WayHit[3] | WayHit[2];
// mask // mask
assign LRUMask[0] = WayHit[1]; assign LRUMask[0] = WayHit[1];
assign LRUMask[1] = WayHit[3]; assign LRUMask[1] = WayHit[3];
assign LRUMask[2] = WayHit[3] | WayHit[2]; assign LRUMask[2] = WayHit[3] | WayHit[2];
-----/\----- EXCLUDED -----/\----- */ -----/\----- EXCLUDED -----/\----- */
for(index = 0; index < NUMWAYS-1; index++) for(index = 0; index < NUMWAYS-1; index++)
assign NewReplacement[index] = LRUEn[index] ? LRUMask[index] : LineReplacementBits[index]; assign NewReplacement[index] = LRUEn[index] ? LRUMask[index] : LineReplacementBits[index];
/* -----\/----- EXCLUDED -----\/----- /* -----\/----- EXCLUDED -----\/-----
assign EncVicWay[1] = LineReplacementBits[2]; assign EncVicWay[1] = LineReplacementBits[2];
assign EncVicWay[0] = LineReplacementBits[2] ? LineReplacementBits[0] : LineReplacementBits[1]; assign EncVicWay[0] = LineReplacementBits[2] ? LineReplacementBits[0] : LineReplacementBits[1];
onehotdecoder #(2) onehotdecoder #(2)
waydec(.bin(EncVicWay), waydec(.bin(EncVicWay),
.decoded({VictimWay[0], VictimWay[1], VictimWay[2], VictimWay[3]})); .decoded({VictimWay[0], VictimWay[1], VictimWay[2], VictimWay[3]}));
-----/\----- EXCLUDED -----/\----- */ -----/\----- EXCLUDED -----/\----- */
end else if (NUMWAYS == 8) begin : EightWay end else if (NUMWAYS == 8) begin : EightWay
// selects // selects
assign LRUEn[6] = 1'b1; assign LRUEn[6] = 1'b1;
assign LRUEn[5] = WayHit[7] | WayHit[6] | WayHit[5] | WayHit[4]; assign LRUEn[5] = WayHit[7] | WayHit[6] | WayHit[5] | WayHit[4];
assign LRUEn[4] = WayHit[7] | WayHit[6]; assign LRUEn[4] = WayHit[7] | WayHit[6];
assign LRUEn[3] = WayHit[5] | WayHit[4]; assign LRUEn[3] = WayHit[5] | WayHit[4];
assign LRUEn[2] = WayHit[3] | WayHit[2] | WayHit[1] | WayHit[0]; assign LRUEn[2] = WayHit[3] | WayHit[2] | WayHit[1] | WayHit[0];
assign LRUEn[1] = WayHit[3] | WayHit[2]; assign LRUEn[1] = WayHit[3] | WayHit[2];
assign LRUEn[0] = WayHit[1] | WayHit[0]; assign LRUEn[0] = WayHit[1] | WayHit[0];
// mask // mask
assign LRUMask[6] = WayHit[7] | WayHit[6] | WayHit[5] | WayHit[4]; assign LRUMask[6] = WayHit[7] | WayHit[6] | WayHit[5] | WayHit[4];
assign LRUMask[5] = WayHit[7] | WayHit[6]; assign LRUMask[5] = WayHit[7] | WayHit[6];
assign LRUMask[4] = WayHit[7]; assign LRUMask[4] = WayHit[7];
assign LRUMask[3] = WayHit[5]; assign LRUMask[3] = WayHit[5];
assign LRUMask[2] = WayHit[3] | WayHit[2]; assign LRUMask[2] = WayHit[3] | WayHit[2];
assign LRUMask[1] = WayHit[2]; assign LRUMask[1] = WayHit[2];
assign LRUMask[0] = WayHit[0]; assign LRUMask[0] = WayHit[0];
for(index = 0; index < NUMWAYS-1; index++) for(index = 0; index < NUMWAYS-1; index++)
assign NewReplacement[index] = LRUEn[index] ? LRUMask[index] : LineReplacementBits[index]; assign NewReplacement[index] = LRUEn[index] ? LRUMask[index] : LineReplacementBits[index];
assign EncVicWay[2] = LineReplacementBits[6]; assign EncVicWay[2] = LineReplacementBits[6];
assign EncVicWay[1] = LineReplacementBits[6] ? LineReplacementBits[5] : LineReplacementBits[2]; assign EncVicWay[1] = LineReplacementBits[6] ? LineReplacementBits[5] : LineReplacementBits[2];
assign EncVicWay[0] = LineReplacementBits[6] ? LineReplacementBits[5] ? LineReplacementBits[4] : LineReplacementBits[3] : assign EncVicWay[0] = LineReplacementBits[6] ? LineReplacementBits[5] ? LineReplacementBits[4] : LineReplacementBits[3] :
LineReplacementBits[2] ? LineReplacementBits[1] : LineReplacementBits[0]; LineReplacementBits[2] ? LineReplacementBits[1] : LineReplacementBits[0];
onehotdecoder #(3) onehotdecoder #(3)
waydec(.bin(EncVicWay), waydec(.bin(EncVicWay),
.decoded({VictimWay[0], VictimWay[1], VictimWay[2], VictimWay[3], .decoded({VictimWay[0], VictimWay[1], VictimWay[2], VictimWay[3],
VictimWay[4], VictimWay[5], VictimWay[6], VictimWay[7]})); VictimWay[4], VictimWay[5], VictimWay[6], VictimWay[7]}));
end end
endgenerate
endmodule endmodule

View File

@ -72,16 +72,13 @@ module cacheway #(parameter NUMLINES=512, parameter LINELEN = 256, TAGLEN = 26,
genvar words; genvar words;
for(words = 0; words < LINELEN/`XLEN; words++) begin: word
generate sram1rw #(.DEPTH(`XLEN), .WIDTH(NUMLINES))
for(words = 0; words < LINELEN/`XLEN; words++) begin : word CacheDataMem(.clk(clk), .Addr(RAdr),
sram1rw #(.DEPTH(`XLEN), .WIDTH(NUMLINES)) .ReadData(ReadDataLineWay[(words+1)*`XLEN-1:words*`XLEN] ),
CacheDataMem(.clk(clk), .Addr(RAdr), .WriteData(WriteData[(words+1)*`XLEN-1:words*`XLEN]),
.ReadData(ReadDataLineWay[(words+1)*`XLEN-1:words*`XLEN] ), .WriteEnable(WriteEnable & WriteWordEnable[words]));
.WriteData(WriteData[(words+1)*`XLEN-1:words*`XLEN]), end
.WriteEnable(WriteEnable & WriteWordEnable[words]));
end
endgenerate
sram1rw #(.DEPTH(TAGLEN), .WIDTH(NUMLINES)) sram1rw #(.DEPTH(TAGLEN), .WIDTH(NUMLINES))
CacheTagMem(.clk(clk), CacheTagMem(.clk(clk),
@ -123,27 +120,21 @@ module cacheway #(parameter NUMLINES=512, parameter LINELEN = 256, TAGLEN = 26,
assign Valid = ValidBits[RAdrD]; assign Valid = ValidBits[RAdrD];
generate // Dirty bits
if(DIRTY_BITS) begin:dirty if(DIRTY_BITS) begin:dirty
always_ff @(posedge clk) begin always_ff @(posedge clk) begin
if (reset) if (reset) DirtyBits <= {NUMLINES{1'b0}};
DirtyBits <= {NUMLINES{1'b0}}; else if (SetDirtyD & (WriteEnableD | VDWriteEnableD)) DirtyBits[RAdrD] <= 1'b1;
else if (SetDirtyD & (WriteEnableD | VDWriteEnableD)) DirtyBits[RAdrD] <= 1'b1; else if (ClearDirtyD & (WriteEnableD | VDWriteEnableD)) DirtyBits[RAdrD] <= 1'b0;
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 end
endgenerate always_ff @(posedge clk) begin
SetDirtyD <= SetDirty;
ClearDirtyD <= ClearDirty;
end
assign Dirty = DirtyBits[RAdrD];
end else begin:dirty
assign Dirty = 1'b0;
end
endmodule // DCacheMemWay endmodule // DCacheMemWay

View File

@ -143,19 +143,17 @@ module dcache #(parameter integer LINELEN,
.WayHit, .VictimDirtyWay, .VictimTagWay, .WayHit, .VictimDirtyWay, .VictimTagWay,
.InvalidateAll(1'b0)); .InvalidateAll(1'b0));
generate if(NUMWAYS > 1) begin:vict
if(NUMWAYS > 1) begin:vict cachereplacementpolicy #(NUMWAYS, INDEXLEN, OFFSETLEN, NUMLINES)
cachereplacementpolicy #(NUMWAYS, INDEXLEN, OFFSETLEN, NUMLINES) cachereplacementpolicy(.clk, .reset,
cachereplacementpolicy(.clk, .reset, .WayHit,
.WayHit, .VictimWay,
.VictimWay, .LsuPAdrM(LsuPAdrM[INDEXLEN+OFFSETLEN-1:OFFSETLEN]),
.LsuPAdrM(LsuPAdrM[INDEXLEN+OFFSETLEN-1:OFFSETLEN]), .RAdr,
.RAdr, .LRUWriteEn);
.LRUWriteEn); end else begin:vict
end else begin:vict assign VictimWay = 1'b1; // one hot.
assign VictimWay = 1'b1; // one hot. end
end
endgenerate
assign CacheHit = | WayHit; assign CacheHit = | WayHit;
assign VictimDirty = | VictimDirtyWay; assign VictimDirty = | VictimDirtyWay;
@ -172,11 +170,8 @@ module dcache #(parameter integer LINELEN,
// easily build a variable input mux. // easily build a variable input mux.
// *** consider using a limited range shift to do this final muxing. // *** consider using a limited range shift to do this final muxing.
genvar index; genvar index;
generate for (index = 0; index < WORDSPERLINE; index++)
for (index = 0; index < WORDSPERLINE; index++) begin:readdatalinesetsmux assign ReadDataLineSetsM[index] = ReadDataLineM[((index+1)*`XLEN)-1: (index*`XLEN)];
assign ReadDataLineSetsM[index] = ReadDataLineM[((index+1)*`XLEN)-1: (index*`XLEN)];
end
endgenerate
// variable input mux // variable input mux

View File

@ -114,19 +114,17 @@ module icache #(parameter integer LINELEN,
.VictimDirtyWay(), .VictimTagWay(), .VictimDirtyWay(), .VictimTagWay(),
.InvalidateAll(InvalidateICacheM)); .InvalidateAll(InvalidateICacheM));
generate if(NUMWAYS > 1) begin:vict
if(NUMWAYS > 1) begin:vict cachereplacementpolicy #(NUMWAYS, INDEXLEN, OFFSETLEN, NUMLINES)
cachereplacementpolicy #(NUMWAYS, INDEXLEN, OFFSETLEN, NUMLINES) cachereplacementpolicy(.clk, .reset,
cachereplacementpolicy(.clk, .reset, .WayHit,
.WayHit, .VictimWay,
.VictimWay, .LsuPAdrM(PCPF[INDEXLEN+OFFSETLEN-1:OFFSETLEN]),
.LsuPAdrM(PCPF[INDEXLEN+OFFSETLEN-1:OFFSETLEN]), .RAdr,
.RAdr, .LRUWriteEn);
.LRUWriteEn); end else begin:vict
end else begin:vict assign VictimWay = 1'b1; // one hot.
assign VictimWay = 1'b1; // one hot. end
end
endgenerate
assign hit = | WayHit; assign hit = | WayHit;
@ -136,12 +134,9 @@ module icache #(parameter integer LINELEN,
or_rows #(NUMWAYS, LINELEN) ReadDataAOMux(.a(ReadDataLineWayMasked), .y(ReadLineF)); or_rows #(NUMWAYS, LINELEN) ReadDataAOMux(.a(ReadDataLineWayMasked), .y(ReadLineF));
genvar index; genvar index;
generate for(index = 0; index < LINELEN / 16 - 1; index++)
for(index = 0; index < LINELEN / 16 - 1; index++) begin:readlinesetsmux
assign ReadLineSetsF[index] = ReadLineF[((index+1)*16)+16-1 : (index*16)]; assign ReadLineSetsF[index] = ReadLineF[((index+1)*16)+16-1 : (index*16)];
end
assign ReadLineSetsF[LINELEN/16-1] = {16'b0, ReadLineF[LINELEN-1:LINELEN-16]}; assign ReadLineSetsF[LINELEN/16-1] = {16'b0, ReadLineF[LINELEN-1:LINELEN-16]};
endgenerate
assign FinalInstrRawF = ReadLineSetsF[PCPF[$clog2(LINELEN / 32) + 1 : 1]]; assign FinalInstrRawF = ReadLineSetsF[PCPF[$clog2(LINELEN / 32) + 1 : 1]];

View File

@ -56,25 +56,22 @@ module amoalu (
endcase endcase
// sign extend if necessary // sign extend if necessary
generate if (`XLEN == 32) begin:sext
if (`XLEN == 32) begin:sext assign a = srca;
assign a = srca; assign b = srcb;
assign b = srcb; assign result = y;
assign result = y; end else begin:sext // `XLEN = 64
end else begin:sext // `XLEN = 64 always_comb
always_comb if (width == 2'b10) begin // sign-extend word-length operations
if (width == 2'b10) begin // sign-extend word-length operations // *** it would be more efficient to look at carry out of bit 31 to determine comparisons than do this big mux on and b
// *** it would be more efficient to look at carry out of bit 31 to determine comparisons than do this big mux on and b a = {{32{srca[31]}}, srca[31:0]};
a = {{32{srca[31]}}, srca[31:0]}; b = {{32{srcb[31]}}, srcb[31:0]};
b = {{32{srcb[31]}}, srcb[31:0]}; result = {{32{y[31]}}, y[31:0]};
result = {{32{y[31]}}, y[31:0]}; end else begin
end else begin a = srca;
a = srca; b = srcb;
b = srcb; result = y;
result = y; end
end end
end
endgenerate
endmodule endmodule

View File

@ -157,7 +157,7 @@ module cvtfp (
// Result Selection // Result Selection
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
generate if(`IEEE754) begin if(`IEEE754) begin
// select the double to single precision result // select the double to single precision result
assign DSRes = XNaNE ? {XSgnE, {8{1'b1}}, 1'b1, XManE[50:29]} : assign DSRes = XNaNE ? {XSgnE, {8{1'b1}}, 1'b1, XManE[50:29]} :
Underflow & ~Denorm ? {XSgnE, 30'b0, CalcPlus1&(|FrmE[1:0]|Shift)} : Underflow & ~Denorm ? {XSgnE, 30'b0, CalcPlus1&(|FrmE[1:0]|Shift)} :
@ -178,8 +178,6 @@ module cvtfp (
// select the final result based on the opperation // 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}}}; assign CvtFpResE = FmtE ? {{32{1'b1}},DSRes} : {XSgnE&~XNaNE, SDExp, SDFrac[51]|XNaNE, SDFrac[50:0]&{51{~XNaNE}}};
end end
endgenerate
endmodule // fpadd endmodule // fpadd

View File

@ -185,11 +185,9 @@ module csa #(parameter WIDTH=8) (
/* /*
logic [WIDTH:0] carry_temp; logic [WIDTH:0] carry_temp;
genvar i; genvar i;
generate for (i=0;i<WIDTH;i=i+1) begin : genbit
for (i=0;i<WIDTH;i=i+1) begin : genbit
fa fa_inst (a[i], b[i], c[i], sum[i], carry_temp[i+1]); fa fa_inst (a[i], b[i], c[i], sum[i], carry_temp[i+1]);
end end
endgenerate
assign carry = {carry_temp[WIDTH-1:1], 1'b0}; assign carry = {carry_temp[WIDTH-1:1], 1'b0};
*/ */
endmodule // csa endmodule // csa

View File

@ -173,7 +173,7 @@ module fcvt (
// - only set invalid flag for out-of-range vales // - only set invalid flag for out-of-range vales
// - set inexact if in representable range and not exact // - 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 Invalid = (Of | Uf)&FOpCtrlE[0];
assign Inexact = (Guard|Round|Sticky)&~(&FOpCtrlE[1:0]&(XSgnE|Of))&~((Of|Uf)&~FOpCtrlE[1]&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}; 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 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}; assign CvtFlgE = {Invalid&~Inexact, 3'b0, Inexact};
end end
endgenerate
endmodule // fpadd endmodule // fpadd

View File

@ -814,20 +814,17 @@ module resultselect(
); );
logic [`FLEN-1:0] XNaNResult, YNaNResult, ZNaNResult, InvalidResult, OverflowResult, KillProdResult, UnderflowResult; // possible results logic [`FLEN-1:0] XNaNResult, YNaNResult, ZNaNResult, InvalidResult, OverflowResult, KillProdResult, UnderflowResult; // possible results
generate if(`IEEE754) begin
if(`IEEE754) begin:nan
assign XNaNResult = FmtM ? {XSgnM, XExpM, 1'b1, XManM[`NF-2:0]} : {{32{1'b1}}, XSgnM, XExpM[7:0], 1'b1, XManM[50:29]}; assign 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 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 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}; 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 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 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 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}; 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 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}}} : 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}}} : {ResultSgn, {`NE{1'b1}}, {`NF{1'b0}}} :

View File

@ -39,30 +39,28 @@ 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 if (`XLEN==32) begin:shifter // RV32
if (`XLEN==32) begin:shifter // RV32 always_comb // funnel mux
always_comb // funnel mux if (Right)
if (Arith) z = {{31{A[31]}}, A};
else z = {31'b0, A};
else z = {A, 31'b0};
assign amttrunc = Amt; // shift amount
end else begin:shifter // RV64
always_comb // funnel mux
if (W64) begin // 32-bit shifts
if (Right) if (Right)
if (Arith) z = {{31{A[31]}}, A}; if (Arith) z = {64'b0, {31{A[31]}}, A[31:0]};
else z = {31'b0, A}; else z = {95'b0, A[31:0]};
else z = {A, 31'b0}; else z = {32'b0, A[31:0], 63'b0};
assign amttrunc = Amt; // shift amount end else begin
end else begin:shifter // RV64 if (Right)
always_comb // funnel mux if (Arith) z = {{63{A[63]}}, A};
if (W64) begin // 32-bit shifts else z = {63'b0, A};
if (Right) else z = {A, 63'b0};
if (Arith) z = {64'b0, {31{A[31]}}, A[31:0]}; end
else z = {95'b0, A[31:0]}; assign amttrunc = W64 ? {1'b0, Amt[4:0]} : Amt; // 32 or 64-bit shift
else z = {32'b0, A[31:0], 63'b0}; end
end else begin
if (Right)
if (Arith) z = {{63{A[63]}}, A};
else z = {63'b0, A};
else z = {A, 63'b0};
end
assign amttrunc = W64 ? {1'b0, Amt[4:0]} : Amt; // 32 or 64-bit shift
end
// endgenerate
// opposite offset for right shfits // opposite offset for right shfits
assign offset = Right ? amttrunc : ~amttrunc; assign offset = Right ? amttrunc : ~amttrunc;

View File

@ -70,74 +70,72 @@ module bpred
// Part 1 branch direction prediction // Part 1 branch direction prediction
generate if (`BPTYPE == "BPTWOBIT") begin:Predictor
if (`BPTYPE == "BPTWOBIT") begin:Predictor twoBitPredictor DirPredictor(.clk(clk),
twoBitPredictor DirPredictor(.clk(clk), .reset(reset),
.reset(reset), .StallF(StallF),
.StallF(StallF), .LookUpPC(PCNextF),
.LookUpPC(PCNextF), .Prediction(BPPredF),
.Prediction(BPPredF), // update
// update .UpdatePC(PCE),
.UpdatePC(PCE), .UpdateEN(InstrClassE[0] & ~StallE),
.UpdateEN(InstrClassE[0] & ~StallE), .UpdatePrediction(UpdateBPPredE));
.UpdatePrediction(UpdateBPPredE));
end else if (`BPTYPE == "BPGLOBAL") begin:Predictor end else if (`BPTYPE == "BPGLOBAL") begin:Predictor
globalHistoryPredictor DirPredictor(.clk(clk), globalHistoryPredictor DirPredictor(.clk(clk),
.reset(reset), .reset(reset),
.*, // Stalls and flushes .*, // Stalls and flushes
.PCNextF(PCNextF), .PCNextF(PCNextF),
.BPPredF(BPPredF), .BPPredF(BPPredF),
// update // update
.InstrClassE(InstrClassE), .InstrClassE(InstrClassE),
.BPInstrClassE(BPInstrClassE), .BPInstrClassE(BPInstrClassE),
.BPPredDirWrongE(BPPredDirWrongE), .BPPredDirWrongE(BPPredDirWrongE),
.PCE(PCE), .PCE(PCE),
.PCSrcE(PCSrcE), .PCSrcE(PCSrcE),
.UpdateBPPredE(UpdateBPPredE)); .UpdateBPPredE(UpdateBPPredE));
end else if (`BPTYPE == "BPGSHARE") begin:Predictor end else if (`BPTYPE == "BPGSHARE") begin:Predictor
gsharePredictor DirPredictor(.clk(clk), gsharePredictor DirPredictor(.clk(clk),
.reset(reset), .reset(reset),
.*, // Stalls and flushes .*, // Stalls and flushes
.PCNextF(PCNextF), .PCNextF(PCNextF),
.BPPredF(BPPredF), .BPPredF(BPPredF),
// update // update
.InstrClassE(InstrClassE), .InstrClassE(InstrClassE),
.BPInstrClassE(BPInstrClassE), .BPInstrClassE(BPInstrClassE),
.BPPredDirWrongE(BPPredDirWrongE), .BPPredDirWrongE(BPPredDirWrongE),
.PCE(PCE), .PCE(PCE),
.PCSrcE(PCSrcE), .PCSrcE(PCSrcE),
.UpdateBPPredE(UpdateBPPredE)); .UpdateBPPredE(UpdateBPPredE));
end end
else if (`BPTYPE == "BPLOCALPAg") begin:Predictor else if (`BPTYPE == "BPLOCALPAg") begin:Predictor
localHistoryPredictor DirPredictor(.clk(clk), localHistoryPredictor DirPredictor(.clk(clk),
.reset(reset), .reset(reset),
.*, // Stalls and flushes .*, // Stalls and flushes
.LookUpPC(PCNextF), .LookUpPC(PCNextF),
.Prediction(BPPredF), .Prediction(BPPredF),
// update // update
.UpdatePC(PCE), .UpdatePC(PCE),
.UpdateEN(InstrClassE[0] & ~StallE), .UpdateEN(InstrClassE[0] & ~StallE),
.PCSrcE(PCSrcE), .PCSrcE(PCSrcE),
.UpdatePrediction(UpdateBPPredE)); .UpdatePrediction(UpdateBPPredE));
end end
else if (`BPTYPE == "BPLOCALPAg") begin:Predictor else if (`BPTYPE == "BPLOCALPAg") begin:Predictor
localHistoryPredictor DirPredictor(.clk(clk), localHistoryPredictor DirPredictor(.clk(clk),
.reset(reset), .reset(reset),
.*, // Stalls and flushes .*, // Stalls and flushes
.LookUpPC(PCNextF), .LookUpPC(PCNextF),
.Prediction(BPPredF), .Prediction(BPPredF),
// update // update
.UpdatePC(PCE), .UpdatePC(PCE),
.UpdateEN(InstrClassE[0] & ~StallE), .UpdateEN(InstrClassE[0] & ~StallE),
.PCSrcE(PCSrcE), .PCSrcE(PCSrcE),
.UpdatePrediction(UpdateBPPredE)); .UpdatePrediction(UpdateBPPredE));
end end
endgenerate
// this predictor will have two pieces of data, // this predictor will have two pieces of data,

View File

@ -111,7 +111,6 @@ module ifu (
logic [31:0] PostSpillInstrRawF; logic [31:0] PostSpillInstrRawF;
generate
if(`C_SUPPORTED) begin : SpillSupport if(`C_SUPPORTED) begin : SpillSupport
logic [`XLEN-1:0] PCFp2; logic [`XLEN-1:0] PCFp2;
logic Spill; logic Spill;
@ -166,7 +165,6 @@ module ifu (
assign SelNextSpill = 0; assign SelNextSpill = 0;
assign PostSpillInstrRawF = InstrRawF; assign PostSpillInstrRawF = InstrRawF;
end end
endgenerate
assign PCFExt = {2'b00, PCFMux}; assign PCFExt = {2'b00, PCFMux};
@ -235,10 +233,6 @@ module ifu (
logic [`PA_BITS-1:0] ICacheBusAdr; logic [`PA_BITS-1:0] ICacheBusAdr;
logic SelUncachedAdr; logic SelUncachedAdr;
generate
if(`MEM_ICACHE) begin : icache if(`MEM_ICACHE) begin : icache
logic [1:0] IfuRWF; logic [1:0] IfuRWF;
assign IfuRWF = CacheableF ? 2'b10 : 2'b00; assign IfuRWF = CacheableF ? 2'b10 : 2'b00;
@ -280,17 +274,13 @@ module ifu (
.InvalidateCacheM(InvalidateICacheM)); .InvalidateCacheM(InvalidateICacheM));
assign FinalInstrRawF = FinalInstrRawF_FIXME[31:0]; assign FinalInstrRawF = FinalInstrRawF_FIXME[31:0];
end else begin
end else begin : passthrough
assign ICacheFetchLine = 0; assign ICacheFetchLine = 0;
assign ICacheBusAdr = 0; assign ICacheBusAdr = 0;
//assign CompressedF = 0; //? //assign CompressedF = 0; //?
assign ICacheStallF = 0; assign ICacheStallF = 0;
assign FinalInstrRawF = 0; assign FinalInstrRawF = 0;
end end
endgenerate
// select between dcache and direct from the BUS. Always selected if no dcache. // select between dcache and direct from the BUS. Always selected if no dcache.
// handled in the busfsm. // handled in the busfsm.
@ -301,14 +291,12 @@ module ifu (
// always present // always present
genvar index; genvar index;
generate for (index = 0; index < WORDSPERLINE; index++) begin:fetchbuffer
for (index = 0; index < WORDSPERLINE; index++) begin:fetchbuffer flopen #(`XLEN) fb(.clk(clk),
flopen #(`XLEN) fb(.clk(clk), .en(IfuBusAck & IfuBusRead & (index == WordCount)),
.en(IfuBusAck & IfuBusRead & (index == WordCount)), .d(IfuBusHRDATA),
.d(IfuBusHRDATA), .q(ICacheMemWriteData[(index+1)*`XLEN-1:index*`XLEN]));
.q(ICacheMemWriteData[(index+1)*`XLEN-1:index*`XLEN])); end
end
endgenerate
assign LocalIfuBusAdr = SelUncachedAdr ? PCPF : ICacheBusAdr; assign LocalIfuBusAdr = SelUncachedAdr ? PCPF : ICacheBusAdr;
assign IfuBusAdr = ({{`PA_BITS-LOGWPL{1'b0}}, WordCount} << $clog2(`XLEN/8)) + LocalIfuBusAdr; assign IfuBusAdr = ({{`PA_BITS-LOGWPL{1'b0}}, WordCount} << $clog2(`XLEN/8)) + LocalIfuBusAdr;
@ -382,25 +370,23 @@ module ifu (
flopenl #(`XLEN) pcreg(clk, reset, ~StallF & ~ICacheStallF, PCNextF, `RESET_VECTOR, PCF); flopenl #(`XLEN) pcreg(clk, reset, ~StallF & ~ICacheStallF, PCNextF, `RESET_VECTOR, PCF);
// branch and jump predictor // branch and jump predictor
generate if (`BPRED_ENABLED == 1) begin : bpred
if (`BPRED_ENABLED == 1) begin : bpred bpred bpred(.clk, .reset,
bpred bpred(.clk, .reset, .StallF, .StallD, .StallE,
.StallF, .StallD, .StallE, .FlushF, .FlushD, .FlushE,
.FlushF, .FlushD, .FlushE, .PCNextF, .BPPredPCF, .SelBPPredF, .PCE, .PCSrcE, .IEUAdrE,
.PCNextF, .BPPredPCF, .SelBPPredF, .PCE, .PCSrcE, .IEUAdrE, .PCD, .PCLinkE, .InstrClassE, .BPPredWrongE, .BPPredDirWrongE,
.PCD, .PCLinkE, .InstrClassE, .BPPredWrongE, .BPPredDirWrongE, .BTBPredPCWrongE, .RASPredPCWrongE, .BPPredClassNonCFIWrongE);
.BTBPredPCWrongE, .RASPredPCWrongE, .BPPredClassNonCFIWrongE);
end else begin : bpred end else begin : bpred
assign BPPredPCF = {`XLEN{1'b0}}; assign BPPredPCF = {`XLEN{1'b0}};
assign SelBPPredF = 1'b0; assign SelBPPredF = 1'b0;
assign BPPredWrongE = PCSrcE; assign BPPredWrongE = PCSrcE;
assign BPPredDirWrongE = 1'b0; assign BPPredDirWrongE = 1'b0;
assign BTBPredPCWrongE = 1'b0; assign BTBPredPCWrongE = 1'b0;
assign RASPredPCWrongE = 1'b0; assign RASPredPCWrongE = 1'b0;
assign BPPredClassNonCFIWrongE = 1'b0; assign BPPredClassNonCFIWrongE = 1'b0;
end end
endgenerate
// The true correct target is IEUAdrE if PCSrcE is 1 else it is the fall through PCLinkE. // The true correct target is IEUAdrE if PCSrcE is 1 else it is the fall through PCLinkE.
assign PCCorrectE = PCSrcE ? IEUAdrE : PCLinkE; assign PCCorrectE = PCSrcE ? IEUAdrE : PCLinkE;

View File

@ -66,16 +66,10 @@ module localHistoryPredictor
// .BitWEN1(2'b11)); // .BitWEN1(2'b11));
genvar index; genvar index;
generate for (index = 0; index < 2**m; index = index +1) begin:localhist
for (index = 0; index < 2**m; index = index +1) begin:localhist flopenr #(k) LocalHistoryRegister(.clk, .reset, .en(UpdateEN & (index == UpdatePCIndex)),
.d(LHRFNext), .q(LHRNextF[index]));
flopenr #(k) LocalHistoryRegister(.clk(clk), end
.reset(reset),
.en(UpdateEN & (index == UpdatePCIndex)),
.d(LHRFNext),
.q(LHRNextF[index]));
end
endgenerate
// need to forward when updating to the same address as reading. // 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 // first we compare to see if the update and lookup addreses are the same

View File

@ -120,75 +120,73 @@ module lsu
flopenrc #(`XLEN) AddressMReg(clk, reset, FlushM, ~StallM, IEUAdrE, IEUAdrM); flopenrc #(`XLEN) AddressMReg(clk, reset, FlushM, ~StallM, IEUAdrE, IEUAdrM);
assign IEUAdrExtM = {2'b00, IEUAdrM}; assign IEUAdrExtM = {2'b00, IEUAdrM};
generate if(`MEM_VIRTMEM) begin : MEM_VIRTMEM
if(`MEM_VIRTMEM) begin : MEM_VIRTMEM logic AnyCPUReqM;
logic AnyCPUReqM; logic [`PA_BITS-1:0] HPTWAdr;
logic [`PA_BITS-1:0] HPTWAdr; logic HPTWRead;
logic HPTWRead; logic [2:0] HPTWSize;
logic [2:0] HPTWSize; logic SelReplayCPURequest;
logic SelReplayCPURequest;
assign AnyCPUReqM = (|MemRWM) | (|AtomicM); assign AnyCPUReqM = (|MemRWM) | (|AtomicM);
interlockfsm interlockfsm (.clk, .reset, .AnyCPUReqM, .ITLBMissF, .ITLBWriteF, interlockfsm interlockfsm (.clk, .reset, .AnyCPUReqM, .ITLBMissF, .ITLBWriteF,
.DTLBMissM, .DTLBWriteM, .ExceptionM, .PendingInterruptM, .DCacheStall, .DTLBMissM, .DTLBWriteM, .ExceptionM, .PendingInterruptM, .DCacheStall,
.InterlockStall, .SelReplayCPURequest, .SelHPTW, .InterlockStall, .SelReplayCPURequest, .SelHPTW,
.IgnoreRequest); .IgnoreRequest);
hptw hptw(.clk, .reset, .SATP_REGW, .PCF, .IEUAdrM, hptw hptw(.clk, .reset, .SATP_REGW, .PCF, .IEUAdrM,
.ITLBMissF(ITLBMissF & ~PendingInterruptM), .ITLBMissF(ITLBMissF & ~PendingInterruptM),
.DTLBMissM(DTLBMissM & ~PendingInterruptM), .DTLBMissM(DTLBMissM & ~PendingInterruptM),
.MemRWM, .PTE, .PageType, .ITLBWriteF, .DTLBWriteM, .MemRWM, .PTE, .PageType, .ITLBWriteF, .DTLBWriteM,
.HPTWReadPTE(ReadDataM), .HPTWReadPTE(ReadDataM),
.DCacheStall, .HPTWAdr, .HPTWRead, .HPTWSize, .AnyCPUReqM); .DCacheStall, .HPTWAdr, .HPTWRead, .HPTWSize, .AnyCPUReqM);
// arbiter between IEU and hptw // arbiter between IEU and hptw
// multiplex the outputs to LSU // multiplex the outputs to LSU
mux2 #(2) rwmux(MemRWM, {HPTWRead, 1'b0}, SelHPTW, PreLsuRWM); mux2 #(2) rwmux(MemRWM, {HPTWRead, 1'b0}, SelHPTW, PreLsuRWM);
mux2 #(3) sizemux(Funct3M, HPTWSize, SelHPTW, LsuFunct3M); mux2 #(3) sizemux(Funct3M, HPTWSize, SelHPTW, LsuFunct3M);
mux2 #(2) atomicmux(AtomicM, 2'b00, SelHPTW, LsuAtomicM); mux2 #(2) atomicmux(AtomicM, 2'b00, SelHPTW, LsuAtomicM);
mux2 #(12) adremux(IEUAdrE[11:0], HPTWAdr[11:0], SelHPTW, PreLsuAdrE); mux2 #(12) adremux(IEUAdrE[11:0], HPTWAdr[11:0], SelHPTW, PreLsuAdrE);
mux2 #(`PA_BITS) lsupadrmux(IEUAdrExtM[`PA_BITS-1:0], HPTWAdr, SelHPTW, PreLsuPAdrM); mux2 #(`PA_BITS) lsupadrmux(IEUAdrExtM[`PA_BITS-1:0], HPTWAdr, SelHPTW, PreLsuPAdrM);
// always block interrupts when using the hardware page table walker. // always block interrupts when using the hardware page table walker.
assign CPUBusy = StallW & ~SelHPTW; assign CPUBusy = StallW & ~SelHPTW;
// It is not possible to pipeline hptw as the following load will depend on the previous load's // It is not possible to pipeline hptw as the following load will depend on the previous load's
// data. Therefore we don't need a pipeline register // data. Therefore we don't need a pipeline register
//flop #(`PA_BITS) HPTWAdrMReg(clk, HPTWAdr, HPTWAdrM); // delay HPTWAdrM by a cycle //flop #(`PA_BITS) HPTWAdrMReg(clk, HPTWAdr, HPTWAdrM); // delay HPTWAdrM by a cycle
// Specify which type of page fault is occurring // Specify which type of page fault is occurring
assign DTLBLoadPageFaultM = DTLBPageFaultM & PreLsuRWM[1]; assign DTLBLoadPageFaultM = DTLBPageFaultM & PreLsuRWM[1];
assign DTLBStorePageFaultM = DTLBPageFaultM & PreLsuRWM[0]; assign DTLBStorePageFaultM = DTLBPageFaultM & PreLsuRWM[0];
// When replaying CPU memory request after PTW select the IEUAdrM for correct address. // When replaying CPU memory request after PTW select the IEUAdrM for correct address.
assign LsuAdrE = SelReplayCPURequest ? IEUAdrM[11:0] : PreLsuAdrE; assign LsuAdrE = SelReplayCPURequest ? IEUAdrM[11:0] : PreLsuAdrE;
end // if (`MEM_VIRTMEM) end // if (`MEM_VIRTMEM)
else begin else begin
assign InterlockStall = 1'b0; assign InterlockStall = 1'b0;
assign LsuAdrE = PreLsuAdrE; assign LsuAdrE = PreLsuAdrE;
assign SelHPTW = 1'b0; assign SelHPTW = 1'b0;
assign IgnoreRequest = 1'b0; assign IgnoreRequest = 1'b0;
assign PTE = '0; assign PTE = '0;
assign PageType = '0; assign PageType = '0;
assign DTLBWriteM = 1'b0; assign DTLBWriteM = 1'b0;
assign ITLBWriteF = 1'b0; assign ITLBWriteF = 1'b0;
assign PreLsuRWM = MemRWM; assign PreLsuRWM = MemRWM;
assign LsuFunct3M = Funct3M; assign LsuFunct3M = Funct3M;
assign LsuAtomicM = AtomicM; assign LsuAtomicM = AtomicM;
assign PreLsuAdrE = IEUAdrE[11:0]; assign PreLsuAdrE = IEUAdrE[11:0];
assign PreLsuPAdrM = IEUAdrExtM; assign PreLsuPAdrM = IEUAdrExtM;
assign CPUBusy = StallW; assign CPUBusy = StallW;
assign DTLBLoadPageFaultM = 1'b0; assign DTLBLoadPageFaultM = 1'b0;
assign DTLBStorePageFaultM = 1'b0; assign DTLBStorePageFaultM = 1'b0;
end end
endgenerate
// **** look into this confusing signal. // **** look into this confusing signal.
// This signal is confusing. CommittedM tells the CPU's trap unit the current instruction // This signal is confusing. CommittedM tells the CPU's trap unit the current instruction
@ -200,72 +198,66 @@ module lsu
// to flush the memory operation at that time. // to flush the memory operation at that time.
assign CommittedM = SelHPTW | DCacheCommittedM | BusCommittedM; assign CommittedM = SelHPTW | DCacheCommittedM | BusCommittedM;
generate if(`ZICSR_SUPPORTED == 1) begin : dmmu
if(`ZICSR_SUPPORTED == 1) begin : dmmu logic DataMisalignedM;
logic DataMisalignedM;
mmu #(.TLB_ENTRIES(`DTLB_ENTRIES), .IMMU(0)) mmu #(.TLB_ENTRIES(`DTLB_ENTRIES), .IMMU(0))
dmmu(.clk, .reset, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, dmmu(.clk, .reset, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP,
.PrivilegeModeW, .DisableTranslation(SelHPTW), .PrivilegeModeW, .DisableTranslation(SelHPTW),
.PAdr(PreLsuPAdrM), .PAdr(PreLsuPAdrM),
.VAdr(IEUAdrM), .VAdr(IEUAdrM),
.Size(LsuFunct3M[1:0]), .Size(LsuFunct3M[1:0]),
.PTE, .PTE,
.PageTypeWriteVal(PageType), .PageTypeWriteVal(PageType),
.TLBWrite(DTLBWriteM), .TLBWrite(DTLBWriteM),
.TLBFlush(DTLBFlushM), .TLBFlush(DTLBFlushM),
.PhysicalAddress(LsuPAdrM), .PhysicalAddress(LsuPAdrM),
.TLBMiss(DTLBMissM), .TLBMiss(DTLBMissM),
.Cacheable(CacheableM), .Cacheable(CacheableM),
.Idempotent(), .AtomicAllowed(), .Idempotent(), .AtomicAllowed(),
.TLBPageFault(DTLBPageFaultM), .TLBPageFault(DTLBPageFaultM),
.InstrAccessFaultF(), .LoadAccessFaultM, .StoreAccessFaultM, .InstrAccessFaultF(), .LoadAccessFaultM, .StoreAccessFaultM,
.AtomicAccessM(1'b0), .ExecuteAccessF(1'b0), /// atomicaccessm is probably a bug .AtomicAccessM(1'b0), .ExecuteAccessF(1'b0), /// atomicaccessm is probably a bug
.WriteAccessM(PreLsuRWM[0]), .ReadAccessM(PreLsuRWM[1]), .WriteAccessM(PreLsuRWM[0]), .ReadAccessM(PreLsuRWM[1]),
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW
); // *** the pma/pmp instruction access faults don't really matter here. is it possible to parameterize which outputs exist? ); // *** the pma/pmp instruction access faults don't really matter here. is it possible to parameterize which outputs exist?
// Determine if an Unaligned access is taking place // Determine if an Unaligned access is taking place
// hptw guarantees alignment, only check inputs from IEU. // hptw guarantees alignment, only check inputs from IEU.
always_comb always_comb
case(Funct3M[1:0]) case(Funct3M[1:0])
2'b00: DataMisalignedM = 0; // lb, sb, lbu 2'b00: DataMisalignedM = 0; // lb, sb, lbu
2'b01: DataMisalignedM = IEUAdrM[0]; // lh, sh, lhu 2'b01: DataMisalignedM = IEUAdrM[0]; // lh, sh, lhu
2'b10: DataMisalignedM = IEUAdrM[1] | IEUAdrM[0]; // lw, sw, flw, fsw, lwu 2'b10: DataMisalignedM = IEUAdrM[1] | IEUAdrM[0]; // lw, sw, flw, fsw, lwu
2'b11: DataMisalignedM = |IEUAdrM[2:0]; // ld, sd, fld, fsd 2'b11: DataMisalignedM = |IEUAdrM[2:0]; // ld, sd, fld, fsd
endcase endcase
// If the CPU's (not HPTW's) request is a page fault. // If the CPU's (not HPTW's) request is a page fault.
assign LoadMisalignedFaultM = DataMisalignedM & MemRWM[1]; assign LoadMisalignedFaultM = DataMisalignedM & MemRWM[1];
assign StoreMisalignedFaultM = DataMisalignedM & MemRWM[0]; assign StoreMisalignedFaultM = DataMisalignedM & MemRWM[0];
end else begin end else begin
assign LsuPAdrM = PreLsuPAdrM; assign LsuPAdrM = PreLsuPAdrM;
assign DTLBMissM = 0; assign DTLBMissM = 0;
assign CacheableM = 1; assign CacheableM = 1;
assign DTLBPageFaultM = 0; assign DTLBPageFaultM = 0;
assign LoadAccessFaultM = 0; assign LoadAccessFaultM = 0;
assign StoreAccessFaultM = 0; assign StoreAccessFaultM = 0;
assign LoadMisalignedFaultM = 0; assign LoadMisalignedFaultM = 0;
assign StoreMisalignedFaultM = 0; assign StoreMisalignedFaultM = 0;
end end
endgenerate
assign LSUStall = DCacheStall | InterlockStall | BusStall; assign LSUStall = DCacheStall | InterlockStall | BusStall;
// Move generate from lrsc to outside this module.
// use PreLsu as prefix for lrsc // use PreLsu as prefix for lrsc
generate if (`A_SUPPORTED) begin:lrsc
if (`A_SUPPORTED) begin:lrsc assign MemReadM = PreLsuRWM[1] & ~(IgnoreRequest) & ~DTLBMissM;
assign MemReadM = PreLsuRWM[1] & ~(IgnoreRequest) & ~DTLBMissM; lrsc lrsc(.clk, .reset, .FlushW, .CPUBusy, .MemReadM, .PreLsuRWM, .LsuAtomicM, .LsuPAdrM,
lrsc lrsc(.clk, .reset, .FlushW, .CPUBusy, .MemReadM, .PreLsuRWM, .LsuAtomicM, .LsuPAdrM, .SquashSCW, .LsuRWM);
.SquashSCW, .LsuRWM); end else begin:lrsc
end else begin:lrsc assign SquashSCW = 0;
assign SquashSCW = 0; assign LsuRWM = PreLsuRWM;
assign LsuRWM = PreLsuRWM; end
end
endgenerate
// conditional // conditional
@ -304,30 +296,28 @@ module lsu
logic SelUncachedAdr; logic SelUncachedAdr;
generate if(`MEM_DCACHE) begin : dcache
if(`MEM_DCACHE) begin : dcache cache #(.LINELEN(`DCACHE_LINELENINBITS), .NUMLINES(`DCACHE_WAYSIZEINBYTES*8/LINELEN),
cache #(.LINELEN(`DCACHE_LINELENINBITS), .NUMLINES(`DCACHE_WAYSIZEINBYTES*8/LINELEN), .NUMWAYS(`DCACHE_NUMWAYS), .DCACHE(1))
.NUMWAYS(`DCACHE_NUMWAYS), .DCACHE(1)) dcache(.clk, .reset, .CPUBusy,
dcache(.clk, .reset, .CPUBusy, .RW(CacheableM ? LsuRWM : 2'b00), .FlushCache(FlushDCacheM), .Atomic(CacheableM ? LsuAtomicM : 2'b00),
.RW(CacheableM ? LsuRWM : 2'b00), .FlushCache(FlushDCacheM), .Atomic(CacheableM ? LsuAtomicM : 2'b00), .LsuAdrE, .LsuPAdrM, .PreLsuPAdrM(PreLsuPAdrM[11:0]), // still don't like this name PreLsuPAdrM, not always physical
.LsuAdrE, .LsuPAdrM, .PreLsuPAdrM(PreLsuPAdrM[11:0]), // still don't like this name PreLsuPAdrM, not always physical .FinalWriteData(FinalWriteDataM), .ReadDataWord(ReadDataWordM), .CacheStall(DCacheStall),
.FinalWriteData(FinalWriteDataM), .ReadDataWord(ReadDataWordM), .CacheStall(DCacheStall), .CacheMiss(DCacheMiss), .CacheAccess(DCacheAccess),
.CacheMiss(DCacheMiss), .CacheAccess(DCacheAccess), .IgnoreRequest, .CacheCommitted(DCacheCommittedM),
.IgnoreRequest, .CacheCommitted(DCacheCommittedM), .CacheBusAdr(DCacheBusAdr), .ReadDataLineSets(ReadDataLineSetsM), .CacheMemWriteData(DCacheMemWriteData),
.CacheBusAdr(DCacheBusAdr), .ReadDataLineSets(ReadDataLineSetsM), .CacheMemWriteData(DCacheMemWriteData), .CacheFetchLine(DCacheFetchLine), .CacheWriteLine(DCacheWriteLine), .CacheBusAck(DCacheBusAck), .InvalidateCacheM(1'b0));
.CacheFetchLine(DCacheFetchLine), .CacheWriteLine(DCacheWriteLine), .CacheBusAck(DCacheBusAck), .InvalidateCacheM(1'b0)); end else begin : passthrough
end else begin : passthrough assign ReadDataWordM = 0;
assign ReadDataWordM = 0; assign DCacheStall = 0;
assign DCacheStall = 0; assign DCacheMiss = 1;
assign DCacheMiss = 1; assign DCacheAccess = CacheableM;
assign DCacheAccess = CacheableM; assign DCacheCommittedM = 0;
assign DCacheCommittedM = 0; assign DCacheWriteLine = 0;
assign DCacheWriteLine = 0; assign DCacheFetchLine = 0;
assign DCacheFetchLine = 0; assign DCacheBusAdr = 0;
assign DCacheBusAdr = 0; assign ReadDataLineSetsM[0] = 0;
assign ReadDataLineSetsM[0] = 0; end
end
endgenerate
// select between dcache and direct from the BUS. Always selected if no dcache. // select between dcache and direct from the BUS. Always selected if no dcache.
@ -343,15 +333,13 @@ module lsu
.Funct3M(LsuFunct3M), .Funct3M(LsuFunct3M),
.ReadDataM); .ReadDataM);
generate if (`A_SUPPORTED) begin : amo
if (`A_SUPPORTED) begin : amo logic [`XLEN-1:0] AMOResult;
logic [`XLEN-1:0] AMOResult; amoalu amoalu(.srca(ReadDataM), .srcb(WriteDataM), .funct(Funct7M), .width(LsuFunct3M[1:0]),
amoalu amoalu(.srca(ReadDataM), .srcb(WriteDataM), .funct(Funct7M), .width(LsuFunct3M[1:0]), .result(AMOResult));
.result(AMOResult)); mux2 #(`XLEN) wdmux(WriteDataM, AMOResult, LsuAtomicM[1], FinalAMOWriteDataM);
mux2 #(`XLEN) wdmux(WriteDataM, AMOResult, LsuAtomicM[1], FinalAMOWriteDataM); end else
end else assign FinalAMOWriteDataM = WriteDataM;
assign FinalAMOWriteDataM = WriteDataM;
endgenerate
// this might only get instantiated if there is a dcache or dtim. // this might only get instantiated if there is a dcache or dtim.
// There is a copy in the ebu. // There is a copy in the ebu.
@ -368,24 +356,20 @@ module lsu
logic [LOGWPL-1:0] WordCount; logic [LOGWPL-1:0] WordCount;
genvar index; genvar index;
generate for (index = 0; index < WORDSPERLINE; index++) begin:fetchbuffer
for (index = 0; index < WORDSPERLINE; index++) begin:fetchbuffer flopen #(`XLEN) fb(.clk,
flopen #(`XLEN) fb(.clk(clk), .en(LsuBusAck & LsuBusRead & (index == WordCount)),
.en(LsuBusAck & LsuBusRead & (index == WordCount)), .d(LsuBusHRDATA),
.d(LsuBusHRDATA), .q(DCacheMemWriteData[(index+1)*`XLEN-1:index*`XLEN]));
.q(DCacheMemWriteData[(index+1)*`XLEN-1:index*`XLEN])); end
end
endgenerate
assign LocalLsuBusAdr = SelUncachedAdr ? LsuPAdrM : DCacheBusAdr ; assign LocalLsuBusAdr = SelUncachedAdr ? LsuPAdrM : DCacheBusAdr ;
assign LsuBusAdr = ({{`PA_BITS-LOGWPL{1'b0}}, WordCount} << $clog2(`XLEN/8)) + LocalLsuBusAdr; assign LsuBusAdr = ({{`PA_BITS-LOGWPL{1'b0}}, WordCount} << $clog2(`XLEN/8)) + LocalLsuBusAdr;
assign PreLsuBusHWDATA = ReadDataLineSetsM[WordCount]; assign PreLsuBusHWDATA = ReadDataLineSetsM[WordCount];
assign LsuBusHWDATA = SelUncachedAdr ? WriteDataM : PreLsuBusHWDATA; // *** why is this not FinalWriteDataM? which does not work. assign LsuBusHWDATA = SelUncachedAdr ? WriteDataM : PreLsuBusHWDATA; // *** why is this not FinalWriteDataM? which does not work.
generate if (`XLEN == 32) assign LsuBusSize = SelUncachedAdr ? LsuFunct3M : 3'b010;
if (`XLEN == 32) assign LsuBusSize = SelUncachedAdr ? LsuFunct3M : 3'b010; else assign LsuBusSize = SelUncachedAdr ? LsuFunct3M : 3'b011;
else assign LsuBusSize = SelUncachedAdr ? LsuFunct3M : 3'b011;
endgenerate;
busfsm #(WordCountThreshold, LOGWPL, `MEM_DCACHE) busfsm #(WordCountThreshold, LOGWPL, `MEM_DCACHE)
busfsm(.clk, .reset, .IgnoreRequest, .LsuRWM, .DCacheFetchLine, .DCacheWriteLine, busfsm(.clk, .reset, .IgnoreRequest, .LsuRWM, .DCacheFetchLine, .DCacheWriteLine,

View File

@ -49,56 +49,53 @@ module ram #(parameter BASE=0, RANGE = 65535) (
logic memwrite; logic memwrite;
logic [3:0] busycount; logic [3:0] busycount;
generate if(`FPGA) begin:ram
if(`FPGA) begin:ram initial begin
initial begin //$readmemh(PRELOAD, RAM);
//$readmemh(PRELOAD, RAM); RAM[0] = 64'h94e1819300002197;
// FPGA only RAM[1] = 64'h4281420141014081;
RAM[0] = 64'h94e1819300002197; RAM[2] = 64'h4481440143814301;
RAM[1] = 64'h4281420141014081; RAM[3] = 64'h4681460145814501;
RAM[2] = 64'h4481440143814301; RAM[4] = 64'h4881480147814701;
RAM[3] = 64'h4681460145814501; RAM[5] = 64'h4a814a0149814901;
RAM[4] = 64'h4881480147814701; RAM[6] = 64'h4c814c014b814b01;
RAM[5] = 64'h4a814a0149814901; RAM[7] = 64'h4e814e014d814d01;
RAM[6] = 64'h4c814c014b814b01; RAM[8] = 64'h0110011b4f814f01;
RAM[7] = 64'h4e814e014d814d01; RAM[9] = 64'h059b45011161016e;
RAM[8] = 64'h0110011b4f814f01; RAM[10] = 64'h0004063705fe0010;
RAM[9] = 64'h059b45011161016e; RAM[11] = 64'h05a000ef8006061b;
RAM[10] = 64'h0004063705fe0010; RAM[12] = 64'h0ff003930000100f;
RAM[11] = 64'h05a000ef8006061b; RAM[13] = 64'h4e952e3110012e37;
RAM[12] = 64'h0ff003930000100f; RAM[14] = 64'hc602829b0053f2b7;
RAM[13] = 64'h4e952e3110012e37; RAM[15] = 64'h2023fe02dfe312fd;
RAM[14] = 64'hc602829b0053f2b7; RAM[16] = 64'h829b0053f2b7007e;
RAM[15] = 64'h2023fe02dfe312fd; RAM[17] = 64'hfe02dfe312fdc602;
RAM[16] = 64'h829b0053f2b7007e; RAM[18] = 64'h4de31efd000e2023;
RAM[17] = 64'hfe02dfe312fdc602; RAM[19] = 64'h059bf1402573fdd0;
RAM[18] = 64'h4de31efd000e2023; RAM[20] = 64'h0000061705e20870;
RAM[19] = 64'h059bf1402573fdd0; RAM[21] = 64'h0010029b01260613;
RAM[20] = 64'h0000061705e20870; RAM[22] = 64'h11010002806702fe;
RAM[21] = 64'h0010029b01260613; RAM[23] = 64'h84b2842ae426e822;
RAM[22] = 64'h11010002806702fe; RAM[24] = 64'h892ee04aec064505;
RAM[23] = 64'h84b2842ae426e822; RAM[25] = 64'h06e000ef07e000ef;
RAM[24] = 64'h892ee04aec064505; RAM[26] = 64'h979334fd02905563;
RAM[25] = 64'h06e000ef07e000ef; RAM[27] = 64'h07930177d4930204;
RAM[26] = 64'h979334fd02905563; RAM[28] = 64'h4089093394be2004;
RAM[27] = 64'h07930177d4930204; RAM[29] = 64'h04138522008905b3;
RAM[28] = 64'h4089093394be2004; RAM[30] = 64'h19e3014000ef2004;
RAM[29] = 64'h04138522008905b3; RAM[31] = 64'h64a2644260e2fe94;
RAM[30] = 64'h19e3014000ef2004; RAM[32] = 64'h6749808261056902;
RAM[31] = 64'h64a2644260e2fe94; RAM[33] = 64'hdfed8b8510472783;
RAM[32] = 64'h6749808261056902; RAM[34] = 64'h2423479110a73823;
RAM[33] = 64'hdfed8b8510472783; RAM[35] = 64'h10472783674910f7;
RAM[34] = 64'h2423479110a73823; RAM[36] = 64'h20058693ffed8b89;
RAM[35] = 64'h10472783674910f7; RAM[37] = 64'h05a1118737836749;
RAM[36] = 64'h20058693ffed8b89; RAM[38] = 64'hfed59be3fef5bc23;
RAM[37] = 64'h05a1118737836749; RAM[39] = 64'h1047278367498082;
RAM[38] = 64'hfed59be3fef5bc23; RAM[40] = 64'h67c98082dfed8b85;
RAM[39] = 64'h1047278367498082; RAM[41] = 64'h0000808210a7a023;
RAM[40] = 64'h67c98082dfed8b85; end // initial begin
RAM[41] = 64'h0000808210a7a023; end // if (FPGA)
end // initial begin
end // if (FPGA)
endgenerate
assign initTrans = HREADY & HSELRam & (HTRANS != 2'b00); assign initTrans = HREADY & HSELRam & (HTRANS != 2'b00);
@ -144,26 +141,23 @@ module ram #(parameter BASE=0, RANGE = 65535) (
-----/\----- EXCLUDED -----/\----- */ -----/\----- EXCLUDED -----/\----- */
/* verilator lint_off WIDTH */ /* verilator lint_off WIDTH */
generate if (`XLEN == 64) begin:ramrw
if (`XLEN == 64) begin:ramrd always_ff @(posedge HCLK) begin
always_ff @(posedge HCLK) begin HWADDR <= #1 A;
HWADDR <= #1 A; HREADRam0 <= #1 RAM[A[31:3]];
HREADRam0 <= #1 RAM[A[31:3]]; if (memwrite & risingHREADYRam) RAM[HWADDR[31:3]] <= #1 HWDATA;
if (memwrite & risingHREADYRam) RAM[HWADDR[31:3]] <= #1 HWDATA;
end
end else begin
always_ff @(posedge HCLK) begin:ramrd
HWADDR <= #1 A;
HREADRam0 <= #1 RAM[A[31:2]];
if (memwrite & risingHREADYRam) RAM[HWADDR[31:2]] <= #1 HWDATA;
end
end end
endgenerate end else begin
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
/* verilator lint_on WIDTH */ /* verilator lint_on WIDTH */
//assign HREADRam = HREADYRam ? HREADRam0 : `XLEN'bz; //assign HREADRam = HREADYRam ? HREADRam0 : `XLEN'bz;
// *** Ross Thompson: removed tristate as fpga synthesis removes. // *** Ross Thompson: removed tristate as fpga synthesis removes.
assign HREADRam = HREADRam0; assign HREADRam = HREADRam0;
endmodule endmodule

View File

@ -35,75 +35,72 @@ module subwordwrite (
logic [`XLEN-1:0] WriteDataSubwordDuplicated; logic [`XLEN-1:0] WriteDataSubwordDuplicated;
generate if (`XLEN == 64) begin:sww
if (`XLEN == 64) begin:sww logic [7:0] ByteMaskM;
logic [7:0] ByteMaskM; // Compute write mask
// Compute write mask always_comb
always_comb case(HSIZED[1:0])
case(HSIZED[1:0]) 2'b00: begin ByteMaskM = 8'b00000000; ByteMaskM[HADDRD[2:0]] = 1; end // sb
2'b00: begin ByteMaskM = 8'b00000000; ByteMaskM[HADDRD[2:0]] = 1; end // sb 2'b01: case (HADDRD[2:1])
2'b01: case (HADDRD[2:1]) 2'b00: ByteMaskM = 8'b00000011;
2'b00: ByteMaskM = 8'b00000011; 2'b01: ByteMaskM = 8'b00001100;
2'b01: ByteMaskM = 8'b00001100; 2'b10: ByteMaskM = 8'b00110000;
2'b10: ByteMaskM = 8'b00110000; 2'b11: ByteMaskM = 8'b11000000;
2'b11: ByteMaskM = 8'b11000000; endcase
endcase 2'b10: if (HADDRD[2]) ByteMaskM = 8'b11110000;
2'b10: if (HADDRD[2]) ByteMaskM = 8'b11110000; else ByteMaskM = 8'b00001111;
else ByteMaskM = 8'b00001111; 2'b11: ByteMaskM = 8'b11111111;
2'b11: ByteMaskM = 8'b11111111; endcase
endcase
// Handle subword writes // Handle subword writes
always_comb always_comb
case(HSIZED[1:0]) case(HSIZED[1:0])
2'b00: WriteDataSubwordDuplicated = {8{HWDATAIN[7:0]}}; // sb 2'b00: WriteDataSubwordDuplicated = {8{HWDATAIN[7:0]}}; // sb
2'b01: WriteDataSubwordDuplicated = {4{HWDATAIN[15:0]}}; // sh 2'b01: WriteDataSubwordDuplicated = {4{HWDATAIN[15:0]}}; // sh
2'b10: WriteDataSubwordDuplicated = {2{HWDATAIN[31:0]}}; // sw 2'b10: WriteDataSubwordDuplicated = {2{HWDATAIN[31:0]}}; // sw
2'b11: WriteDataSubwordDuplicated = HWDATAIN; // sw 2'b11: WriteDataSubwordDuplicated = HWDATAIN; // sw
endcase endcase
always_comb begin
HWDATA=HRDATA;
if (ByteMaskM[0]) HWDATA[7:0] = WriteDataSubwordDuplicated[7:0];
if (ByteMaskM[1]) HWDATA[15:8] = WriteDataSubwordDuplicated[15:8];
if (ByteMaskM[2]) HWDATA[23:16] = WriteDataSubwordDuplicated[23:16];
if (ByteMaskM[3]) HWDATA[31:24] = WriteDataSubwordDuplicated[31:24];
if (ByteMaskM[4]) HWDATA[39:32] = WriteDataSubwordDuplicated[39:32];
if (ByteMaskM[5]) HWDATA[47:40] = WriteDataSubwordDuplicated[47:40];
if (ByteMaskM[6]) HWDATA[55:48] = WriteDataSubwordDuplicated[55:48];
if (ByteMaskM[7]) HWDATA[63:56] = WriteDataSubwordDuplicated[63:56];
end
end else begin:sww // 32-bit
logic [3:0] ByteMaskM;
// Compute write mask
always_comb
case(HSIZED[1:0])
2'b00: begin ByteMaskM = 4'b0000; ByteMaskM[HADDRD[1:0]] = 1; end // sb
2'b01: if (HADDRD[1]) ByteMaskM = 4'b1100;
else ByteMaskM = 4'b0011;
2'b10: ByteMaskM = 4'b1111;
default: ByteMaskM = 4'b111; // shouldn't happen
endcase
// Handle subword writes
always_comb
case(HSIZED[1:0])
2'b00: WriteDataSubwordDuplicated = {4{HWDATAIN[7:0]}}; // sb
2'b01: WriteDataSubwordDuplicated = {2{HWDATAIN[15:0]}}; // sh
2'b10: WriteDataSubwordDuplicated = HWDATAIN; // sw
default: WriteDataSubwordDuplicated = HWDATAIN; // shouldn't happen
endcase
always_comb begin
HWDATA=HRDATA;
if (ByteMaskM[0]) HWDATA[7:0] = WriteDataSubwordDuplicated[7:0];
if (ByteMaskM[1]) HWDATA[15:8] = WriteDataSubwordDuplicated[15:8];
if (ByteMaskM[2]) HWDATA[23:16] = WriteDataSubwordDuplicated[23:16];
if (ByteMaskM[3]) HWDATA[31:24] = WriteDataSubwordDuplicated[31:24];
end
always_comb begin
HWDATA=HRDATA;
if (ByteMaskM[0]) HWDATA[7:0] = WriteDataSubwordDuplicated[7:0];
if (ByteMaskM[1]) HWDATA[15:8] = WriteDataSubwordDuplicated[15:8];
if (ByteMaskM[2]) HWDATA[23:16] = WriteDataSubwordDuplicated[23:16];
if (ByteMaskM[3]) HWDATA[31:24] = WriteDataSubwordDuplicated[31:24];
if (ByteMaskM[4]) HWDATA[39:32] = WriteDataSubwordDuplicated[39:32];
if (ByteMaskM[5]) HWDATA[47:40] = WriteDataSubwordDuplicated[47:40];
if (ByteMaskM[6]) HWDATA[55:48] = WriteDataSubwordDuplicated[55:48];
if (ByteMaskM[7]) HWDATA[63:56] = WriteDataSubwordDuplicated[63:56];
end end
endgenerate
end else begin:sww // 32-bit
logic [3:0] ByteMaskM;
// Compute write mask
always_comb
case(HSIZED[1:0])
2'b00: begin ByteMaskM = 4'b0000; ByteMaskM[HADDRD[1:0]] = 1; end // sb
2'b01: if (HADDRD[1]) ByteMaskM = 4'b1100;
else ByteMaskM = 4'b0011;
2'b10: ByteMaskM = 4'b1111;
default: ByteMaskM = 4'b111; // shouldn't happen
endcase
// Handle subword writes
always_comb
case(HSIZED[1:0])
2'b00: WriteDataSubwordDuplicated = {4{HWDATAIN[7:0]}}; // sb
2'b01: WriteDataSubwordDuplicated = {2{HWDATAIN[15:0]}}; // sh
2'b10: WriteDataSubwordDuplicated = HWDATAIN; // sw
default: WriteDataSubwordDuplicated = HWDATAIN; // shouldn't happen
endcase
always_comb begin
HWDATA=HRDATA;
if (ByteMaskM[0]) HWDATA[7:0] = WriteDataSubwordDuplicated[7:0];
if (ByteMaskM[1]) HWDATA[15:8] = WriteDataSubwordDuplicated[15:8];
if (ByteMaskM[2]) HWDATA[23:16] = WriteDataSubwordDuplicated[23:16];
if (ByteMaskM[3]) HWDATA[31:24] = WriteDataSubwordDuplicated[31:24];
end
end
endmodule endmodule

View File

@ -54,33 +54,31 @@ module uart (
assign HRESPUART = 0; // OK 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 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
if (`XLEN == 64) begin:uart always_comb begin
always_comb begin HREADUART = {Dout, Dout, Dout, Dout, Dout, Dout, Dout, Dout};
HREADUART = {Dout, Dout, Dout, Dout, Dout, Dout, Dout, Dout}; case (A)
case (A) 3'b000: Din = HWDATA[7:0];
3'b000: Din = HWDATA[7:0]; 3'b001: Din = HWDATA[15:8];
3'b001: Din = HWDATA[15:8]; 3'b010: Din = HWDATA[23:16];
3'b010: Din = HWDATA[23:16]; 3'b011: Din = HWDATA[31:24];
3'b011: Din = HWDATA[31:24]; 3'b100: Din = HWDATA[39:32];
3'b100: Din = HWDATA[39:32]; 3'b101: Din = HWDATA[47:40];
3'b101: Din = HWDATA[47:40]; 3'b110: Din = HWDATA[55:48];
3'b110: Din = HWDATA[55:48]; 3'b111: Din = HWDATA[63:56];
3'b111: Din = HWDATA[63:56]; endcase
endcase
end
end else begin:uart // 32-bit
always_comb begin
HREADUART = {Dout, Dout, Dout, Dout};
case (A[1:0])
2'b00: Din = HWDATA[7:0];
2'b01: Din = HWDATA[15:8];
2'b10: Din = HWDATA[23:16];
2'b11: Din = HWDATA[31:24];
endcase
end
end end
endgenerate end else begin:uart // 32-bit
always_comb begin
HREADUART = {Dout, Dout, Dout, Dout};
case (A[1:0])
2'b00: Din = HWDATA[7:0];
2'b01: Din = HWDATA[15:8];
2'b10: Din = HWDATA[23:16];
2'b11: Din = HWDATA[31:24];
endcase
end
end
logic BAUDOUTb; // loop tx clock BAUDOUTb back to rx clock RCLK 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 // *** make sure reads don't occur on UART unless fully selected because they could change state. This applies to all peripherals

View File

@ -36,7 +36,7 @@
// 4: print memory accesses whenever they happen // 4: print memory accesses whenever they happen
// 5: print everything // 5: print everything
module testbench(); module testbench;
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
/////////////////////////////////// CONFIG //////////////////////////////////// /////////////////////////////////// CONFIG ////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////