mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Removed more generate statements
This commit is contained in:
parent
f04856ee94
commit
32590d484c
@ -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;
|
||||||
|
@ -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) (
|
||||||
|
153
pipelined/src/cache/cachereplacementpolicy.sv
vendored
153
pipelined/src/cache/cachereplacementpolicy.sv
vendored
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
51
pipelined/src/cache/cacheway.sv
vendored
51
pipelined/src/cache/cacheway.sv
vendored
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
31
pipelined/src/cache/dcache.sv
vendored
31
pipelined/src/cache/dcache.sv
vendored
@ -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
|
||||||
|
|
||||||
|
29
pipelined/src/cache/icache.sv
vendored
29
pipelined/src/cache/icache.sv
vendored
@ -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]];
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
@ -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}}} :
|
||||||
|
@ -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;
|
||||||
|
@ -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,
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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,
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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 ////////////////////////////////////
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
Loading…
Reference in New Issue
Block a user