mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Merge branch 'main' of https://github.com/davidharrishmc/riscv-wally
This commit is contained in:
commit
fe0c6afe58
@ -59,9 +59,6 @@ module fpu (
|
|||||||
// single stored in a double: | 32 1s | single precision value |
|
// single stored in a double: | 32 1s | single precision value |
|
||||||
// - sets the underflow after rounding
|
// - sets the underflow after rounding
|
||||||
|
|
||||||
// LSU interface
|
|
||||||
logic [`FLEN-1:0] FWriteDataE;
|
|
||||||
|
|
||||||
// control signals
|
// control signals
|
||||||
logic FRegWriteW; // FP register write enable
|
logic FRegWriteW; // FP register write enable
|
||||||
logic [2:0] FrmM; // FP rounding mode
|
logic [2:0] FrmM; // FP rounding mode
|
||||||
@ -291,17 +288,7 @@ module fpu (
|
|||||||
// - FP uses NaN-blocking format
|
// - FP uses NaN-blocking format
|
||||||
// - if there are any unsused bits the most significant bits are filled with 1s
|
// - if there are any unsused bits the most significant bits are filled with 1s
|
||||||
|
|
||||||
if(`FPSIZES == 1) assign FWriteDataE = YE;
|
flopenrc #(`FLEN) FWriteDataMReg (clk, reset, FlushM, ~StallM, YE, FWriteDataM);
|
||||||
else if(`FPSIZES == 2) assign FWriteDataE = FmtE ? YE : {`FLEN/`LEN1{YE[`LEN1-1:0]}};
|
|
||||||
else
|
|
||||||
always_comb
|
|
||||||
case(FmtE)
|
|
||||||
`Q_FMT: FWriteDataE = YE;
|
|
||||||
`D_FMT: FWriteDataE = {`FLEN/`D_LEN{YE[`D_LEN-1:0]}};
|
|
||||||
`S_FMT: FWriteDataE = {`FLEN/`S_LEN{YE[`S_LEN-1:0]}};
|
|
||||||
`H_FMT: FWriteDataE = {`FLEN/`H_LEN{YE[`H_LEN-1:0]}};
|
|
||||||
endcase
|
|
||||||
flopenrc #(`FLEN) FWriteDataMReg (clk, reset, FlushM, ~StallM, FWriteDataE, FWriteDataM);
|
|
||||||
|
|
||||||
// NaN Block SrcA
|
// NaN Block SrcA
|
||||||
generate
|
generate
|
||||||
|
@ -34,15 +34,15 @@ module simpleram #(parameter BASE=0, RANGE = 65535) (
|
|||||||
input logic clk,
|
input logic clk,
|
||||||
input logic [31:0] a,
|
input logic [31:0] a,
|
||||||
input logic we,
|
input logic we,
|
||||||
input logic [`XLEN/8-1:0] ByteMask,
|
input logic [`LLEN/8-1:0] ByteMask,
|
||||||
input logic [`XLEN-1:0] wd,
|
input logic [`LLEN-1:0] wd,
|
||||||
output logic [`XLEN-1:0] rd
|
output logic [`LLEN-1:0] rd
|
||||||
);
|
);
|
||||||
|
|
||||||
localparam ADDR_WDITH = $clog2(RANGE/8);
|
localparam ADDR_WDITH = $clog2(RANGE/8);
|
||||||
localparam OFFSET = $clog2(`XLEN/8);
|
localparam OFFSET = $clog2(`LLEN/8);
|
||||||
|
|
||||||
bram1p1rw #(`XLEN/8, 8, ADDR_WDITH)
|
bram1p1rw #(`LLEN/8, 8, ADDR_WDITH)
|
||||||
memory(.clk, .we, .bwe(ByteMask), .addr(a[ADDR_WDITH+OFFSET-1:OFFSET]), .dout(rd), .din(wd));
|
memory(.clk, .we, .bwe(ByteMask), .addr(a[ADDR_WDITH+OFFSET-1:OFFSET]), .dout(rd), .din(wd));
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
@ -187,7 +187,7 @@ module ifu (
|
|||||||
|
|
||||||
if (`IMEM == `MEM_TIM) begin : irom // *** fix up dtim taking PA_BITS rather than XLEN, *** IEUAdr is a bad name. Probably use a ROM rather than DTIM
|
if (`IMEM == `MEM_TIM) begin : irom // *** fix up dtim taking PA_BITS rather than XLEN, *** IEUAdr is a bad name. Probably use a ROM rather than DTIM
|
||||||
dtim irom(.clk, .reset, .CPUBusy, .LSURWM(2'b10), .IEUAdrM({{(`XLEN-32){1'b0}}, PCPF[31:0]}), .IEUAdrE(PCNextFSpill),
|
dtim irom(.clk, .reset, .CPUBusy, .LSURWM(2'b10), .IEUAdrM({{(`XLEN-32){1'b0}}, PCPF[31:0]}), .IEUAdrE(PCNextFSpill),
|
||||||
.TrapM(1'b0), .FinalWriteDataM(), .ByteMaskM('0),
|
.TrapM(1'b0), .WriteDataM(), .ByteMaskM('0),
|
||||||
.ReadDataWordM({{(`XLEN-32){1'b0}}, FinalInstrRawF}), .BusStall, .LSUBusWrite(), .LSUBusRead(IFUBusRead),
|
.ReadDataWordM({{(`XLEN-32){1'b0}}, FinalInstrRawF}), .BusStall, .LSUBusWrite(), .LSUBusRead(IFUBusRead),
|
||||||
.BusCommittedM(), .DCacheStallM(ICacheStallF), .Cacheable(CacheableF),
|
.BusCommittedM(), .DCacheStallM(ICacheStallF), .Cacheable(CacheableF),
|
||||||
.DCacheCommittedM(), .DCacheMiss(ICacheMiss), .DCacheAccess(ICacheAccess));
|
.DCacheCommittedM(), .DCacheMiss(ICacheMiss), .DCacheAccess(ICacheAccess));
|
||||||
|
@ -34,23 +34,23 @@ module atomic (
|
|||||||
input logic clk,
|
input logic clk,
|
||||||
input logic reset, StallW,
|
input logic reset, StallW,
|
||||||
input logic [`XLEN-1:0] ReadDataM,
|
input logic [`XLEN-1:0] ReadDataM,
|
||||||
input logic [`XLEN-1:0] LSUWriteDataM,
|
input logic [`XLEN-1:0] IMWriteDataM,
|
||||||
input logic [`PA_BITS-1:0] LSUPAdrM,
|
input logic [`PA_BITS-1:0] LSUPAdrM,
|
||||||
input logic [6:0] LSUFunct7M,
|
input logic [6:0] LSUFunct7M,
|
||||||
input logic [2:0] LSUFunct3M,
|
input logic [2:0] LSUFunct3M,
|
||||||
input logic [1:0] LSUAtomicM,
|
input logic [1:0] LSUAtomicM,
|
||||||
input logic [1:0] PreLSURWM,
|
input logic [1:0] PreLSURWM,
|
||||||
input logic IgnoreRequest,
|
input logic IgnoreRequest,
|
||||||
output logic [`XLEN-1:0] AMOWriteDataM,
|
output logic [`XLEN-1:0] IMAWriteDataM,
|
||||||
output logic SquashSCW,
|
output logic SquashSCW,
|
||||||
output logic [1:0] LSURWM);
|
output logic [1:0] LSURWM);
|
||||||
|
|
||||||
logic [`XLEN-1:0] AMOResult;
|
logic [`XLEN-1:0] AMOResult;
|
||||||
logic MemReadM;
|
logic MemReadM;
|
||||||
|
|
||||||
amoalu amoalu(.srca(ReadDataM), .srcb(LSUWriteDataM), .funct(LSUFunct7M), .width(LSUFunct3M[1:0]),
|
amoalu amoalu(.srca(ReadDataM), .srcb(IMWriteDataM), .funct(LSUFunct7M), .width(LSUFunct3M[1:0]),
|
||||||
.result(AMOResult));
|
.result(AMOResult));
|
||||||
mux2 #(`XLEN) wdmux(LSUWriteDataM, AMOResult, LSUAtomicM[1], AMOWriteDataM);
|
mux2 #(`XLEN) wdmux(IMWriteDataM, AMOResult, LSUAtomicM[1], IMAWriteDataM);
|
||||||
assign MemReadM = PreLSURWM[1] & ~IgnoreRequest;
|
assign MemReadM = PreLSURWM[1] & ~IgnoreRequest;
|
||||||
lrsc lrsc(.clk, .reset, .StallW, .MemReadM, .PreLSURWM, .LSUAtomicM, .LSUPAdrM,
|
lrsc lrsc(.clk, .reset, .StallW, .MemReadM, .PreLSURWM, .LSUAtomicM, .LSUPAdrM,
|
||||||
.SquashSCW, .LSURWM);
|
.SquashSCW, .LSURWM);
|
||||||
|
@ -36,10 +36,10 @@ module dtim(
|
|||||||
input logic [`XLEN-1:0] IEUAdrM,
|
input logic [`XLEN-1:0] IEUAdrM,
|
||||||
input logic [`XLEN-1:0] IEUAdrE,
|
input logic [`XLEN-1:0] IEUAdrE,
|
||||||
input logic TrapM,
|
input logic TrapM,
|
||||||
input logic [`XLEN-1:0] FinalWriteDataM,
|
input logic [`LLEN-1:0] WriteDataM,
|
||||||
input logic [`XLEN/8-1:0] ByteMaskM,
|
input logic [`LLEN/8-1:0] ByteMaskM,
|
||||||
input logic Cacheable,
|
input logic Cacheable,
|
||||||
output logic [`XLEN-1:0] ReadDataWordM,
|
output logic [`LLEN-1:0] ReadDataWordM,
|
||||||
output logic BusStall,
|
output logic BusStall,
|
||||||
output logic LSUBusWrite,
|
output logic LSUBusWrite,
|
||||||
output logic LSUBusRead,
|
output logic LSUBusRead,
|
||||||
@ -53,7 +53,7 @@ module dtim(
|
|||||||
.clk, .ByteMask(ByteMaskM),
|
.clk, .ByteMask(ByteMaskM),
|
||||||
.a(CPUBusy | LSURWM[0] | reset ? IEUAdrM[31:0] : IEUAdrE[31:0]), // move mux out; this shouldn't be needed when stails are handled differently ***
|
.a(CPUBusy | LSURWM[0] | reset ? IEUAdrM[31:0] : IEUAdrE[31:0]), // move mux out; this shouldn't be needed when stails are handled differently ***
|
||||||
.we(LSURWM[0] & Cacheable & ~TrapM), // have to ignore write if Trap.
|
.we(LSURWM[0] & Cacheable & ~TrapM), // have to ignore write if Trap.
|
||||||
.wd(FinalWriteDataM), .rd(ReadDataWordM));
|
.wd(WriteDataM), .rd(ReadDataWordM));
|
||||||
|
|
||||||
// since we have a local memory the bus connections are all disabled.
|
// since we have a local memory the bus connections are all disabled.
|
||||||
// There are no peripherals supported.
|
// There are no peripherals supported.
|
||||||
|
@ -110,9 +110,10 @@ module lsu (
|
|||||||
logic BusCommittedM, DCacheCommittedM;
|
logic BusCommittedM, DCacheCommittedM;
|
||||||
logic SelLSUBusWord;
|
logic SelLSUBusWord;
|
||||||
logic DataDAPageFaultM;
|
logic DataDAPageFaultM;
|
||||||
logic [`XLEN-1:0] LSUWriteDataM;
|
logic [`XLEN-1:0] IMWriteDataM, IMAWriteDataM;
|
||||||
|
logic [`LLEN-1:0] IMAFWriteDataM;
|
||||||
logic [`LLEN-1:0] ReadDataM;
|
logic [`LLEN-1:0] ReadDataM;
|
||||||
logic [(`LLEN-1)/8:0] ByteMaskM, FinalByteMaskM;
|
logic [(`LLEN-1)/8:0] ByteMaskM;
|
||||||
|
|
||||||
// *** TO DO: Burst mode
|
// *** TO DO: Burst mode
|
||||||
|
|
||||||
@ -131,7 +132,7 @@ module lsu (
|
|||||||
.TrapM, .DCacheStallM, .SATP_REGW, .PCF,
|
.TrapM, .DCacheStallM, .SATP_REGW, .PCF,
|
||||||
.STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .PrivilegeModeW,
|
.STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .PrivilegeModeW,
|
||||||
.ReadDataM(ReadDataM[`XLEN-1:0]), .WriteDataM, .Funct3M, .LSUFunct3M, .Funct7M, .LSUFunct7M,
|
.ReadDataM(ReadDataM[`XLEN-1:0]), .WriteDataM, .Funct3M, .LSUFunct3M, .Funct7M, .LSUFunct7M,
|
||||||
.IEUAdrExtM, .PTE, .LSUWriteDataM, .PageType, .PreLSURWM, .LSUAtomicM, .IEUAdrE,
|
.IEUAdrExtM, .PTE, .IMWriteDataM, .PageType, .PreLSURWM, .LSUAtomicM, .IEUAdrE,
|
||||||
.LSUAdrE, .PreLSUPAdrM, .CPUBusy, .InterlockStall, .SelHPTW,
|
.LSUAdrE, .PreLSUPAdrM, .CPUBusy, .InterlockStall, .SelHPTW,
|
||||||
.IgnoreRequestTLB);
|
.IgnoreRequestTLB);
|
||||||
end else begin
|
end else begin
|
||||||
@ -140,7 +141,7 @@ module lsu (
|
|||||||
assign LSUAdrE = IEUAdrE[11:0];
|
assign LSUAdrE = IEUAdrE[11:0];
|
||||||
assign PreLSUPAdrM = IEUAdrExtM;
|
assign PreLSUPAdrM = IEUAdrExtM;
|
||||||
assign LSUFunct3M = Funct3M; assign LSUFunct7M = Funct7M; assign LSUAtomicM = AtomicM;
|
assign LSUFunct3M = Funct3M; assign LSUFunct7M = Funct7M; assign LSUAtomicM = AtomicM;
|
||||||
assign LSUWriteDataM = WriteDataM;
|
assign IMWriteDataM = WriteDataM;
|
||||||
end
|
end
|
||||||
|
|
||||||
// CommittedM tells the CPU's privilege unit the current instruction
|
// CommittedM tells the CPU's privilege unit the current instruction
|
||||||
@ -188,8 +189,7 @@ module lsu (
|
|||||||
// Memory System
|
// Memory System
|
||||||
// Either Data Cache or Data Tightly Integrated Memory or just bus interface
|
// Either Data Cache or Data Tightly Integrated Memory or just bus interface
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
logic [`XLEN-1:0] AMOWriteDataM, IEUWriteDataM, LittleEndianWriteDataM;
|
logic [`LLEN-1:0] LSUWriteDataM, LittleEndianWriteDataM;
|
||||||
logic [`LLEN-1:0] FinalWriteDataM;
|
|
||||||
logic [`LLEN-1:0] ReadDataWordM, LittleEndianReadDataWordM;
|
logic [`LLEN-1:0] ReadDataWordM, LittleEndianReadDataWordM;
|
||||||
logic [`LLEN-1:0] ReadDataWordMuxM;
|
logic [`LLEN-1:0] ReadDataWordMuxM;
|
||||||
logic IgnoreRequest;
|
logic IgnoreRequest;
|
||||||
@ -202,7 +202,7 @@ module lsu (
|
|||||||
if (`DMEM == `MEM_TIM) begin : dtim
|
if (`DMEM == `MEM_TIM) begin : dtim
|
||||||
// *** directly instantiate RAM or ROM here. Instantiate SRAM1P1RW.
|
// *** directly instantiate RAM or ROM here. Instantiate SRAM1P1RW.
|
||||||
// Merge SimpleRAM and SRAM1p1rw into one that is good for synthesis and RAM libraries and flops
|
// Merge SimpleRAM and SRAM1p1rw into one that is good for synthesis and RAM libraries and flops
|
||||||
dtim dtim(.clk, .reset, .CPUBusy, .LSURWM, .IEUAdrM, .IEUAdrE, .TrapM, .FinalWriteDataM(IEUWriteDataM), //*** fix the dtim FinalWriteData
|
dtim dtim(.clk, .reset, .CPUBusy, .LSURWM, .IEUAdrM, .IEUAdrE, .TrapM, .WriteDataM(LSUWriteDataM), //*** fix the dtim FinalWriteData
|
||||||
.ReadDataWordM(ReadDataWordM[`XLEN-1:0]), .BusStall, .LSUBusWrite,.LSUBusRead, .BusCommittedM,
|
.ReadDataWordM(ReadDataWordM[`XLEN-1:0]), .BusStall, .LSUBusWrite,.LSUBusRead, .BusCommittedM,
|
||||||
.DCacheStallM, .DCacheCommittedM, .ByteMaskM(ByteMaskM[`XLEN/8-1:0]), .Cacheable(CacheableM),
|
.DCacheStallM, .DCacheCommittedM, .ByteMaskM(ByteMaskM[`XLEN/8-1:0]), .Cacheable(CacheableM),
|
||||||
.DCacheMiss, .DCacheAccess);
|
.DCacheMiss, .DCacheAccess);
|
||||||
@ -230,23 +230,15 @@ module lsu (
|
|||||||
|
|
||||||
mux2 #(`LLEN) UnCachedDataMux(.d0(LittleEndianReadDataWordM), .d1({{`LLEN-`XLEN{1'b0}}, DLSUBusBuffer[`XLEN-1:0]}),
|
mux2 #(`LLEN) UnCachedDataMux(.d0(LittleEndianReadDataWordM), .d1({{`LLEN-`XLEN{1'b0}}, DLSUBusBuffer[`XLEN-1:0]}),
|
||||||
.s(SelUncachedAdr), .y(ReadDataWordMuxM));
|
.s(SelUncachedAdr), .y(ReadDataWordMuxM));
|
||||||
mux2 #(`XLEN) LsuBushwdataMux(.d0(ReadDataWordM[`XLEN-1:0]), .d1(IEUWriteDataM),
|
mux2 #(`XLEN) LsuBushwdataMux(.d0(ReadDataWordM[`XLEN-1:0]), .d1(LSUWriteDataM),
|
||||||
.s(SelUncachedAdr), .y(LSUBusHWDATA));
|
.s(SelUncachedAdr), .y(LSUBusHWDATA));
|
||||||
|
|
||||||
// *** Ross fix up location of mux to be here; remove from IEU datapath
|
|
||||||
// *** look over entire FPU write and read paths
|
|
||||||
// *** Why is
|
|
||||||
if(CACHE_ENABLED) begin : dcache
|
if(CACHE_ENABLED) begin : dcache
|
||||||
if (`F_SUPPORTED)
|
|
||||||
mux2 #(`LLEN) datamux({{`LLEN/`XLEN}{IEUWriteDataM}}, FWriteDataM, FpLoadStoreM, FinalWriteDataM);
|
|
||||||
else
|
|
||||||
assign FinalWriteDataM = IEUWriteDataM;
|
|
||||||
cache #(.LINELEN(`DCACHE_LINELENINBITS), .NUMLINES(`DCACHE_WAYSIZEINBYTES*8/LINELEN),
|
cache #(.LINELEN(`DCACHE_LINELENINBITS), .NUMLINES(`DCACHE_WAYSIZEINBYTES*8/LINELEN),
|
||||||
.NUMWAYS(`DCACHE_NUMWAYS), .LOGBWPL(LOGBWPL), .WORDLEN(`LLEN), .MUXINTERVAL(`XLEN), .DCACHE(1)) dcache(
|
.NUMWAYS(`DCACHE_NUMWAYS), .LOGBWPL(LOGBWPL), .WORDLEN(`LLEN), .MUXINTERVAL(`XLEN), .DCACHE(1)) dcache(
|
||||||
.clk, .reset, .CPUBusy, .SelLSUBusWord, .RW(LSURWM), .Atomic(LSUAtomicM),
|
.clk, .reset, .CPUBusy, .SelLSUBusWord, .RW(LSURWM), .Atomic(LSUAtomicM),
|
||||||
.FlushCache(FlushDCacheM), .NextAdr(LSUAdrE), .PAdr(LSUPAdrM),
|
.FlushCache(FlushDCacheM), .NextAdr(LSUAdrE), .PAdr(LSUPAdrM),
|
||||||
.ByteMask(FinalByteMaskM), .WordCount,
|
.ByteMask(ByteMaskM), .WordCount,
|
||||||
.FinalWriteData(FinalWriteDataM), .Cacheable(CacheableM),
|
.FinalWriteData(LSUWriteDataM), .Cacheable(CacheableM),
|
||||||
.CacheStall(DCacheStallM), .CacheMiss(DCacheMiss), .CacheAccess(DCacheAccess),
|
.CacheStall(DCacheStallM), .CacheMiss(DCacheMiss), .CacheAccess(DCacheAccess),
|
||||||
.IgnoreRequestTLB, .TrapM, .CacheCommitted(DCacheCommittedM),
|
.IgnoreRequestTLB, .TrapM, .CacheCommitted(DCacheCommittedM),
|
||||||
.CacheBusAdr(DCacheBusAdr), .ReadDataWord(ReadDataWordM),
|
.CacheBusAdr(DCacheBusAdr), .ReadDataWord(ReadDataWordM),
|
||||||
@ -266,24 +258,27 @@ module lsu (
|
|||||||
// Atomic operations
|
// Atomic operations
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
if (`A_SUPPORTED) begin:atomic
|
if (`A_SUPPORTED) begin:atomic
|
||||||
atomic atomic(.clk, .reset, .StallW, .ReadDataM(ReadDataM[`XLEN-1:0]), .LSUWriteDataM, .LSUPAdrM,
|
atomic atomic(.clk, .reset, .StallW, .ReadDataM(ReadDataM[`XLEN-1:0]), .IMWriteDataM, .LSUPAdrM,
|
||||||
.LSUFunct7M, .LSUFunct3M, .LSUAtomicM, .PreLSURWM, .IgnoreRequest,
|
.LSUFunct7M, .LSUFunct3M, .LSUAtomicM, .PreLSURWM, .IgnoreRequest,
|
||||||
.AMOWriteDataM, .SquashSCW, .LSURWM);
|
.IMAWriteDataM, .SquashSCW, .LSURWM);
|
||||||
end else begin:lrsc
|
end else begin:lrsc
|
||||||
assign SquashSCW = 0; assign LSURWM = PreLSURWM; assign AMOWriteDataM = LSUWriteDataM;
|
assign SquashSCW = 0; assign LSURWM = PreLSURWM; assign IMAWriteDataM = IMWriteDataM;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if (`F_SUPPORTED)
|
||||||
|
mux2 #(`LLEN) datamux({{{`LLEN-`XLEN}{1'b0}}, IMAWriteDataM}, FWriteDataM, FpLoadStoreM, IMAFWriteDataM);
|
||||||
|
else assign IMAFWriteDataM = IMAWriteDataM;
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Subword Accesses
|
// Subword Accesses
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
subwordread subwordread(.ReadDataWordMuxM, .LSUPAdrM(LSUPAdrM[2:0]),
|
subwordread subwordread(.ReadDataWordMuxM, .LSUPAdrM(LSUPAdrM[2:0]),
|
||||||
.FpLoadStoreM, .Funct3M(LSUFunct3M), .ReadDataM);
|
.FpLoadStoreM, .Funct3M(LSUFunct3M), .ReadDataM);
|
||||||
subwordwrite subwordwrite(.LSUPAdrM(LSUPAdrM[2:0]),
|
subwordwrite subwordwrite(.LSUPAdrM(LSUPAdrM[2:0]),
|
||||||
.LSUFunct3M, .AMOWriteDataM, .LittleEndianWriteDataM);
|
.LSUFunct3M, .IMAFWriteDataM, .LittleEndianWriteDataM);
|
||||||
|
|
||||||
// Compute byte masks
|
// Compute byte masks
|
||||||
swbytemaskword #(`LLEN) swbytemask(.Size(LSUFunct3M), .Adr(LSUPAdrM[$clog2(`LLEN/8)-1:0]), .ByteMask(ByteMaskM));
|
swbytemaskword #(`LLEN) swbytemask(.Size(LSUFunct3M), .Adr(LSUPAdrM[$clog2(`LLEN/8)-1:0]), .ByteMask(ByteMaskM));
|
||||||
assign FinalByteMaskM = ByteMaskM;
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// MW Pipeline Register
|
// MW Pipeline Register
|
||||||
@ -297,10 +292,10 @@ module lsu (
|
|||||||
// swap the bytes when read from big-endian memory
|
// swap the bytes when read from big-endian memory
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
if (`BIGENDIAN_SUPPORTED) begin:endian
|
if (`BIGENDIAN_SUPPORTED) begin:endian
|
||||||
bigendianswap #(`XLEN) storeswap(.BigEndianM, .a(LittleEndianWriteDataM), .y(IEUWriteDataM));
|
bigendianswap #(`LLEN) storeswap(.BigEndianM, .a(LittleEndianWriteDataM), .y(LSUWriteDataM));
|
||||||
bigendianswap #(`LLEN) loadswap(.BigEndianM, .a(ReadDataWordM), .y(LittleEndianReadDataWordM));
|
bigendianswap #(`LLEN) loadswap(.BigEndianM, .a(ReadDataWordM), .y(LittleEndianReadDataWordM));
|
||||||
end else begin
|
end else begin
|
||||||
assign IEUWriteDataM = LittleEndianWriteDataM;
|
assign LSUWriteDataM = LittleEndianWriteDataM;
|
||||||
assign LittleEndianReadDataWordM = ReadDataWordM;
|
assign LittleEndianReadDataWordM = ReadDataWordM;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ module lsuvirtmem(
|
|||||||
output logic [6:0] LSUFunct7M,
|
output logic [6:0] LSUFunct7M,
|
||||||
input logic [`XLEN-1:0] IEUAdrE,
|
input logic [`XLEN-1:0] IEUAdrE,
|
||||||
output logic [`XLEN-1:0] PTE,
|
output logic [`XLEN-1:0] PTE,
|
||||||
output logic [`XLEN-1:0] LSUWriteDataM,
|
output logic [`XLEN-1:0] IMWriteDataM,
|
||||||
output logic [1:0] PageType,
|
output logic [1:0] PageType,
|
||||||
output logic [1:0] PreLSURWM,
|
output logic [1:0] PreLSURWM,
|
||||||
output logic [1:0] LSUAtomicM,
|
output logic [1:0] LSUAtomicM,
|
||||||
@ -112,8 +112,8 @@ module lsuvirtmem(
|
|||||||
mux2 #(12) adremux(IEUAdrE[11:0], HPTWAdr[11:0], SelHPTW, PreLSUAdrE);
|
mux2 #(12) adremux(IEUAdrE[11:0], HPTWAdr[11:0], SelHPTW, PreLSUAdrE);
|
||||||
mux2 #(`XLEN+2) lsupadrmux(IEUAdrExtM, HPTWAdrExt, SelHPTWAdr, PreLSUPAdrM);
|
mux2 #(`XLEN+2) lsupadrmux(IEUAdrExtM, HPTWAdrExt, SelHPTWAdr, PreLSUPAdrM);
|
||||||
if(`HPTW_WRITES_SUPPORTED)
|
if(`HPTW_WRITES_SUPPORTED)
|
||||||
mux2 #(`XLEN) lsuwritedatamux(WriteDataM, PTE, SelHPTW, LSUWriteDataM);
|
mux2 #(`XLEN) lsuwritedatamux(WriteDataM, PTE, SelHPTW, IMWriteDataM);
|
||||||
else assign LSUWriteDataM = WriteDataM;
|
else assign IMWriteDataM = WriteDataM;
|
||||||
mux2 #(12) replaymux(PreLSUAdrE, IEUAdrExtM[11:0], SelReplayMemE, LSUAdrE); // replay cpu request after hptw. *** redudant with mux in cache.
|
mux2 #(12) replaymux(PreLSUAdrE, IEUAdrExtM[11:0], SelReplayMemE, LSUAdrE); // replay cpu request after hptw. *** redudant with mux in cache.
|
||||||
|
|
||||||
// always block interrupts when using the hardware page table walker.
|
// always block interrupts when using the hardware page table walker.
|
||||||
|
@ -33,25 +33,34 @@
|
|||||||
module subwordwrite (
|
module subwordwrite (
|
||||||
input logic [2:0] LSUPAdrM,
|
input logic [2:0] LSUPAdrM,
|
||||||
input logic [2:0] LSUFunct3M,
|
input logic [2:0] LSUFunct3M,
|
||||||
input logic [`XLEN-1:0] AMOWriteDataM,
|
input logic [`LLEN-1:0] IMAFWriteDataM,
|
||||||
output logic [`XLEN-1:0] LittleEndianWriteDataM);
|
output logic [`LLEN-1:0] LittleEndianWriteDataM);
|
||||||
|
|
||||||
// Replicate data for subword writes
|
// Replicate data for subword writes
|
||||||
if (`XLEN == 64) begin:sww
|
if (`LLEN == 128) begin:sww
|
||||||
|
always_comb
|
||||||
|
case(LSUFunct3M[2:0])
|
||||||
|
2'b000: LittleEndianWriteDataM = {16{IMAFWriteDataM[7:0]}}; // sb
|
||||||
|
2'b001: LittleEndianWriteDataM = {8{IMAFWriteDataM[15:0]}}; // sh
|
||||||
|
2'b010: LittleEndianWriteDataM = {4{IMAFWriteDataM[31:0]}}; // sw
|
||||||
|
2'b011: LittleEndianWriteDataM = {2{IMAFWriteDataM[63:0]}}; // sd
|
||||||
|
default: LittleEndianWriteDataM = IMAFWriteDataM; // sq
|
||||||
|
endcase
|
||||||
|
end else if (`LLEN == 64) begin:sww
|
||||||
always_comb
|
always_comb
|
||||||
case(LSUFunct3M[1:0])
|
case(LSUFunct3M[1:0])
|
||||||
2'b00: LittleEndianWriteDataM = {8{AMOWriteDataM[7:0]}}; // sb
|
2'b00: LittleEndianWriteDataM = {8{IMAFWriteDataM[7:0]}}; // sb
|
||||||
2'b01: LittleEndianWriteDataM = {4{AMOWriteDataM[15:0]}}; // sh
|
2'b01: LittleEndianWriteDataM = {4{IMAFWriteDataM[15:0]}}; // sh
|
||||||
2'b10: LittleEndianWriteDataM = {2{AMOWriteDataM[31:0]}}; // sw
|
2'b10: LittleEndianWriteDataM = {2{IMAFWriteDataM[31:0]}}; // sw
|
||||||
2'b11: LittleEndianWriteDataM = AMOWriteDataM; // sw
|
2'b11: LittleEndianWriteDataM = IMAFWriteDataM; // sd
|
||||||
endcase
|
endcase
|
||||||
end else begin:sww // 32-bit
|
end else begin:sww // 32-bit
|
||||||
always_comb
|
always_comb
|
||||||
case(LSUFunct3M[1:0])
|
case(LSUFunct3M[1:0])
|
||||||
2'b00: LittleEndianWriteDataM = {4{AMOWriteDataM[7:0]}}; // sb
|
2'b00: LittleEndianWriteDataM = {4{IMAFWriteDataM[7:0]}}; // sb
|
||||||
2'b01: LittleEndianWriteDataM = {2{AMOWriteDataM[15:0]}}; // sh
|
2'b01: LittleEndianWriteDataM = {2{IMAFWriteDataM[15:0]}}; // sh
|
||||||
2'b10: LittleEndianWriteDataM = AMOWriteDataM; // sw
|
2'b10: LittleEndianWriteDataM = IMAFWriteDataM; // sw
|
||||||
default: LittleEndianWriteDataM = AMOWriteDataM; // shouldn't happen
|
default: LittleEndianWriteDataM = IMAFWriteDataM; // shouldn't happen
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -38,17 +38,17 @@ module adrdecs (
|
|||||||
output logic [8:0] SelRegions
|
output logic [8:0] SelRegions
|
||||||
);
|
);
|
||||||
|
|
||||||
|
localparam logic [3:0] SUPPORTED_SIZE = (`LLEN == 32 ? 4'b0111 : 4'b1111);
|
||||||
// Determine which region of physical memory (if any) is being accessed
|
// Determine which region of physical memory (if any) is being accessed
|
||||||
// *** eventually uncomment Access signals
|
adrdec ddr4dec(PhysicalAddress, `EXT_MEM_BASE, `EXT_MEM_RANGE, `EXT_MEM_SUPPORTED, AccessRWX, Size, SUPPORTED_SIZE, SelRegions[7]);
|
||||||
adrdec ddr4dec(PhysicalAddress, `EXT_MEM_BASE, `EXT_MEM_RANGE, `EXT_MEM_SUPPORTED, AccessRWX, Size, 4'b1111, SelRegions[7]);
|
adrdec boottimdec(PhysicalAddress, `BOOTROM_BASE, `BOOTROM_RANGE, `BOOTROM_SUPPORTED, AccessRX, Size, SUPPORTED_SIZE, SelRegions[6]);
|
||||||
adrdec boottimdec(PhysicalAddress, `BOOTROM_BASE, `BOOTROM_RANGE, `BOOTROM_SUPPORTED, /*1'b1*/AccessRX, Size, 4'b1111, SelRegions[6]);
|
adrdec timdec(PhysicalAddress, `RAM_BASE, `RAM_RANGE, `RAM_SUPPORTED, AccessRWX, Size, SUPPORTED_SIZE, SelRegions[5]);
|
||||||
adrdec timdec(PhysicalAddress, `RAM_BASE, `RAM_RANGE, `RAM_SUPPORTED, /*1'b1*/AccessRWX, Size, 4'b1111, SelRegions[5]);
|
|
||||||
|
|
||||||
adrdec clintdec(PhysicalAddress, `CLINT_BASE, `CLINT_RANGE, `CLINT_SUPPORTED, AccessRW, Size, 4'b1111, SelRegions[4]);
|
adrdec clintdec(PhysicalAddress, `CLINT_BASE, `CLINT_RANGE, `CLINT_SUPPORTED, AccessRW, Size, SUPPORTED_SIZE, SelRegions[4]);
|
||||||
adrdec gpiodec(PhysicalAddress, `GPIO_BASE, `GPIO_RANGE, `GPIO_SUPPORTED, AccessRW, Size, 4'b0100, SelRegions[3]);
|
adrdec gpiodec(PhysicalAddress, `GPIO_BASE, `GPIO_RANGE, `GPIO_SUPPORTED, AccessRW, Size, 4'b0100, SelRegions[3]);
|
||||||
adrdec uartdec(PhysicalAddress, `UART_BASE, `UART_RANGE, `UART_SUPPORTED, AccessRW, Size, 4'b0001, SelRegions[2]);
|
adrdec uartdec(PhysicalAddress, `UART_BASE, `UART_RANGE, `UART_SUPPORTED, AccessRW, Size, 4'b0001, SelRegions[2]);
|
||||||
adrdec plicdec(PhysicalAddress, `PLIC_BASE, `PLIC_RANGE, `PLIC_SUPPORTED, AccessRW, Size, 4'b0100, SelRegions[1]);
|
adrdec plicdec(PhysicalAddress, `PLIC_BASE, `PLIC_RANGE, `PLIC_SUPPORTED, AccessRW, Size, 4'b0100, SelRegions[1]);
|
||||||
adrdec sdcdec(PhysicalAddress, `SDC_BASE, `SDC_RANGE, `SDC_SUPPORTED, AccessRW, Size, 4'b1100, SelRegions[0]); // *** PMA chapter says xlen only like CLINT
|
adrdec sdcdec(PhysicalAddress, `SDC_BASE, `SDC_RANGE, `SDC_SUPPORTED, AccessRW, Size, SUPPORTED_SIZE & 4'b1100, SelRegions[0]);
|
||||||
|
|
||||||
assign SelRegions[8] = ~|(SelRegions[7:0]);
|
assign SelRegions[8] = ~|(SelRegions[7:0]);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user