This commit is contained in:
David Harris 2023-01-19 14:47:54 -08:00
commit 9df5fdbd89
21 changed files with 435 additions and 345 deletions

View File

@ -1,14 +1,13 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// ahbcacheinterface.sv // ahbcacheinterface.sv
// //
// Written: Ross Thompson ross1728@gmail.com August 29, 2022 // Written: Ross Thompson ross1728@gmail.com
// Modified: // Created: August 29, 2022
// Modified: 18 January 2023
// //
// Purpose: Cache/Bus data path. // Purpose: Translates cache bus requests and uncached ieu memory requests into AHB transactions.
// Bus Side logic //
// register the fetch data from the next level of memory. // Documentation: RISC-V System on Chip Design Chapter 9 (Figure 9.8)
// This register should be necessary for timing. There is no register in the uncore or
// ahblite controller between the memories and this cache.
// //
// A component of the CORE-V-WALLY configurable RISC-V project. // A component of the CORE-V-WALLY configurable RISC-V project.
// //
@ -30,7 +29,12 @@
`include "wally-config.vh" `include "wally-config.vh"
module ahbcacheinterface #(parameter BEATSPERLINE, LINELEN, LOGWPL, LLENPOVERAHBW) ( module ahbcacheinterface #(
parameter integer BEATSPERLINE, // Number of AHBW words (beats) in cacheline
parameter integer AHBWLOGBWPL, // Log2 of ^
parameter integer LINELEN, // Number of bits in cacheline
parameter integer LLENPOVERAHBW // Number of AHB beats in a LLEN word. AHBW cannot be larger than LLEN. (implementation limitation)
)(
input logic HCLK, HRESETn, input logic HCLK, HRESETn,
// bus interface controls // bus interface controls
input logic HREADY, // AHB peripheral ready input logic HREADY, // AHB peripheral ready
@ -52,7 +56,7 @@ module ahbcacheinterface #(parameter BEATSPERLINE, LINELEN, LOGWPL, LLENPOVERAHB
input logic [1:0] CacheBusRW, // Cache bus operation, 01: writeback, 10: fetch input logic [1:0] CacheBusRW, // Cache bus operation, 01: writeback, 10: fetch
output logic CacheBusAck, // Handshack to $ indicating bus transaction completed output logic CacheBusAck, // Handshack to $ indicating bus transaction completed
output logic [LINELEN-1:0] FetchBuffer, // Register to hold beats of cache line as the arrive from bus output logic [LINELEN-1:0] FetchBuffer, // Register to hold beats of cache line as the arrive from bus
output logic [LOGWPL-1:0] BeatCount, // Beat position within the cache line in the Address Phase output logic [AHBWLOGBWPL-1:0] BeatCount, // Beat position within the cache line in the Address Phase
output logic SelBusBeat, // Tells the cache to select the word from ReadData or WriteData from BeatCount rather than PAdr output logic SelBusBeat, // Tells the cache to select the word from ReadData or WriteData from BeatCount rather than PAdr
// uncached interface // uncached interface
@ -70,7 +74,7 @@ module ahbcacheinterface #(parameter BEATSPERLINE, LINELEN, LOGWPL, LLENPOVERAHB
localparam integer BeatCountThreshold = BEATSPERLINE - 1; // Largest beat index localparam integer BeatCountThreshold = BEATSPERLINE - 1; // Largest beat index
logic [`PA_BITS-1:0] LocalHADDR; // Address after selecting between cached and uncached operation logic [`PA_BITS-1:0] LocalHADDR; // Address after selecting between cached and uncached operation
logic [LOGWPL-1:0] BeatCountDelayed; // Beat within the cache line in the second (Data) cache stage logic [AHBWLOGBWPL-1:0] BeatCountDelayed; // Beat within the cache line in the second (Data) cache stage
logic CaptureEn; // Enable updating the Fetch buffer with valid data from HRDATA logic CaptureEn; // Enable updating the Fetch buffer with valid data from HRDATA
logic [`AHBW/8-1:0] BusByteMaskM; // Byte enables within a word. For cache request all 1s logic [`AHBW/8-1:0] BusByteMaskM; // Byte enables within a word. For cache request all 1s
logic [`AHBW-1:0] PreHWDATA; // AHB Address phase write data logic [`AHBW-1:0] PreHWDATA; // AHB Address phase write data
@ -86,7 +90,7 @@ module ahbcacheinterface #(parameter BEATSPERLINE, LINELEN, LOGWPL, LLENPOVERAHB
end end
mux2 #(`PA_BITS) localadrmux(PAdr, CacheBusAdr, Cacheable, LocalHADDR); mux2 #(`PA_BITS) localadrmux(PAdr, CacheBusAdr, Cacheable, LocalHADDR);
assign HADDR = ({{`PA_BITS-LOGWPL{1'b0}}, BeatCount} << $clog2(`AHBW/8)) + LocalHADDR; assign HADDR = ({{`PA_BITS-AHBWLOGBWPL{1'b0}}, BeatCount} << $clog2(`AHBW/8)) + LocalHADDR;
mux2 #(3) sizemux(.d0(Funct3), .d1(`AHBW == 32 ? 3'b010 : 3'b011), .s(Cacheable), .y(HSIZE)); mux2 #(3) sizemux(.d0(Funct3), .d1(`AHBW == 32 ? 3'b010 : 3'b011), .s(Cacheable), .y(HSIZE));
@ -111,7 +115,7 @@ module ahbcacheinterface #(parameter BEATSPERLINE, LINELEN, LOGWPL, LLENPOVERAHB
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, AHBWLOGBWPL) 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);

View File

@ -1,14 +1,13 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// ahbinterface.sv // ahbinterface.sv
// //
// Written: Ross Thompson ross1728@gmail.com August 29, 2022 // Written: Ross Thompson ross1728@gmail.com
// Modified: // Created: August 29, 2022
// Modified: 18 January 2023
// //
// Purpose: Cache/Bus data path. // Purpose: Translates LSU simple memory requests into AHB transactions (NON_SEQ).
// Bus Side logic //
// register the fetch data from the next level of memory. // Documentation: RISC-V System on Chip Design Chapter 6 (Figure 6.21)
// This register should be necessary for timing. There is no register in the uncore or
// ahblite controller between the memories and this cache.
// //
// A component of the CORE-V-WALLY configurable RISC-V project. // A component of the CORE-V-WALLY configurable RISC-V project.
// //
@ -30,7 +29,9 @@
`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 // 1: LSU bus width is `XLEN, 0: IFU bus width is 32 bits
)(
input logic HCLK, HRESETn, input logic HCLK, HRESETn,
// bus interface // bus interface
input logic HREADY, // AHB peripheral ready input logic HREADY, // AHB peripheral ready

View File

@ -1,10 +1,13 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// busfsm.sv // busfsm.sv
// //
// Written: Ross Thompson ross1728@gmail.com December 29, 2021 // Written: Ross Thompson ross1728@gmail.com
// Modified: // Created: December 29, 2021
// Modified: 18 January 2023
// //
// Purpose: Load/Store Unit's interface to BUS for cacheless system // Purpose: Controller for cache to AHB bus interface
//
// Documentation: RISC-V System on Chip Design Chapter 9 (Figure 9.9)
// //
// A component of the CORE-V-WALLY configurable RISC-V project. // A component of the CORE-V-WALLY configurable RISC-V project.
// //
@ -25,10 +28,13 @@
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
`include "wally-config.vh" `include "wally-config.vh"
`define BURST_EN 1 `define BURST_EN 1 // Enables burst mode. Disable to show the lost performance.
// HCLK and clk must be the same clock! // HCLK and clk must be the same clock!
module buscachefsm #(parameter integer BeatCountThreshold, LOGWPL) ( module buscachefsm #(
parameter integer BeatCountThreshold, // Largest beat index
parameter integer AHBWLOGBWPL // Log2 of BEATSPERLINE
)(
input logic HCLK, input logic HCLK,
input logic HRESETn, input logic HRESETn,
@ -47,8 +53,8 @@ module buscachefsm #(parameter integer BeatCountThreshold, LOGWPL) (
output logic CacheBusAck, // Handshack to $ indicating bus transaction completed output logic CacheBusAck, // Handshack to $ indicating bus transaction completed
// lsu interface // lsu interface
output logic [LOGWPL-1:0] BeatCount, // Beat position within the cache line in the Address Phase output logic [AHBWLOGBWPL-1:0] BeatCount, // Beat position within the cache line in the Address Phase
output logic [LOGWPL-1:0] BeatCountDelayed, // Beat within the cache line in the second (Data) cache stage output logic [AHBWLOGBWPL-1:0] BeatCountDelayed, // Beat within the cache line in the second (Data) cache stage
output logic SelBusBeat, // Tells the cache to select the word from ReadData or WriteData from BeatCount rather than PAdr output logic SelBusBeat, // Tells the cache to select the word from ReadData or WriteData from BeatCount rather than PAdr
// BUS interface // BUS interface
@ -63,7 +69,7 @@ module buscachefsm #(parameter integer BeatCountThreshold, LOGWPL) (
(* mark_debug = "true" *) busstatetype CurrState, NextState; (* mark_debug = "true" *) busstatetype CurrState, NextState;
logic [LOGWPL-1:0] NextBeatCount; logic [AHBWLOGBWPL-1:0] NextBeatCount;
logic FinalBeatCount; logic FinalBeatCount;
logic [2:0] LocalBurstType; logic [2:0] LocalBurstType;
logic BeatCntEn; logic BeatCntEn;
@ -98,11 +104,11 @@ module buscachefsm #(parameter integer BeatCountThreshold, LOGWPL) (
// IEU, LSU, and IFU controls // IEU, LSU, and IFU controls
// Used to store data from data phase of AHB. // Used to store data from data phase of AHB.
flopenr #(LOGWPL) BeatCountReg(HCLK, ~HRESETn | BeatCntReset, BeatCntEn, NextBeatCount, BeatCount); flopenr #(AHBWLOGBWPL) BeatCountReg(HCLK, ~HRESETn | BeatCntReset, BeatCntEn, NextBeatCount, BeatCount);
flopenr #(LOGWPL) BeatCountDelayedReg(HCLK, ~HRESETn | BeatCntReset, BeatCntEn, BeatCount, BeatCountDelayed); flopenr #(AHBWLOGBWPL) BeatCountDelayedReg(HCLK, ~HRESETn | BeatCntReset, BeatCntEn, BeatCount, BeatCountDelayed);
assign NextBeatCount = BeatCount + 1'b1; assign NextBeatCount = BeatCount + 1'b1;
assign FinalBeatCount = BeatCountDelayed == BeatCountThreshold[LOGWPL-1:0]; assign FinalBeatCount = BeatCountDelayed == BeatCountThreshold[AHBWLOGBWPL-1:0];
assign BeatCntEn = ((NextState == CACHE_WRITEBACK | NextState == CACHE_FETCH) & HREADY & ~Flush) | assign BeatCntEn = ((NextState == CACHE_WRITEBACK | NextState == CACHE_FETCH) & HREADY & ~Flush) |
(NextState == ADR_PHASE & |CacheBusRW & HREADY); (NextState == ADR_PHASE & |CacheBusRW & HREADY);
assign BeatCntReset = NextState == ADR_PHASE; assign BeatCntReset = NextState == ADR_PHASE;

View File

@ -1,10 +1,13 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// busfsm.sv // busfsm.sv
// //
// Written: Ross Thompson ross1728@gmail.com December 29, 2021 // Written: Ross Thompson ross1728@gmail.com
// Modified: // Created: December 29, 2021
// Modified: 18 January 2023
// //
// Purpose: Load/Store Unit's interface to BUS for cacheless system // Purpose: Simple NON_SEQ (no burst) AHB controller.
//
// Documentation: RISC-V System on Chip Design Chapter 6 (Figure 6.23)
// //
// A component of the CORE-V-WALLY configurable RISC-V project. // A component of the CORE-V-WALLY configurable RISC-V project.
// //

View File

@ -1,16 +1,17 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// controller input stage // controller input stage
// //
// Written: Ross Thompson August 31, 2022 // Written: Ross Thompson ross1728@gmail.com
// ross1728@gmail.com // Created: August 31, 2022
// Modified: // Modified: 18 January 2023
// //
// Purpose: AHB multi controller interface to merge LSU and IFU controls. // Purpose: AHB multi controller interface to merge LSU and IFU controls.
// See ARM_HIH0033A_AMBA_AHB-Lite_SPEC 1.0 // See ARM_HIH0033A_AMBA_AHB-Lite_SPEC 1.0
// Arbitrates requests from instruction and data streams // Arbitrates requests from instruction and data streams
// Connects core to peripherals and I/O pins on SOC // Connects core to peripherals and I/O pins on SOC
// Bus width presently matches XLEN // Bus width presently matches XLEN
// Anticipate replacing this with an AXI bus interface to communicate with FPGA DRAM/Flash controllers //
// Documentation: RISC-V System on Chip Design Chapter 6 (Figure 6.25)
// //
// A component of the CORE-V-WALLY configurable RISC-V project. // A component of the CORE-V-WALLY configurable RISC-V project.
// //
@ -32,25 +33,29 @@
`include "wally-config.vh" `include "wally-config.vh"
module controllerinputstage #(parameter SAVE_ENABLED = 1) ( module controllerinputstage #(
parameter SAVE_ENABLED = 1 // 1: Save manager inputs if Save = 1, 0: Don't save inputs
)(
input logic HCLK, input logic HCLK,
input logic HRESETn, input logic HRESETn,
input logic Save, Restore, Disable, input logic Save, // Two or more managers requesting (HTRANS != 00) at the same time. Save the non-granted manager inputs
output logic Request, input logic Restore, // Restore a saved manager inputs when it is finally granted
input logic Disable, // Supress HREADY to the non-granted manager
output logic Request, // This manager is making a request
// controller input // controller input
input logic HWRITEIn, input logic [1:0] HTRANSIn, // Manager input. AHB transaction type, 00: IDLE, 10 NON_SEQ, 11 SEQ
input logic [2:0] HSIZEIn, input logic HWRITEIn, // Manager input. AHB 0: Read operation 1: Write operation
input logic [2:0] HBURSTIn, input logic [2:0] HSIZEIn, // Manager input. AHB transaction width
input logic [1:0] HTRANSIn, input logic [2:0] HBURSTIn, // Manager input. AHB burst length
input logic [`PA_BITS-1:0] HADDRIn, input logic [`PA_BITS-1:0] HADDRIn, // Manager input. AHB address
output logic HREADYOut, output logic HREADYOut, // Indicate to manager the peripherial is not busy and another manager does not have priority
// controller output // controller output
output logic HWRITEOut, output logic [1:0] HTRANSOut, // Aribrated manager transaction. AHB transaction type, 00: IDLE, 10 NON_SEQ, 11 SEQ
output logic [2:0] HSIZEOut, output logic HWRITEOut, // Aribrated manager transaction. AHB 0: Read operation 1: Write operation
output logic [2:0] HBURSTOut, output logic [2:0] HSIZEOut, // Aribrated manager transaction. AHB transaction width
output logic [1:0] HTRANSOut, output logic [2:0] HBURSTOut, // Aribrated manager transaction. AHB burst length
output logic [`PA_BITS-1:0] HADDROut, output logic [`PA_BITS-1:0] HADDROut, // Aribrated manager transaction. AHB address
input logic HREADYIn input logic HREADYIn // Peripherial ready
); );
logic HWRITESave; logic HWRITESave;

