mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
ebu cleanup
This commit is contained in:
parent
b4dd7b21e6
commit
17fd2d2a3b
@ -94,10 +94,11 @@ module ahbcacheinterface #(parameter BEATSPERLINE, LINELEN, LOGWPL, CACHE_ENABLE
|
|||||||
logic [`AHBW-1:0] AHBWordSets [(LLENPOVERAHBW)-1:0];
|
logic [`AHBW-1:0] AHBWordSets [(LLENPOVERAHBW)-1:0];
|
||||||
genvar index;
|
genvar index;
|
||||||
for (index = 0; index < LLENPOVERAHBW; index++) begin:readdatalinesetsmux
|
for (index = 0; index < LLENPOVERAHBW; index++) begin:readdatalinesetsmux
|
||||||
assign AHBWordSets[index] = CacheReadDataWordM[(index*`AHBW)+`AHBW-1: (index*`AHBW)];
|
assign AHBWordSets[index] = CacheReadDataWordM[(index*`AHBW)+`AHBW-1: (index*`AHBW)];
|
||||||
end
|
end
|
||||||
assign CacheReadDataWordAHB = AHBWordSets[BeatCount[$clog2(LLENPOVERAHBW)-1:0]];
|
assign CacheReadDataWordAHB = AHBWordSets[BeatCount[$clog2(LLENPOVERAHBW)-1:0]];
|
||||||
end else assign CacheReadDataWordAHB = CacheReadDataWordM[`AHBW-1:0];
|
end else assign CacheReadDataWordAHB = CacheReadDataWordM[`AHBW-1:0];
|
||||||
|
|
||||||
mux2 #(`AHBW) HWDATAMux(.d0(CacheReadDataWordAHB), .d1(WriteDataM[`AHBW-1:0]),
|
mux2 #(`AHBW) HWDATAMux(.d0(CacheReadDataWordAHB), .d1(WriteDataM[`AHBW-1:0]),
|
||||||
.s(~(CacheableOrFlushCacheM)), .y(PreHWDATA));
|
.s(~(CacheableOrFlushCacheM)), .y(PreHWDATA));
|
||||||
flopen #(`AHBW) wdreg(HCLK, HREADY, PreHWDATA, HWDATA); // delay HWDATA by 1 cycle per spec
|
flopen #(`AHBW) wdreg(HCLK, HREADY, PreHWDATA, HWDATA); // delay HWDATA by 1 cycle per spec
|
||||||
@ -109,9 +110,8 @@ module ahbcacheinterface #(parameter BEATSPERLINE, LINELEN, LOGWPL, CACHE_ENABLE
|
|||||||
|
|
||||||
flopen #(`AHBW/8) HWSTRBReg(HCLK, HREADY, BusByteMaskM[`AHBW/8-1:0], HWSTRB);
|
flopen #(`AHBW/8) HWSTRBReg(HCLK, HREADY, BusByteMaskM[`AHBW/8-1:0], HWSTRB);
|
||||||
|
|
||||||
|
|
||||||
buscachefsm #(BeatCountThreshold, LOGWPL) AHBBuscachefsm(
|
buscachefsm #(BeatCountThreshold, LOGWPL) AHBBuscachefsm(
|
||||||
.HCLK, .HRESETn, .Flush, .BusRW, .Stall, .BusCommitted, .BusStall, .CaptureEn, .SelBusBeat,
|
.HCLK, .HRESETn, .Flush, .BusRW, .Stall, .BusCommitted, .BusStall, .CaptureEn, .SelBusBeat,
|
||||||
.CacheBusRW, .CacheBusAck, .BeatCount, .BeatCountDelayed,
|
.CacheBusRW, .CacheBusAck, .BeatCount, .BeatCountDelayed,
|
||||||
.HREADY, .HTRANS, .HWRITE, .HBURST);
|
.HREADY, .HTRANS, .HWRITE, .HBURST);
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -30,10 +30,8 @@
|
|||||||
|
|
||||||
`include "wally-config.vh"
|
`include "wally-config.vh"
|
||||||
|
|
||||||
module ahbinterface #(parameter LSU = 0) // **** modify to use LSU/ifu parameter to control widths of buses
|
module ahbinterface #(parameter LSU = 0) ( // **** modify to use LSU/ifu parameter to control widths of buses
|
||||||
(
|
|
||||||
input logic HCLK, HRESETn,
|
input logic HCLK, HRESETn,
|
||||||
|
|
||||||
// bus interface
|
// bus interface
|
||||||
input logic HREADY,
|
input logic HREADY,
|
||||||
input logic [`XLEN-1:0] HRDATA,
|
input logic [`XLEN-1:0] HRDATA,
|
||||||
@ -50,18 +48,18 @@ module ahbinterface #(parameter LSU = 0) // **** modify to use LSU/ifu parameter
|
|||||||
input logic Stall,
|
input logic Stall,
|
||||||
output logic BusStall,
|
output logic BusStall,
|
||||||
output logic BusCommitted,
|
output logic BusCommitted,
|
||||||
output logic [(LSU ? `XLEN : 32)-1:0] FetchBuffer);
|
output logic [(LSU ? `XLEN : 32)-1:0] FetchBuffer
|
||||||
|
);
|
||||||
|
|
||||||
logic CaptureEn;
|
logic CaptureEn;
|
||||||
|
|
||||||
/// *** only 32 bit for IFU.
|
localparam LEN = (LSU ? `XLEN : 32); // 32 bits for IFU, XLEN for LSU
|
||||||
localparam LEN = (LSU ? `XLEN : 32);
|
|
||||||
|
|
||||||
flopen #(LEN) fb(.clk(HCLK), .en(CaptureEn), .d(HRDATA[LEN-1:0]), .q(FetchBuffer));
|
flopen #(LEN) fb(.clk(HCLK), .en(CaptureEn), .d(HRDATA[LEN-1:0]), .q(FetchBuffer));
|
||||||
|
|
||||||
if(LSU) begin
|
if(LSU) begin
|
||||||
// delay HWDATA by 1 cycle per spec; *** assumes AHBW = XLEN
|
// delay HWDATA by 1 cycle per spec; assumes AHBW = XLEN
|
||||||
flop #(`XLEN) wdreg(HCLK, WriteData, HWDATA);
|
flop #(`XLEN) wdreg(HCLK, WriteData, HWDATA);
|
||||||
flop #(`XLEN/8) HWSTRBReg(HCLK, ByteMask, HWSTRB);
|
flop #(`XLEN/8) HWSTRBReg(HCLK, ByteMask, HWSTRB);
|
||||||
end else begin
|
end else begin
|
||||||
assign HWDATA = '0;
|
assign HWDATA = '0;
|
||||||
|
@ -32,28 +32,26 @@ module amoalu (
|
|||||||
input logic [`XLEN-1:0] srca, srcb,
|
input logic [`XLEN-1:0] srca, srcb,
|
||||||
input logic [6:0] funct,
|
input logic [6:0] funct,
|
||||||
input logic [1:0] width,
|
input logic [1:0] width,
|
||||||
output logic [`XLEN-1:0] result);
|
output logic [`XLEN-1:0] result
|
||||||
|
);
|
||||||
|
|
||||||
logic [`XLEN-1:0] a, b, y;
|
logic [`XLEN-1:0] a, b, y;
|
||||||
|
|
||||||
// *** can this be muxed into the regular ALU to avoid needing a second one? Only a good
|
|
||||||
// idea if the regular ALU is not the critical path
|
|
||||||
|
|
||||||
// *** see how synthesis generates this and optimize more structurally if necessary to share hardware
|
// *** see how synthesis generates this and optimize more structurally if necessary to share hardware
|
||||||
// a single carry chain should be shared for + and the four min/max
|
// a single carry chain should be shared for + and the four min/max
|
||||||
// and the same mux can be used to select b for swap.
|
// and the same mux can be used to select b for swap.
|
||||||
always_comb
|
always_comb
|
||||||
case (funct[6:2])
|
case (funct[6:2])
|
||||||
5'b00001: y = b; // amoswap
|
5'b00001: y = b; // amoswap
|
||||||
5'b00000: y = a + b; // amoadd
|
5'b00000: y = a + b; // amoadd
|
||||||
5'b00100: y = a ^ b; // amoxor
|
5'b00100: y = a ^ b; // amoxor
|
||||||
5'b01100: y = a & b; // amoand
|
5'b01100: y = a & b; // amoand
|
||||||
5'b01000: y = a | b; // amoor
|
5'b01000: y = a | b; // amoor
|
||||||
5'b10000: y = ($signed(a) < $signed(b)) ? a : b; // amomin
|
5'b10000: y = ($signed(a) < $signed(b)) ? a : b; // amomin
|
||||||
5'b10100: y = ($signed(a) >= $signed(b)) ? a : b; // amomax
|
5'b10100: y = ($signed(a) >= $signed(b)) ? a : b; // amomax
|
||||||
5'b11000: y = ($unsigned(a) < $unsigned(b)) ? a : b; // amominu
|
5'b11000: y = ($unsigned(a) < $unsigned(b)) ? a : b; // amominu
|
||||||
5'b11100: y = ($unsigned(a) >= $unsigned(b)) ? a : b; // amomaxu
|
5'b11100: y = ($unsigned(a) >= $unsigned(b)) ? a : b; // amomaxu
|
||||||
default: y = `XLEN'bx; // undefined; *** could change to b for efficiency
|
default: y = `XLEN'bx; // undefined; *** could change to b for efficiency
|
||||||
endcase
|
endcase
|
||||||
|
|
||||||
// sign extend if necessary
|
// sign extend if necessary
|
||||||
@ -64,7 +62,6 @@ module amoalu (
|
|||||||
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
|
|
||||||
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]};
|
||||||
|
@ -28,39 +28,34 @@
|
|||||||
`define BURST_EN 1
|
`define BURST_EN 1
|
||||||
|
|
||||||
// HCLK and clk must be the same clock!
|
// HCLK and clk must be the same clock!
|
||||||
module buscachefsm #(parameter integer BeatCountThreshold, parameter integer LOGWPL)
|
module buscachefsm #(parameter integer BeatCountThreshold, LOGWPL) (
|
||||||
(input logic HCLK,
|
input logic HCLK,
|
||||||
input logic HRESETn,
|
input logic HRESETn,
|
||||||
|
|
||||||
// IEU interface
|
// IEU interface
|
||||||
input logic Flush,
|
input logic Flush,
|
||||||
input logic [1:0] BusRW,
|
input logic [1:0] BusRW,
|
||||||
input logic Stall,
|
input logic Stall,
|
||||||
output logic BusCommitted,
|
output logic BusCommitted,
|
||||||
output logic BusStall,
|
output logic BusStall,
|
||||||
output logic CaptureEn,
|
output logic CaptureEn,
|
||||||
|
|
||||||
// cache interface
|
// cache interface
|
||||||
input logic [1:0] CacheBusRW,
|
input logic [1:0] CacheBusRW,
|
||||||
output logic CacheBusAck,
|
output logic CacheBusAck,
|
||||||
|
|
||||||
// lsu interface
|
// lsu interface
|
||||||
output logic [LOGWPL-1:0] BeatCount, BeatCountDelayed,
|
output logic [LOGWPL-1:0] BeatCount, BeatCountDelayed,
|
||||||
output logic SelBusBeat,
|
output logic SelBusBeat,
|
||||||
|
|
||||||
// BUS interface
|
// BUS interface
|
||||||
input logic HREADY,
|
input logic HREADY,
|
||||||
output logic [1:0] HTRANS,
|
output logic [1:0] HTRANS,
|
||||||
output logic HWRITE,
|
output logic HWRITE,
|
||||||
output logic [2:0] HBURST
|
output logic [2:0] HBURST
|
||||||
);
|
);
|
||||||
|
|
||||||
typedef enum logic [2:0] {ADR_PHASE,
|
typedef enum logic [2:0] {ADR_PHASE, DATA_PHASE, MEM3, CACHE_FETCH, CACHE_WRITEBACK} busstatetype;
|
||||||
DATA_PHASE,
|
|
||||||
MEM3,
|
|
||||||
CACHE_FETCH,
|
|
||||||
CACHE_WRITEBACK} busstatetype;
|
|
||||||
|
|
||||||
typedef enum logic [1:0] {AHB_IDLE = 2'b00, AHB_BUSY = 2'b01, AHB_NONSEQ = 2'b10, AHB_SEQ = 2'b11} ahbtranstype;
|
typedef enum logic [1:0] {AHB_IDLE = 2'b00, AHB_BUSY = 2'b01, AHB_NONSEQ = 2'b10, AHB_SEQ = 2'b11} ahbtranstype;
|
||||||
|
|
||||||
(* mark_debug = "true" *) busstatetype CurrState, NextState;
|
(* mark_debug = "true" *) busstatetype CurrState, NextState;
|
||||||
@ -77,42 +72,31 @@ module buscachefsm #(parameter integer BeatCountThreshold, parameter integer LOG
|
|||||||
else CurrState <= #1 NextState;
|
else CurrState <= #1 NextState;
|
||||||
|
|
||||||
always_comb begin
|
always_comb begin
|
||||||
case(CurrState)
|
case(CurrState)
|
||||||
ADR_PHASE: if(HREADY & |BusRW) NextState = DATA_PHASE;
|
ADR_PHASE: if (HREADY & |BusRW) NextState = DATA_PHASE;
|
||||||
else if (HREADY & CacheBusRW[0]) NextState = CACHE_WRITEBACK;
|
else if (HREADY & CacheBusRW[0]) NextState = CACHE_WRITEBACK;
|
||||||
else if (HREADY & CacheBusRW[1]) NextState = CACHE_FETCH;
|
else if (HREADY & CacheBusRW[1]) NextState = CACHE_FETCH;
|
||||||
else NextState = ADR_PHASE;
|
else NextState = ADR_PHASE;
|
||||||
DATA_PHASE: if(HREADY) NextState = MEM3;
|
DATA_PHASE: if(HREADY) NextState = MEM3;
|
||||||
else NextState = DATA_PHASE;
|
else NextState = DATA_PHASE;
|
||||||
MEM3: if(Stall) NextState = MEM3;
|
MEM3: if(Stall) NextState = MEM3;
|
||||||
else NextState = ADR_PHASE;
|
else NextState = ADR_PHASE;
|
||||||
CACHE_FETCH: if(HREADY & FinalBeatCount & CacheBusRW[0]) NextState = CACHE_WRITEBACK;
|
CACHE_FETCH: if(HREADY & FinalBeatCount & CacheBusRW[0]) NextState = CACHE_WRITEBACK;
|
||||||
else if(HREADY & FinalBeatCount & CacheBusRW[1]) NextState = CACHE_FETCH;
|
else if(HREADY & FinalBeatCount & CacheBusRW[1]) NextState = CACHE_FETCH;
|
||||||
else if(HREADY & FinalBeatCount & ~|CacheBusRW) NextState = ADR_PHASE;
|
else if(HREADY & FinalBeatCount & ~|CacheBusRW) NextState = ADR_PHASE;
|
||||||
else NextState = CACHE_FETCH;
|
else NextState = CACHE_FETCH;
|
||||||
CACHE_WRITEBACK: if(HREADY & FinalBeatCount & CacheBusRW[0]) NextState = CACHE_WRITEBACK;
|
CACHE_WRITEBACK: if(HREADY & FinalBeatCount & CacheBusRW[0]) NextState = CACHE_WRITEBACK;
|
||||||
else if(HREADY & FinalBeatCount & CacheBusRW[1]) NextState = CACHE_FETCH;
|
else if(HREADY & FinalBeatCount & CacheBusRW[1]) NextState = CACHE_FETCH;
|
||||||
else if(HREADY & FinalBeatCount & ~|CacheBusRW) NextState = ADR_PHASE;
|
else if(HREADY & FinalBeatCount & ~|CacheBusRW) NextState = ADR_PHASE;
|
||||||
else NextState = CACHE_WRITEBACK;
|
else NextState = CACHE_WRITEBACK;
|
||||||
default: NextState = ADR_PHASE;
|
default: NextState = ADR_PHASE;
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
|
|
||||||
// IEU, LSU, and IFU controls
|
// IEU, LSU, and IFU controls
|
||||||
flopenr #(LOGWPL)
|
|
||||||
BeatCountReg(.clk(HCLK),
|
|
||||||
.reset(~HRESETn | BeatCntReset),
|
|
||||||
.en(BeatCntEn),
|
|
||||||
.d(NextBeatCount),
|
|
||||||
.q(BeatCount));
|
|
||||||
|
|
||||||
// Used to store data from data phase of AHB.
|
// Used to store data from data phase of AHB.
|
||||||
flopenr #(LOGWPL)
|
flopenr #(LOGWPL) BeatCountReg(HCLK, ~HRESETn | BeatCntReset, BeatCntEn, NextBeatCount, BeatCount);
|
||||||
BeatCountDelayedReg(.clk(HCLK),
|
flopenr #(LOGWPL) BeatCountDelayedReg(HCLK, ~HRESETn | BeatCntReset, BeatCntEn, BeatCount, BeatCountDelayed);
|
||||||
.reset(~HRESETn | BeatCntReset),
|
|
||||||
.en(BeatCntEn),
|
|
||||||
.d(BeatCount),
|
|
||||||
.q(BeatCountDelayed));
|
|
||||||
assign NextBeatCount = BeatCount + 1'b1;
|
assign NextBeatCount = BeatCount + 1'b1;
|
||||||
|
|
||||||
assign FinalBeatCount = BeatCountDelayed == BeatCountThreshold[LOGWPL-1:0];
|
assign FinalBeatCount = BeatCountDelayed == BeatCountThreshold[LOGWPL-1:0];
|
||||||
@ -124,10 +108,10 @@ module buscachefsm #(parameter integer BeatCountThreshold, parameter integer LOG
|
|||||||
assign CacheAccess = CurrState == CACHE_FETCH | CurrState == CACHE_WRITEBACK;
|
assign CacheAccess = CurrState == CACHE_FETCH | CurrState == CACHE_WRITEBACK;
|
||||||
|
|
||||||
assign BusStall = (CurrState == ADR_PHASE & (|BusRW | |CacheBusRW)) |
|
assign BusStall = (CurrState == ADR_PHASE & (|BusRW | |CacheBusRW)) |
|
||||||
//(CurrState == DATA_PHASE & ~BusRW[0]) | // replace the next line with this. Fails uart test but i think it's a test problem not a hardware problem.
|
//(CurrState == DATA_PHASE & ~BusRW[0]) | // *** replace the next line with this. Fails uart test but i think it's a test problem not a hardware problem.
|
||||||
(CurrState == DATA_PHASE) |
|
(CurrState == DATA_PHASE) |
|
||||||
(CurrState == CACHE_FETCH & ~HREADY) |
|
(CurrState == CACHE_FETCH & ~HREADY) |
|
||||||
(CurrState == CACHE_WRITEBACK & ~HREADY);
|
(CurrState == CACHE_WRITEBACK & ~HREADY);
|
||||||
assign BusCommitted = CurrState != ADR_PHASE;
|
assign BusCommitted = CurrState != ADR_PHASE;
|
||||||
|
|
||||||
// AHB bus interface
|
// AHB bus interface
|
||||||
@ -151,7 +135,7 @@ module buscachefsm #(parameter integer BeatCountThreshold, parameter integer LOG
|
|||||||
// communication to cache
|
// communication to cache
|
||||||
assign CacheBusAck = (CacheAccess & HREADY & FinalBeatCount);
|
assign CacheBusAck = (CacheAccess & HREADY & FinalBeatCount);
|
||||||
assign SelBusBeat = (CurrState == ADR_PHASE & (BusRW[0] | CacheBusRW[0])) |
|
assign SelBusBeat = (CurrState == ADR_PHASE & (BusRW[0] | CacheBusRW[0])) |
|
||||||
(CurrState == DATA_PHASE & BusRW[0]) |
|
(CurrState == DATA_PHASE & BusRW[0]) |
|
||||||
(CurrState == CACHE_WRITEBACK) |
|
(CurrState == CACHE_WRITEBACK) |
|
||||||
(CurrState == CACHE_FETCH);
|
(CurrState == CACHE_FETCH);
|
||||||
|
|
||||||
|
@ -27,26 +27,23 @@
|
|||||||
`include "wally-config.vh"
|
`include "wally-config.vh"
|
||||||
|
|
||||||
// HCLK and clk must be the same clock!
|
// HCLK and clk must be the same clock!
|
||||||
module busfsm
|
module busfsm (
|
||||||
(input logic HCLK,
|
input logic HCLK,
|
||||||
input logic HRESETn,
|
input logic HRESETn,
|
||||||
|
|
||||||
// IEU interface
|
// IEU interface
|
||||||
input logic Flush,
|
input logic Flush,
|
||||||
input logic [1:0] BusRW,
|
input logic [1:0] BusRW,
|
||||||
input logic Stall,
|
input logic Stall,
|
||||||
output logic BusCommitted,
|
output logic BusCommitted,
|
||||||
output logic BusStall,
|
output logic BusStall,
|
||||||
output logic CaptureEn,
|
output logic CaptureEn,
|
||||||
input logic HREADY,
|
input logic HREADY,
|
||||||
output logic [1:0] HTRANS,
|
output logic [1:0] HTRANS,
|
||||||
output logic HWRITE
|
output logic HWRITE
|
||||||
);
|
);
|
||||||
|
|
||||||
typedef enum logic [2:0] {ADR_PHASE,
|
typedef enum logic [2:0] {ADR_PHASE, DATA_PHASE, MEM3} busstatetype;
|
||||||
DATA_PHASE,
|
|
||||||
MEM3} busstatetype;
|
|
||||||
|
|
||||||
typedef enum logic [1:0] {AHB_IDLE = 2'b00, AHB_BUSY = 2'b01, AHB_NONSEQ = 2'b10, AHB_SEQ = 2'b11} ahbtranstype;
|
typedef enum logic [1:0] {AHB_IDLE = 2'b00, AHB_BUSY = 2'b01, AHB_NONSEQ = 2'b10, AHB_SEQ = 2'b11} ahbtranstype;
|
||||||
|
|
||||||
(* mark_debug = "true" *) busstatetype CurrState, NextState;
|
(* mark_debug = "true" *) busstatetype CurrState, NextState;
|
||||||
@ -56,15 +53,15 @@ module busfsm
|
|||||||
else CurrState <= #1 NextState;
|
else CurrState <= #1 NextState;
|
||||||
|
|
||||||
always_comb begin
|
always_comb begin
|
||||||
case(CurrState)
|
case(CurrState)
|
||||||
ADR_PHASE: if(HREADY & |BusRW) NextState = DATA_PHASE;
|
ADR_PHASE: if(HREADY & |BusRW) NextState = DATA_PHASE;
|
||||||
else NextState = ADR_PHASE;
|
else NextState = ADR_PHASE;
|
||||||
DATA_PHASE: if(HREADY) NextState = MEM3;
|
DATA_PHASE: if(HREADY) NextState = MEM3;
|
||||||
else NextState = DATA_PHASE;
|
else NextState = DATA_PHASE;
|
||||||
MEM3: if(Stall) NextState = MEM3;
|
MEM3: if(Stall) NextState = MEM3;
|
||||||
else NextState = ADR_PHASE;
|
else NextState = ADR_PHASE;
|
||||||
default: NextState = ADR_PHASE;
|
default: NextState = ADR_PHASE;
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
|
|
||||||
assign BusStall = (CurrState == ADR_PHASE & |BusRW) |
|
assign BusStall = (CurrState == ADR_PHASE & |BusRW) |
|
||||||
|
Loading…
Reference in New Issue
Block a user