View File

@ -1,16 +1,17 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// abhmulticontroller // abhmulticontroller
// //
// Written: Ross Thompson August 29, 2022 // Written: Ross Thompson ross1728@gmail.com
// ross1728@gmail.com // Created: August 29, 2022
// Modified: // Modified: 18 January 2023
// //
// Purpose: AHB multi controller interface to merge LSU and IFU controls. // Purpose: AHB multi controller interface to merge LSU and IFU controls.
// See ARM_HIH0033A_AMBA_AHB-Lite_SPEC 1.0 // See ARM_HIH0033A_AMBA_AHB-Lite_SPEC 1.0
// Arbitrates requests from instruction and data streams // Arbitrates requests from instruction and data streams
// Connects core to peripherals and I/O pins on SOC // Connects core to peripherals and I/O pins on SOC
// Bus width presently matches XLEN // Bus width presently matches XLEN
// Anticipate replacing this with an AXI bus interface to communicate with FPGA DRAM/Flash controllers //
// Documentation: RISC-V System on Chip Design Chapter 6 (Figures 6.25 and 6.26)
// //
// A component of the CORE-V-WALLY configurable RISC-V project. // A component of the CORE-V-WALLY configurable RISC-V project.
// //
@ -35,42 +36,46 @@
module ebu ( module ebu (
input logic clk, reset, input logic clk, reset,
// Signals from IFU // Signals from IFU
input logic [`PA_BITS-1:0] IFUHADDR, input logic [1:0] IFUHTRANS, // IFU AHB transaction request
input logic [2:0] IFUHSIZE, input logic [2:0] IFUHSIZE, // IFU AHB transaction size
input logic [2:0] IFUHBURST, input logic [2:0] IFUHBURST, // IFU AHB burst length
input logic [1:0] IFUHTRANS, input logic [`PA_BITS-1:0] IFUHADDR, // IFU AHB address
output logic IFUHREADY, output logic IFUHREADY, // AHB peripheral ready gated by possible non-grant
// Signals from LSU // Signals from LSU
input logic [`PA_BITS-1:0] LSUHADDR, input logic [1:0] LSUHTRANS, // LSU AHB transaction request
input logic LSUHWRITE, // LSU AHB transaction direction. 1: write, 0: read
input logic [2:0] LSUHSIZE, // LSU AHB size
input logic [2:0] LSUHBURST, // LSU AHB burst length
input logic [`PA_BITS-1:0] LSUHADDR, // LSU AHB address
input logic [`XLEN-1:0] LSUHWDATA, // initially support AHBW = XLEN input logic [`XLEN-1:0] LSUHWDATA, // initially support AHBW = XLEN
input logic [`XLEN/8-1:0] LSUHWSTRB, input logic [`XLEN/8-1:0] LSUHWSTRB, // AHB byte mask
input logic [2:0] LSUHSIZE, output logic LSUHREADY, // AHB peripheral. Never gated as LSU always has priority
input logic [2:0] LSUHBURST,
input logic [1:0] LSUHTRANS,
input logic LSUHWRITE,
output logic LSUHREADY,
// add LSUHWSTRB ***
// AHB-Lite external signals // AHB-Lite external signals
(* mark_debug = "true" *) input logic HREADY, HRESP,
(* mark_debug = "true" *) output logic HCLK, HRESETn, (* mark_debug = "true" *) output logic HCLK, HRESETn,
(* mark_debug = "true" *) output logic [`PA_BITS-1:0] HADDR, (* mark_debug = "true" *) input logic HREADY, // AHB peripheral ready
(* mark_debug = "true" *) output logic [`AHBW-1:0] HWDATA, (* mark_debug = "true" *) input logic HRESP, // AHB peripheral response. 0: OK 1: Error
(* mark_debug = "true" *) output logic [`XLEN/8-1:0] HWSTRB, (* mark_debug = "true" *) output logic [`PA_BITS-1:0] HADDR, // AHB address to peripheral after arbitration
(* mark_debug = "true" *) output logic HWRITE, (* mark_debug = "true" *) output logic [`AHBW-1:0] HWDATA, // AHB Write data after arbitration
(* mark_debug = "true" *) output logic [2:0] HSIZE, (* mark_debug = "true" *) output logic [`XLEN/8-1:0] HWSTRB, // AHB byte write enables after arbitration
(* mark_debug = "true" *) output logic [2:0] HBURST, (* mark_debug = "true" *) output logic HWRITE, // AHB transaction direction after arbitration
(* mark_debug = "true" *) output logic [3:0] HPROT, (* mark_debug = "true" *) output logic [2:0] HSIZE, // AHB transaction size after arbitration
(* mark_debug = "true" *) output logic [1:0] HTRANS, (* mark_debug = "true" *) output logic [2:0] HBURST, // AHB burst length after arbitration
(* mark_debug = "true" *) output logic HMASTLOCK (* mark_debug = "true" *) output logic [3:0] HPROT, // AHB protection. Wally does not use
(* mark_debug = "true" *) output logic [1:0] HTRANS, // AHB transaction request after arbitration
(* mark_debug = "true" *) output logic HMASTLOCK // AHB master lock. Wally does not use
); );
typedef enum logic [1:0] {IDLE, ARBITRATE} statetype; typedef enum logic [1:0] {IDLE, ARBITRATE} statetype;
statetype CurrState, NextState; statetype CurrState, NextState;
logic LSUDisable, LSUSelect; logic LSUDisable;
logic IFUSave, IFURestore, IFUDisable, IFUSelect; logic LSUSelect;
logic both; logic IFUSave;
logic IFURestore;
logic IFUDisable;
logic IFUSelect;
logic both; // Both the LSU and IFU request at the same time
logic [`PA_BITS-1:0] IFUHADDROut; logic [`PA_BITS-1:0] IFUHADDROut;
logic [1:0] IFUHTRANSOut; logic [1:0] IFUHTRANSOut;
@ -84,14 +89,15 @@ module ebu (
logic [2:0] LSUHSIZEOut; logic [2:0] LSUHSIZEOut;
logic LSUHWRITEOut; logic LSUHWRITEOut;
logic IFUReq, LSUReq; logic IFUReq;
logic LSUReq;
logic BeatCntEn; logic BeatCntEn;
logic [4-1:0] NextBeatCount, BeatCount; logic [4-1:0] NextBeatCount, BeatCount; // Position within a burst transfer
logic FinalBeat, FinalBeatD; logic FinalBeat, FinalBeatD; // Indicates the last beat of a burst
logic CntReset; logic CntReset;
logic [3:0] Threshold; logic [3:0] Threshold; // Number of beats derived from HBURST
logic IFUReqD; logic IFUReqD; // 1 cycle delayed IFU request. Part of arbitration
assign HCLK = clk; assign HCLK = clk;
@ -100,14 +106,16 @@ module ebu (
// if two requests come in at once pick one to select and save the others Address phase // if two requests come in at once pick one to select and save the others Address phase
// inputs. Abritration scheme is LSU always goes first. // inputs. Abritration scheme is LSU always goes first.
// input stage IFU ////////////////////////////////////////////////////////////////////////////////////////////////////
// input stages and muxing for IFU and LSU
////////////////////////////////////////////////////////////////////////////////////////////////////
controllerinputstage IFUInput(.HCLK, .HRESETn, .Save(IFUSave), .Restore(IFURestore), .Disable(IFUDisable), controllerinputstage IFUInput(.HCLK, .HRESETn, .Save(IFUSave), .Restore(IFURestore), .Disable(IFUDisable),
.Request(IFUReq), .Request(IFUReq),
.HWRITEIn(1'b0), .HSIZEIn(IFUHSIZE), .HBURSTIn(IFUHBURST), .HTRANSIn(IFUHTRANS), .HADDRIn(IFUHADDR), .HWRITEIn(1'b0), .HSIZEIn(IFUHSIZE), .HBURSTIn(IFUHBURST), .HTRANSIn(IFUHTRANS), .HADDRIn(IFUHADDR),
.HWRITEOut(IFUHWRITEOut), .HSIZEOut(IFUHSIZEOut), .HBURSTOut(IFUHBURSTOut), .HREADYOut(IFUHREADY), .HWRITEOut(IFUHWRITEOut), .HSIZEOut(IFUHSIZEOut), .HBURSTOut(IFUHBURSTOut), .HREADYOut(IFUHREADY),
.HTRANSOut(IFUHTRANSOut), .HADDROut(IFUHADDROut), .HREADYIn(HREADY)); .HTRANSOut(IFUHTRANSOut), .HADDROut(IFUHADDROut), .HREADYIn(HREADY));
// input stage LSU
// LSU always has priority so there should never be a need to save and restore the address phase inputs. // LSU always has priority so there should never be a need to save and restore the address phase inputs.
controllerinputstage #(0) LSUInput(.HCLK, .HRESETn, .Save(1'b0), .Restore(1'b0), .Disable(LSUDisable), controllerinputstage #(0) LSUInput(.HCLK, .HRESETn, .Save(1'b0), .Restore(1'b0), .Disable(LSUDisable),
.Request(LSUReq), .Request(LSUReq),
@ -115,7 +123,7 @@ module ebu (
.HWRITEOut(LSUHWRITEOut), .HSIZEOut(LSUHSIZEOut), .HBURSTOut(LSUHBURSTOut), .HWRITEOut(LSUHWRITEOut), .HSIZEOut(LSUHSIZEOut), .HBURSTOut(LSUHBURSTOut),
.HTRANSOut(LSUHTRANSOut), .HADDROut(LSUHADDROut), .HREADYIn(HREADY)); .HTRANSOut(LSUHTRANSOut), .HADDROut(LSUHADDROut), .HREADYIn(HREADY));
// output mux //*** rewrite for general number of controllers. // output mux //*** switch to structural implementation
assign HADDR = LSUSelect ? LSUHADDROut : IFUSelect ? IFUHADDROut : '0; assign HADDR = LSUSelect ? LSUHADDROut : IFUSelect ? IFUHADDROut : '0;
assign HSIZE = LSUSelect ? LSUHSIZEOut : IFUSelect ? IFUHSIZEOut: '0; assign HSIZE = LSUSelect ? LSUHSIZEOut : IFUSelect ? IFUHSIZEOut: '0;
assign HBURST = LSUSelect ? LSUHBURSTOut : IFUSelect ? IFUHBURSTOut : '0; // If doing memory accesses, use LSUburst, else use Instruction burst. assign HBURST = LSUSelect ? LSUHBURSTOut : IFUSelect ? IFUHBURSTOut : '0; // If doing memory accesses, use LSUburst, else use Instruction burst.
@ -129,8 +137,13 @@ module ebu (
assign HWSTRB = LSUHWSTRB; assign HWSTRB = LSUHWSTRB;
// HRDATA is sent to all controllers at the core level. // HRDATA is sent to all controllers at the core level.
////////////////////////////////////////////////////////////////////////////////////////////////////
// Aribtration scheme
// FSM decides if arbitration needed. Arbitration is held until the last beat of // FSM decides if arbitration needed. Arbitration is held until the last beat of
// a burst is completed. // a burst is completed.
////////////////////////////////////////////////////////////////////////////////////////////////////
assign both = LSUReq & IFUReq; assign both = LSUReq & IFUReq;
flopenl #(.TYPE(statetype)) busreg(HCLK, ~HRESETn, 1'b1, NextState, IDLE, CurrState); flopenl #(.TYPE(statetype)) busreg(HCLK, ~HRESETn, 1'b1, NextState, IDLE, CurrState);
always_comb always_comb
@ -142,8 +155,27 @@ module ebu (
default: NextState = IDLE; default: NextState = IDLE;
endcase endcase
// This part is only used when burst mode is supported. // basic arb always selects LSU when both
// Controller needs to count beats. // replace this block for more sophisticated arbitration as needed.
// Controller 0 (IFU)
assign IFUSave = CurrState == IDLE & both;
assign IFURestore = CurrState == ARBITRATE;
assign IFUDisable = CurrState == ARBITRATE;
assign IFUSelect = (NextState == ARBITRATE) ? 1'b0 : IFUReq;
// Controller 1 (LSU)
// When both the IFU and LSU request at the same time, the FSM will go into the arbitrate state.
// Once the LSU request is done the fsm returns to IDLE. To prevent the LSU from regaining
// priority and re issuing the same memroy operation, the delayed IFUReqD squashes the LSU request.
// This is necessary because the pipeline is stalled for the entire duration of both transactions,
// and the LSU memory request will stil be active.
flopr #(1) ifureqreg(clk, ~HRESETn, IFUReq, IFUReqD);
assign LSUDisable = CurrState == ARBITRATE ? 1'b0 : (IFUReqD & ~(HREADY & FinalBeatD));
assign LSUSelect = NextState == ARBITRATE ? 1'b1: LSUReq;
////////////////////////////////////////////////////////////////////////////////////////////////////
// Burst mode logic
////////////////////////////////////////////////////////////////////////////////////////////////////
flopenr #(4) BeatCountReg(HCLK, ~HRESETn | CntReset | FinalBeat, BeatCntEn, NextBeatCount, BeatCount); flopenr #(4) BeatCountReg(HCLK, ~HRESETn | CntReset | FinalBeat, BeatCntEn, NextBeatCount, BeatCount);
assign NextBeatCount = BeatCount + 1'b1; assign NextBeatCount = BeatCount + 1'b1;
@ -165,17 +197,6 @@ module ebu (
endcase endcase
end end
// basic arb always selects LSU when both
// replace this block for more sophisticated arbitration as needed.
// Controller 0 (IFU)
assign IFUSave = CurrState == IDLE & both;
assign IFURestore = CurrState == ARBITRATE;
assign IFUDisable = CurrState == ARBITRATE;
assign IFUSelect = (NextState == ARBITRATE) ? 1'b0 : IFUReq;
// Controller 1 (LSU)
assign LSUDisable = CurrState == ARBITRATE ? 1'b0 : (IFUReqD & ~(HREADY & FinalBeatD));
assign LSUSelect = NextState == ARBITRATE ? 1'b1: LSUReq;
flopr #(1) ifureqreg(clk, ~HRESETn, IFUReq, IFUReqD);
endmodule endmodule

View File

@ -1,13 +1,12 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// bpred.sv // bpred.sv
// //
// Written: Ross Thomposn // Written: Ross Thomposn ross1728@gmail.com
// Email: ross1728@gmail.com // Created: 12 February 2021
// Created: February 12, 2021 // Modified: 19 January 2023
// Modified:
// //
// Purpose: Branch prediction unit // Purpose: Branch direction prediction and jump/branch target prediction.
// Produces a branch prediction based on branch history. // Prediction made during the fetch stage and corrected in the execution stage.
// //
// A component of the CORE-V-WALLY configurable RISC-V project. // A component of the CORE-V-WALLY configurable RISC-V project.
// //
@ -35,7 +34,7 @@ module bpred (
input logic FlushD, FlushE, FlushM, FlushW, input logic FlushD, FlushE, FlushM, FlushW,
// Fetch stage // Fetch stage
// the prediction // the prediction
input logic [31:0] InstrD, // Decompressed decode stage instruction input logic [31:0] InstrD, // Decompressed decode stage instruction. Used to decode instruction class
input logic [`XLEN-1:0] PCNextF, // Next Fetch Address input logic [`XLEN-1:0] PCNextF, // Next Fetch Address
input logic [`XLEN-1:0] PCPlus2or4F, // PCF+2/4 input logic [`XLEN-1:0] PCPlus2or4F, // PCF+2/4
output logic [`XLEN-1:0] PCNext1F, // Branch Predictor predicted or corrected fetch address on miss prediction output logic [`XLEN-1:0] PCNext1F, // Branch Predictor predicted or corrected fetch address on miss prediction
@ -47,8 +46,7 @@ module bpred (
input logic [`XLEN-1:0] PCE, // Execution stage instruction address. input logic [`XLEN-1:0] PCE, // Execution stage instruction address.
input logic [`XLEN-1:0] PCM, // Memory stage instruction address. input logic [`XLEN-1:0] PCM, // Memory stage instruction address.
// *** after reviewing the compressed instruction set I am leaning towards having the btb predict the instruction class. // Branch and jump outcome
// *** the specifics of how this is encode is subject to change.
input logic PCSrcE, // Executation stage branch is taken input logic PCSrcE, // Executation stage branch is taken
input logic [`XLEN-1:0] IEUAdrE, // The branch/jump target address input logic [`XLEN-1:0] IEUAdrE, // The branch/jump target address
input logic [`XLEN-1:0] PCLinkE, // The address following the branch instruction. (AKA Fall through address) input logic [`XLEN-1:0] PCLinkE, // The address following the branch instruction. (AKA Fall through address)

View File

@ -1,11 +1,16 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// decompress.sv // decompress.sv
// //
// Written: David_Harris@hmc.edu 9 January 2021 // Written: David_Harris@hmc.edu
// Modified: // Created: 9 January 2021
// Modified: 18 January 2023
// //
// Purpose: Expand 16-bit compressed instructions to 32 bits // Purpose: Expand 16-bit compressed instructions to 32 bits
// //
// Documentation: RISC-V System on Chip Design Chapter 11 (Section 11.3.1)
// RISC-V Specification 13 Dec 2019 Chapter 16 pg. 97
// *** probably need more documentation in this file since the book is very light on decompression.
//
// A component of the CORE-V-WALLY configurable RISC-V project. // A component of the CORE-V-WALLY configurable RISC-V project.
// //
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
@ -27,9 +32,10 @@
`include "wally-config.vh" `include "wally-config.vh"
module decompress ( module decompress (
input logic [31:0] InstrRawD, input logic [31:0] InstrRawD, // 32-bit instruction or raw un decompress instruction
output logic [31:0] InstrD, output logic [31:0] InstrD, // Decompressed instruction
output logic IllegalCompInstrD); output logic IllegalCompInstrD // Invalid decompressed instruction
);
logic [15:0] instr16; logic [15:0] instr16;
logic [4:0] rds1, rs2, rs1p, rs2p, rds1p, rdp; logic [4:0] rds1, rs2, rs1p, rs2p, rds1p, rdp;

View File

@ -121,11 +121,10 @@ module ifu (
// Spill Support // Spill Support
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
if(`C_SUPPORTED) begin : SpillSupport if(`C_SUPPORTED) begin : Spill
spillsupport #(`ICACHE) spillsupport(.clk, .reset, .StallF, .Flush(FlushD), .PCF, .PCPlus4F, .PCNextF, .InstrRawF(InstrRawF), spill #(`ICACHE) spill(.clk, .reset, .StallD, .FlushD, .PCF, .PCPlus4F, .PCNextF, .InstrRawF,
.InstrDAPageFaultF, .IFUCacheBusStallD, .ITLBMissF, .PCNextFSpill, .PCFSpill, .InstrDAPageFaultF, .IFUCacheBusStallD, .ITLBMissF, .PCNextFSpill, .PCFSpill, .SelNextSpillF, .PostSpillInstrRawF, .CompressedF);
.SelNextSpillF, .PostSpillInstrRawF, .CompressedF); end else begin : NoSpill
end else begin : NoSpillSupport
assign PCNextFSpill = PCNextF; assign PCNextFSpill = PCNextF;
assign PCFSpill = PCF; assign PCFSpill = PCF;
assign PostSpillInstrRawF = InstrRawF; assign PostSpillInstrRawF = InstrRawF;
@ -190,8 +189,10 @@ module ifu (
// The IROM uses untranslated addresses, so it is not compatible with virtual memory. // The IROM uses untranslated addresses, so it is not compatible with virtual memory.
if (`IROM_SUPPORTED) begin : irom if (`IROM_SUPPORTED) begin : irom
logic IROMce;
assign IROMce = ~GatedStallD | reset;
assign IFURWF = 2'b10; assign IFURWF = 2'b10;
irom irom(.clk, .ce(~GatedStallD | reset), .Adr(PCNextFSpill[`XLEN-1:0]), .ReadData(IROMInstrF)); irom irom(.clk, .ce(IROMce), .Adr(PCNextFSpill[`XLEN-1:0]), .IROMInstrF);
end else begin end else begin
assign IFURWF = 2'b10; assign IFURWF = 2'b10;
end end
@ -227,7 +228,7 @@ module ifu (
.NextAdr(PCNextFSpill[11:0]), .NextAdr(PCNextFSpill[11:0]),
.PAdr(PCPF), .PAdr(PCPF),
.CacheCommitted(CacheCommittedF), .InvalidateCache(InvalidateICacheM)); .CacheCommitted(CacheCommittedF), .InvalidateCache(InvalidateICacheM));
ahbcacheinterface #(WORDSPERLINE, LINELEN, LOGBWPL, LLENPOVERAHBW) ahbcacheinterface #(WORDSPERLINE, LOGBWPL, LINELEN, LLENPOVERAHBW)
ahbcacheinterface(.HCLK(clk), .HRESETn(~reset), ahbcacheinterface(.HCLK(clk), .HRESETn(~reset),
.HRDATA, .HRDATA,
.Flush(FlushD), .CacheBusRW, .HSIZE(IFUHSIZE), .HBURST(IFUHBURST), .HTRANS(IFUHTRANS), .HWSTRB(), .Flush(FlushD), .CacheBusRW, .HSIZE(IFUHSIZE), .HBURST(IFUHBURST), .HTRANS(IFUHTRANS), .HWSTRB(),

View File

@ -1,8 +1,9 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// irom.sv // irom.sv
// //
// Written: Ross Thompson ross1728@gmail.com January 30, 2022 // Written: Ross Thompson ross1728@gmail.com
// Modified: // Created: 30 January 2022
// Modified: 18 January 2023
// //
// Purpose: simple instruction ROM // Purpose: simple instruction ROM
// A component of the CORE-V-WALLY configurable RISC-V project. // A component of the CORE-V-WALLY configurable RISC-V project.
@ -26,23 +27,30 @@
`include "wally-config.vh" `include "wally-config.vh"
module irom( module irom(
input logic clk, ce, input logic clk,
input logic [`XLEN-1:0] Adr, input logic ce, // Chip Enable. 0: Holds IROMInstrF constant
output logic [31:0] ReadData input logic [`XLEN-1:0] Adr, // PCNextFSpill
output logic [31:0] IROMInstrF // Instruction read data
); );
localparam ADDR_WDITH = $clog2(`IROM_RANGE/8); localparam ADDR_WDITH = $clog2(`IROM_RANGE/8);
localparam OFFSET = $clog2(`XLEN/8); localparam OFFSET = $clog2(`XLEN/8);
logic [`XLEN-1:0] ReadDataFull; logic [`XLEN-1:0] IROMInstrFFull;
logic [31:0] RawIROMInstrF;
rom1p1r #(ADDR_WDITH, `XLEN) rom(.clk, .ce, .addr(Adr[ADDR_WDITH+OFFSET-1:OFFSET]), .dout(ReadDataFull)); logic [1:0] AdrD;
if (`XLEN == 32) assign ReadData = ReadDataFull; flopen #(2) AdrReg(clk, ce, Adr[2:1], AdrD);
// have to delay Ardr[OFFSET-1] by 1 cycle
rom1p1r #(ADDR_WDITH, `XLEN) rom(.clk, .ce, .addr(Adr[ADDR_WDITH+OFFSET-1:OFFSET]), .dout(IROMInstrFFull));
if (`XLEN == 32) assign RawIROMInstrF = IROMInstrFFull;
else begin else begin
logic AdrD; // IROM is aligned to XLEN words, but instructions are 32 bits. Select between the two
flopen #(1) AdrReg(clk, ce, Adr[OFFSET-1], AdrD); // haves. Adr is the Next PCF not PCF so we delay 1 cycle.
assign ReadData = AdrD ? ReadDataFull[63:32] : ReadDataFull[31:0]; assign RawIROMInstrF = AdrD[1] ? IROMInstrFFull[63:32] : IROMInstrFFull[31:0];
end end
// If the memory addres is aligned to 2 bytes return the upper 2 bytes in the lower 2 bytes.
// The spill logic will handle merging the two together.
assign IROMInstrF = AdrD[0] ? {16'b0, RawIROMInstrF[31:16]} : RawIROMInstrF;
endmodule endmodule

112
pipelined/src/ifu/spill.sv Normal file
View File

@ -0,0 +1,112 @@
///////////////////////////////////////////
// spill.sv
//
// Written: Ross Thompson ross1728@gmail.com
// Created: 28 January 2022
// Modified: 19 January 2023
//
// Purpose: allows the IFU to make extra memory request if instruction address crosses
// cache line boundaries or if instruction address without a cache crosses
// XLEN/8 boundary.
//
// Documentation: RISC-V System on Chip Design Chapter 11 (Figure 11.5)
//
// A component of the CORE-V-WALLY configurable RISC-V project.
//
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
//
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
//
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
// may obtain a copy of the License at
//
// https://solderpad.org/licenses/SHL-2.1/
//
// Unless required by applicable law or agreed to in writing, any work distributed under the
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
`include "wally-config.vh"
module spill #(
parameter CACHE_ENABLED // Changes spill threshold to 1 if there is no cache
)(input logic clk,
input logic reset,
input logic StallD, FlushD,
input logic [`XLEN-1:0] PCF, // 2 byte aligned PC in Fetch stage
input logic [`XLEN-1:2] PCPlus4F, // PCF + 4
input logic [`XLEN-1:0] PCNextF, // The next PCF
input logic [31:0] InstrRawF, // Instruction from the IROM, I$, or bus. Used to check if the instruction if compressed
input logic IFUCacheBusStallD, // I$ or bus are stalled. Transition to second fetch of spill after the first is fetched
input logic ITLBMissF, // ITLB miss, ignore memory request
input logic InstrDAPageFaultF, // Ignore memory request if the hptw support write and a DA page fault occurs (hptw is still active)
output logic [`XLEN-1:0] PCNextFSpill, // The next PCF for one of the two memory addresses of the spill
output logic [`XLEN-1:0] PCFSpill, // PCF for one of the two memory addresses of the spill
output logic SelNextSpillF, // During the transition between the two spill operations, the IFU should stall the pipeline
output logic [31:0] PostSpillInstrRawF,// The final 32 bit instruction after merging the two spilled fetches into 1 instruction
output logic CompressedF); // The fetched instruction is compressed
// Spill threshold occurs when all the cache offset PC bits are 1 (except [0]). Without a cache this is just PCF[1]
localparam integer SPILLTHRESHOLD = CACHE_ENABLED ? `ICACHE_LINELENINBITS/32 : 1;
logic [`XLEN-1:0] PCPlus2F;
logic TakeSpillF;
logic SpillF;
logic SelSpillF;
logic SpillSaveF;
logic [15:0] InstrFirstHalf;
typedef enum logic [1:0] {STATE_READY, STATE_SPILL} statetype;
(* mark_debug = "true" *) statetype CurrState, NextState;
////////////////////////////////////////////////////////////////////////////////////////////////////
// PC logic
////////////////////////////////////////////////////////////////////////////////////////////////////
// compute PCF+2 from the raw PC+4
mux2 #(`XLEN) pcplus2mux(.d0({PCF[`XLEN-1:2], 2'b10}), .d1({PCPlus4F, 2'b00}), .s(PCF[1]), .y(PCPlus2F));
// select between PCNextF and PCF+2
mux2 #(`XLEN) pcnextspillmux(.d0(PCNextF), .d1(PCPlus2F), .s(SelNextSpillF & ~FlushD), .y(PCNextFSpill));
// select between PCF and PCF+2
mux2 #(`XLEN) pcspillmux(.d0(PCF), .d1(PCPlus2F), .s(SelSpillF), .y(PCFSpill));
////////////////////////////////////////////////////////////////////////////////////////////////////
// Detect spill
////////////////////////////////////////////////////////////////////////////////////////////////////
assign SpillF = &PCF[$clog2(SPILLTHRESHOLD)+1:1];
assign TakeSpillF = SpillF & ~IFUCacheBusStallD & ~(ITLBMissF | (`HPTW_WRITES_SUPPORTED & InstrDAPageFaultF));
always_ff @(posedge clk)
if (reset | FlushD) CurrState <= #1 STATE_READY;
else CurrState <= #1 NextState;
always_comb begin
case (CurrState)
STATE_READY: if (TakeSpillF) NextState = STATE_SPILL;
else NextState = STATE_READY;
STATE_SPILL: if(IFUCacheBusStallD | StallD) NextState = STATE_SPILL;
else NextState = STATE_READY;
default: NextState = STATE_READY;
endcase
end
assign SelSpillF = (CurrState == STATE_SPILL);
assign SelNextSpillF = (CurrState == STATE_READY & TakeSpillF) | (CurrState == STATE_SPILL & IFUCacheBusStallD);
assign SpillSaveF = (CurrState == STATE_READY) & TakeSpillF & ~FlushD;
////////////////////////////////////////////////////////////////////////////////////////////////////
// Merge spilled instruction
////////////////////////////////////////////////////////////////////////////////////////////////////
// save the first 2 bytes
flopenr #(16) SpillInstrReg(clk, reset, SpillSaveF, InstrRawF[15:0], InstrFirstHalf);
// merge together
mux2 #(32) postspillmux(InstrRawF, {InstrRawF[15:0], InstrFirstHalf}, SpillF, PostSpillInstrRawF);
assign CompressedF = PostSpillInstrRawF[1:0] != 2'b11;
endmodule

View File

@ -1,98 +0,0 @@
///////////////////////////////////////////
// spillsupport.sv
//
// Written: Ross Thompson ross1728@gmail.com January 28, 2022
// Modified:
//
// Purpose: allows the IFU to make extra memory request if instruction address crosses
// cache line boundaries or if instruction address without a cache crosses
// XLEN/8 boundary.
//
// A component of the CORE-V-WALLY configurable RISC-V project.
//
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
//
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
//
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
// may obtain a copy of the License at
//
// https://solderpad.org/licenses/SHL-2.1/
//
// Unless required by applicable law or agreed to in writing, any work distributed under the
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
`include "wally-config.vh"
module spillsupport #(parameter CACHE_ENABLED)
(input logic clk,
input logic reset,
input logic StallF, Flush,
input logic [`XLEN-1:0] PCF,
input logic [`XLEN-1:2] PCPlus4F,
input logic [`XLEN-1:0] PCNextF,
input logic [31:0] InstrRawF,
input logic IFUCacheBusStallD,
input logic ITLBMissF,
input logic InstrDAPageFaultF,
output logic [`XLEN-1:0] PCNextFSpill,
output logic [`XLEN-1:0] PCFSpill,
output logic SelNextSpillF,
output logic [31:0] PostSpillInstrRawF,
output logic CompressedF);
localparam integer SPILLTHRESHOLD = CACHE_ENABLED ? `ICACHE_LINELENINBITS/32 : 1;
logic [`XLEN-1:0] PCPlus2F;
logic TakeSpillF;
logic SpillF;
logic SelSpillF, SpillSaveF;
logic [15:0] SpillDataLine0, SavedInstr;
typedef enum logic [1:0] {STATE_READY, STATE_SPILL} statetype;
(* mark_debug = "true" *) statetype CurrState, NextState;
// compute PCF+2
mux2 #(`XLEN) pcplus2mux(.d0({PCF[`XLEN-1:2], 2'b10}), .d1({PCPlus4F, 2'b00}), .s(PCF[1]), .y(PCPlus2F));
// select between PCNextF and PCF+2
mux2 #(`XLEN) pcnextspillmux(.d0(PCNextF), .d1(PCPlus2F), .s(SelNextSpillF & ~Flush), .y(PCNextFSpill));
// select between PCF and PCF+2
mux2 #(`XLEN) pcspillmux(.d0(PCF), .d1(PCPlus2F), .s(SelSpillF), .y(PCFSpill));
assign SpillF = &PCF[$clog2(SPILLTHRESHOLD)+1:1];
assign TakeSpillF = SpillF & ~IFUCacheBusStallD & ~(ITLBMissF | (`HPTW_WRITES_SUPPORTED & InstrDAPageFaultF));
always_ff @(posedge clk)
if (reset | Flush) CurrState <= #1 STATE_READY;
else CurrState <= #1 NextState;
always_comb begin
case (CurrState)
STATE_READY: if (TakeSpillF) NextState = STATE_SPILL;
else NextState = STATE_READY;
STATE_SPILL: if(IFUCacheBusStallD | StallF) NextState = STATE_SPILL;
else NextState = STATE_READY;
default: NextState = STATE_READY;
endcase
end
assign SelSpillF = (CurrState == STATE_SPILL);
assign SelNextSpillF = (CurrState == STATE_READY & TakeSpillF) |
(CurrState == STATE_SPILL & IFUCacheBusStallD);
assign SpillSaveF = (CurrState == STATE_READY) & TakeSpillF;
assign SavedInstr = CACHE_ENABLED ? InstrRawF[15:0] : InstrRawF[31:16];
flopenr #(16) SpillInstrReg(.clk(clk),
.en(SpillSaveF & ~Flush),
.reset(reset),
.d(SavedInstr),
.q(SpillDataLine0));
mux2 #(32) postspillmux(.d0(InstrRawF), .d1({InstrRawF[15:0], SpillDataLine0}), .s(SpillF),
.y(PostSpillInstrRawF));
assign CompressedF = PostSpillInstrRawF[1:0] != 2'b11;
endmodule

View File

@ -1,11 +1,14 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// amoalu.sv // amoalu.sv
// //
// Written: David_Harris@hmc.edu 10 March 2021 // Written: David_Harris@hmc.edu
// Modified: // Created: 10 March 2021
// Modified: 18 January 2023
// //
// Purpose: Performs AMO operations // Purpose: Performs AMO operations
// //
// Documentation: RISC-V System on Chip Design Chapter 14 (Figure ***)
//
// A component of the CORE-V-WALLY configurable RISC-V project. // A component of the CORE-V-WALLY configurable RISC-V project.
// //
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
@ -26,13 +29,12 @@
`include "wally-config.vh" `include "wally-config.vh"
// *** this should probably be moved into the LSU because it is instantiated in the D$
module amoalu ( module amoalu (
input logic [`XLEN-1:0] srca, srcb, input logic [`XLEN-1:0] ReadDataM, // LSU's ReadData
input logic [6:0] funct, input logic [`XLEN-1:0] IHWriteDataM, // LSU's WriteData
input logic [1:0] width, input logic [6:0] LSUFunct7M, // ALU Operation
output logic [`XLEN-1:0] result input logic [2:0] LSUFunct3M, // Memoy access width
output logic [`XLEN-1:0] AMOResult // ALU output
); );
logic [`XLEN-1:0] a, b, y; logic [`XLEN-1:0] a, b, y;
@ -41,7 +43,7 @@ module amoalu (
// 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 (LSUFunct7M[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
@ -56,19 +58,19 @@ module amoalu (
// sign extend if necessary // sign extend if necessary
if (`XLEN == 32) begin:sext if (`XLEN == 32) begin:sext
assign a = srca; assign a = ReadDataM;
assign b = srcb; assign b = IHWriteDataM;
assign result = y; assign AMOResult = 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 (LSUFunct3M[1:0] == 2'b10) begin // sign-extend word-length operations
a = {{32{srca[31]}}, srca[31:0]}; a = {{32{ReadDataM[31]}}, ReadDataM[31:0]};
b = {{32{srcb[31]}}, srcb[31:0]}; b = {{32{IHWriteDataM[31]}}, IHWriteDataM[31:0]};
result = {{32{y[31]}}, y[31:0]}; AMOResult = {{32{y[31]}}, y[31:0]};
end else begin end else begin
a = srca; a = ReadDataM;
b = srcb; b = IHWriteDataM;
result = y; AMOResult = y;
end end
end end
endmodule endmodule

View File

@ -1,10 +1,13 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// atomic.sv // atomic.sv
// //
// Written: Ross Thompson ross1728@gmail.com January 31, 2022 // Written: Ross Thompson ross1728@gmail.com
// Modified: // Created: 31 January 2022
// Modified: 18 January 2023
// //
// Purpose: atomic data path. // Purpose: Wrapper for amoalu and lrsc
//
// Documentation: RISC-V System on Chip Design Chapter 14 (Figure ***)
// //
// A component of the CORE-V-WALLY configurable RISC-V project. // A component of the CORE-V-WALLY configurable RISC-V project.
// //
@ -28,25 +31,25 @@
module atomic ( module atomic (
input logic clk, input logic clk,
input logic reset, StallW, input logic reset,
input logic [`XLEN-1:0] ReadDataM, input logic StallW,
input logic [`XLEN-1:0] IHWriteDataM, input logic [`XLEN-1:0] ReadDataM, // LSU ReadData XLEN because FPU does not issue atomic memory operation from FPU registers
input logic [`PA_BITS-1:0] PAdrM, input logic [`XLEN-1:0] IHWriteDataM, // LSU WriteData XLEN because FPU does not issue atomic memory operation from FPU registers
input logic [6:0] LSUFunct7M, input logic [`PA_BITS-1:0] PAdrM, // Physical memory address
input logic [2:0] LSUFunct3M, input logic [6:0] LSUFunct7M, // AMO alu operation gated by HPTW
input logic [1:0] LSUAtomicM, input logic [2:0] LSUFunct3M, // IEU or HPTW memory operation size
input logic [1:0] PreLSURWM, input logic [1:0] LSUAtomicM, // 10: AMO operation, select AMOResult as the writedata output, 01: LR/SC operation
input logic IgnoreRequest, input logic [1:0] PreLSURWM, // IEU or HPTW Read/Write signal
output logic [`XLEN-1:0] IMAWriteDataM, input logic IgnoreRequest, // On FlushM or TLB miss ignore memory operation
output logic SquashSCW, output logic [`XLEN-1:0] IMAWriteDataM, // IEU, HPTW, or AMO write data
output logic [1:0] LSURWM output logic SquashSCW, // Store conditional failed disable write to GPR
output logic [1:0] LSURWM // IEU or HPTW Read/Write signal gated by LR/SC
); );
logic [`XLEN-1:0] AMOResult; logic [`XLEN-1:0] AMOResult;
logic MemReadM; logic MemReadM;
amoalu amoalu(.srca(ReadDataM), .srcb(IHWriteDataM), .funct(LSUFunct7M), .width(LSUFunct3M[1:0]), amoalu amoalu(.ReadDataM, .IHWriteDataM, .LSUFunct7M, .LSUFunct3M, .AMOResult);
.result(AMOResult));
mux2 #(`XLEN) wdmux(IHWriteDataM, AMOResult, LSUAtomicM[1], IMAWriteDataM); mux2 #(`XLEN) wdmux(IHWriteDataM, AMOResult, LSUAtomicM[1], IMAWriteDataM);
assign MemReadM = PreLSURWM[1] & ~IgnoreRequest; assign MemReadM = PreLSURWM[1] & ~IgnoreRequest;

View File

@ -1,10 +1,14 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// dtim.sv // dtim.sv
// //
// Written: Ross Thompson ross1728@gmail.com January 30, 2022 // Written: Ross Thompson ross1728@gmail.com
// Modified: // Created: 30 January 2022
// Modified: 18 January 2023
//
// Purpose: tightly integrated memory into the LSU.
//
// Documentation: RISC-V System on Chip Design Chapter 4 (Figure 4.12)
// //
// Purpose: simple memory with bus or cache.
// A component of the CORE-V-WALLY configurable RISC-V project. // A component of the CORE-V-WALLY configurable RISC-V project.
// //
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
@ -27,10 +31,10 @@
module dtim( module dtim(
input logic clk, input logic clk,
input logic ce, // Chip Enable
input logic [1:0] MemRWM, // Read/Write control
input logic [`PA_BITS-1:0] AdrM, // Execution stage memory address
input logic FlushW, input logic FlushW,
input logic ce, // Chip Enable. 0: Holds ReadDataWordM
input logic [1:0] MemRWM, // Read/Write control
input logic [`PA_BITS-1:0] DTIMAdr, // No stall: Execution stage memory address. Stall: Memory stage memory address
input logic [`LLEN-1:0] WriteDataM, // Write data from IEU input logic [`LLEN-1:0] WriteDataM, // Write data from IEU
input logic [`LLEN/8-1:0] ByteMaskM, // Selects which bytes within a word to write input logic [`LLEN/8-1:0] ByteMaskM, // Selects which bytes within a word to write
output logic [`LLEN-1:0] ReadDataWordM // Read data before subword selection output logic [`LLEN-1:0] ReadDataWordM // Read data before subword selection
@ -44,6 +48,6 @@ module dtim(
assign we = MemRWM[0] & ~FlushW; // have to ignore write if Trap. assign we = MemRWM[0] & ~FlushW; // have to ignore write if Trap.
ram1p1rwbe #(.DEPTH(`DTIM_RANGE/8), .WIDTH(`LLEN)) ram1p1rwbe #(.DEPTH(`DTIM_RANGE/8), .WIDTH(`LLEN))
ram(.clk, .ce, .we, .bwe(ByteMaskM), .addr(AdrM[ADDR_WDITH+OFFSET-1:OFFSET]), .dout(ReadDataWordM), .din(WriteDataM)); ram(.clk, .ce, .we, .bwe(ByteMaskM), .addr(DTIMAdr[ADDR_WDITH+OFFSET-1:OFFSET]), .dout(ReadDataWordM), .din(WriteDataM));
endmodule endmodule

View File

@ -1,8 +1,9 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// endianswap.sv // endianswap.sv
// //
// Written: David_Harris@hmc.edu 7 May 2022 // Written: David_Harris@hmc.edu
// Modified: // Created: 7 May 2022
// Modified: 18 January 2023
// //
// Purpose: Swap byte order for Big-Endian accesses // Purpose: Swap byte order for Big-Endian accesses
// //

View File

@ -1,12 +1,15 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// lrsc.sv // lrsc.sv
// //
// Written: David_Harris@hmc.edu 17 July 2021 // Written: David_Harris@hmc.edu
// Modified: // Created: 17 July 2021
// Modified: 18 January 2023
// //
// Purpose: Load Reserved / Store Conditional unit // Purpose: Load Reserved / Store Conditional unit
// Track the reservation and squash the store if it fails // Track the reservation and squash the store if it fails
// //
// Documentation: RISC-V System on Chip Design Chapter 14 (Figure ***)
//
// A component of the CORE-V-WALLY configurable RISC-V project. // A component of the CORE-V-WALLY configurable RISC-V project.
// //
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University

View File

@ -131,7 +131,7 @@ module lsu (
logic LSULoadAccessFaultM; // Load acces fault logic LSULoadAccessFaultM; // Load acces fault
logic LSUStoreAmoAccessFaultM; // Store access fault logic LSUStoreAmoAccessFaultM; // Store access fault
logic IgnoreRequestTLB; // On either ITLB or DTLB miss, ignore miss so HPTW can handle logic IgnoreRequestTLB; // On either ITLB or DTLB miss, ignore miss so HPTW can handle
logic IgnoreRequest; // On FlushM, ignore TLB miss logic IgnoreRequest; // On FlushM or TLB miss ignore memory operation
logic SelDTIM; // Select DTIM rather than bus or D$ logic SelDTIM; // Select DTIM rather than bus or D$
@ -232,17 +232,19 @@ module lsu (
// **** fix ReadDataWordM to be LLEN. ByteMask is wrong length. // **** fix ReadDataWordM to be LLEN. ByteMask is wrong length.
// **** create config to support DTIM with floating point. // **** create config to support DTIM with floating point.
dtim dtim(.clk, .ce(~GatedStallW), .MemRWM(DTIMMemRWM), dtim dtim(.clk, .ce(~GatedStallW), .MemRWM(DTIMMemRWM),
.AdrM(DTIMAdr), .FlushW, .WriteDataM(LSUWriteDataM), .DTIMAdr, .FlushW, .WriteDataM(LSUWriteDataM),
.ReadDataWordM(DTIMReadDataWordM[`XLEN-1:0]), .ByteMaskM(ByteMaskM[`XLEN/8-1:0])); .ReadDataWordM(DTIMReadDataWordM[`XLEN-1:0]), .ByteMaskM(ByteMaskM[`XLEN/8-1:0]));
end else begin end else begin
end end
if (`BUS) begin : bus if (`BUS) begin : bus
localparam integer LLENWORDSPERLINE = `DCACHE ? `DCACHE_LINELENINBITS/`LLEN : 1; // Number of LLEN words in cacheline
localparam integer LLENLOGBWPL = `DCACHE ? $clog2(LLENWORDSPERLINE) : 1; // Log2 of ^
localparam integer BEATSPERLINE = `DCACHE ? `DCACHE_LINELENINBITS/`AHBW : 1; // Number of AHBW words (beats) in cacheline
localparam integer AHBWLOGBWPL = `DCACHE ? $clog2(BEATSPERLINE) : 1; // Log2 of ^
if(`DCACHE) begin : dcache if(`DCACHE) begin : dcache
localparam integer LINELEN = `DCACHE ? `DCACHE_LINELENINBITS : `XLEN; // Number of bytes in cacheline localparam integer LLENWORDSPERLINE = `DCACHE_LINELENINBITS/`LLEN; // Number of LLEN words in cacheline
localparam integer LLENLOGBWPL = $clog2(LLENWORDSPERLINE); // Log2 of ^
localparam integer BEATSPERLINE = `DCACHE_LINELENINBITS/`AHBW; // Number of AHBW words (beats) in cacheline
localparam integer AHBWLOGBWPL = $clog2(BEATSPERLINE); // Log2 of ^
localparam integer LINELEN = `DCACHE_LINELENINBITS; // Number of bits in cacheline
localparam integer LLENPOVERAHBW = `LLEN / `AHBW; // Number of AHB beats in a LLEN word. AHBW cannot be larger than LLEN. (implementation limitation)
logic [LINELEN-1:0] FetchBuffer; // Temporary buffer to hold partially fetched cacheline logic [LINELEN-1:0] FetchBuffer; // Temporary buffer to hold partially fetched cacheline
logic [`PA_BITS-1:0] DCacheBusAdr; // Cacheline address to fetch or writeback. logic [`PA_BITS-1:0] DCacheBusAdr; // Cacheline address to fetch or writeback.
logic [AHBWLOGBWPL-1:0] BeatCount; // Position within a cacheline. ahbcacheinterface to cache logic [AHBWLOGBWPL-1:0] BeatCount; // Position within a cacheline. ahbcacheinterface to cache
@ -250,7 +252,6 @@ module lsu (
logic SelBusBeat; // ahbcacheinterface selects postion in cacheline with BeatCount logic SelBusBeat; // ahbcacheinterface selects postion in cacheline with BeatCount
logic [1:0] CacheBusRW; // Cache sends request to ahbcacheinterface logic [1:0] CacheBusRW; // Cache sends request to ahbcacheinterface
logic [1:0] BusRW; // Uncached bus memory access logic [1:0] BusRW; // Uncached bus memory access
localparam integer LLENPOVERAHBW = `LLEN / `AHBW; // Number of AHB beats in a LLEN word. AHBW cannot be larger than LLEN. (implementation limitation)
logic CacheableOrFlushCacheM; // Memory address is cacheable or operation is a cache flush logic CacheableOrFlushCacheM; // Memory address is cacheable or operation is a cache flush
logic [1:0] CacheRWM; // Cache read (10), write (01), AMO (11) logic [1:0] CacheRWM; // Cache read (10), write (01), AMO (11)
logic [1:0] CacheAtomicM; // Cache AMO logic [1:0] CacheAtomicM; // Cache AMO
@ -272,7 +273,7 @@ module lsu (
.FetchBuffer, .CacheBusRW, .FetchBuffer, .CacheBusRW,
.CacheBusAck(DCacheBusAck), .InvalidateCache(1'b0)); .CacheBusAck(DCacheBusAck), .InvalidateCache(1'b0));
ahbcacheinterface #(.BEATSPERLINE(BEATSPERLINE), .LINELEN(LINELEN), .LOGWPL(AHBWLOGBWPL), .LLENPOVERAHBW(LLENPOVERAHBW)) ahbcacheinterface( ahbcacheinterface #(.BEATSPERLINE(BEATSPERLINE), .AHBWLOGBWPL(AHBWLOGBWPL), .LINELEN(LINELEN), .LLENPOVERAHBW(LLENPOVERAHBW)) ahbcacheinterface(
.HCLK(clk), .HRESETn(~reset), .Flush(FlushW), .HCLK(clk), .HRESETn(~reset), .Flush(FlushW),
.HRDATA, .HWDATA(LSUHWDATA), .HWSTRB(LSUHWSTRB), .HRDATA, .HWDATA(LSUHWDATA), .HWSTRB(LSUHWSTRB),
.HSIZE(LSUHSIZE), .HBURST(LSUHBURST), .HTRANS(LSUHTRANS), .HWRITE(LSUHWRITE), .HREADY(LSUHREADY), .HSIZE(LSUHSIZE), .HBURST(LSUHBURST), .HTRANS(LSUHTRANS), .HWRITE(LSUHWRITE), .HREADY(LSUHREADY),

View File

@ -1,11 +1,14 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// subwordread.sv // subwordread.sv
// //
// Written: David_Harris@hmc.edu 9 January 2021 // Written: David_Harris@hmc.edu
// Modified: // Created: 9 January 2021
// Modified: 18 January 2023
// //
// Purpose: Extract subwords and sign extend for reads // Purpose: Extract subwords and sign extend for reads
// //
// Documentation: RISC-V System on Chip Design Chapter 4 (Figure 4.9)
//
// A component of the CORE-V-WALLY configurable RISC-V project. // A component of the CORE-V-WALLY configurable RISC-V project.
// //
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University

View File

@ -1,11 +1,14 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// subwordwrite.sv // subwordwrite.sv
// //
// Written: David_Harris@hmc.edu 9 January 2021 // Written: David_Harris@hmc.edu
// Modified: // Created: 9 January 2021
// Modified: 18 January 2023
// //
// Purpose: Masking and muxing for subword writes // Purpose: Masking and muxing for subword writes
// //
// Documentation: RISC-V System on Chip Design Chapter 4 (Figure 4.9)
//
// A component of the CORE-V-WALLY configurable RISC-V project. // A component of the CORE-V-WALLY configurable RISC-V project.
// //
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University

View File

@ -1,11 +1,14 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// swbytemask.sv // swbytemask.sv
// //
// Written: David_Harris@hmc.edu 9 January 2021 // Written: David_Harris@hmc.edu
// Modified: // Created: 9 January 2021
// Modified: 18 January 2023
// //
// Purpose: On-chip RAM, external to core // Purpose: On-chip RAM, external to core
// //
// Documentation: RISC-V System on Chip Design Chapter 4 (Figure 4.9)
//
// A component of the CORE-V-WALLY configurable RISC-V project. // A component of the CORE-V-WALLY configurable RISC-V project.
// //
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University