cvw/pipelined/src/ebu/ahblite.sv

147 lines
6.6 KiB
Systemverilog
Raw Normal View History

2021-01-29 06:07:17 +00:00
///////////////////////////////////////////
// ahblite.sv
//
// Written: David_Harris@hmc.edu 9 January 2021
// Modified:
//
// Purpose: AHB Lite External Bus Unit
// See ARM_HIH0033A_AMBA_AHB-Lite_SPEC 1.0
// Arbitrates requests from instruction and data streams
// Connects core to peripherals and I/O pins on SOC
2021-01-29 06:07:17 +00:00
// Bus width presently matches XLEN
// Anticipate replacing this with an AXI bus interface to communicate with FPGA DRAM/Flash controllers
//
// A component of the Wally configurable RISC-V project.
//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
//
// MIT LICENSE
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
2021-01-29 06:07:17 +00:00
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
2021-01-29 06:07:17 +00:00
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
// OR OTHER DEALINGS IN THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////////////////////
2021-01-29 06:07:17 +00:00
`include "wally-config.vh"
module ahblite (
2021-12-17 20:40:25 +00:00
input logic clk, reset,
2021-01-30 04:43:48 +00:00
// Load control
2021-12-17 20:40:25 +00:00
input logic UnsignedLoadM,
input logic [1:0] AtomicMaskedM,
2021-01-29 06:07:17 +00:00
// Signals from Instruction Cache
input logic [`PA_BITS-1:0] IFUBusAdr,
input logic IFUBusRead,
output logic [`XLEN-1:0] IFUBusHRDATA,
output logic IFUBusAck,
2021-01-29 06:07:17 +00:00
// Signals from Data Cache
input logic [`PA_BITS-1:0] LSUBusAdr,
input logic LSUBusRead,
input logic LSUBusWrite,
input logic [`XLEN-1:0] LSUBusHWDATA,
output logic [`XLEN-1:0] LSUBusHRDATA,
input logic [2:0] LSUBusSize,
output logic LSUBusAck,
2021-01-29 06:07:17 +00:00
// AHB-Lite external signals
2021-12-17 20:40:25 +00:00
(* mark_debug = "true" *) input logic [`AHBW-1:0] HRDATA,
(* mark_debug = "true" *) input logic HREADY, HRESP,
(* mark_debug = "true" *) output logic HCLK, HRESETn,
2022-01-15 00:11:30 +00:00
(* mark_debug = "true" *) output logic [31:0] HADDR, // *** one day switch to a different bus that supports the full physical address
2021-12-17 20:40:25 +00:00
(* mark_debug = "true" *) output logic [`AHBW-1:0] HWDATA,
(* mark_debug = "true" *) output logic HWRITE,
(* mark_debug = "true" *) output logic [2:0] HSIZE,
(* mark_debug = "true" *) output logic [2:0] HBURST,
(* mark_debug = "true" *) output logic [3:0] HPROT,
(* mark_debug = "true" *) output logic [1:0] HTRANS,
(* mark_debug = "true" *) output logic HMASTLOCK,
2021-02-15 15:10:50 +00:00
// Delayed signals for writes
2021-12-17 20:40:25 +00:00
(* mark_debug = "true" *) output logic [2:0] HADDRD,
(* mark_debug = "true" *) output logic [3:0] HSIZED,
(* mark_debug = "true" *) output logic HWRITED
2021-01-29 06:07:17 +00:00
);
2022-02-11 01:15:16 +00:00
typedef enum logic [1:0] {IDLE, MEMREAD, MEMWRITE, INSTRREAD} statetype;
statetype BusState, NextBusState;
2021-01-29 06:07:17 +00:00
logic GrantData;
logic [31:0] AccessAddress;
logic [2:0] ISize;
2021-01-29 06:07:17 +00:00
assign HCLK = clk;
assign HRESETn = ~reset;
2021-10-23 17:12:33 +00:00
// initially support AHBW = XLEN
2021-01-29 06:07:17 +00:00
2021-02-08 04:21:55 +00:00
// track bus state
2021-02-15 15:10:50 +00:00
// Data accesses have priority over instructions. However, if a data access comes
// while an instruction read is occuring, the instruction read finishes before
// the data access can take place.
flopenl #(.TYPE(statetype)) busreg(HCLK, ~HRESETn, 1'b1, NextBusState, IDLE, BusState);
2021-02-15 15:10:50 +00:00
// This case statement computes the desired next state for the AHBlite,
// prioritizing address translations, then atomics, then data accesses, and
// finally instructions. This proposition controls HADDR so the PMA and PMP
// checkers can determine whether the access is allowed. If not, the actual
// NextWalkerState is set to IDLE.
// *** This ability to squash accesses must be replicated by any bus
// interface that might be used in place of the ahblite.
2021-02-15 15:10:50 +00:00
always_comb
case (BusState)
IDLE: if (LSUBusRead) NextBusState = MEMREAD; // Memory has priority over instructions
else if (LSUBusWrite)NextBusState = MEMWRITE;
else if (IFUBusRead) NextBusState = INSTRREAD;
else NextBusState = IDLE;
MEMREAD: if (~HREADY) NextBusState = MEMREAD;
else if (IFUBusRead) NextBusState = INSTRREAD;
else NextBusState = IDLE;
MEMWRITE: if (~HREADY) NextBusState = MEMWRITE;
else if (IFUBusRead) NextBusState = INSTRREAD;
else NextBusState = IDLE;
INSTRREAD: if (~HREADY) NextBusState = INSTRREAD;
else NextBusState = IDLE; // if (IFUBusRead still high)
default: NextBusState = IDLE;
2021-02-15 15:10:50 +00:00
endcase
2021-02-15 15:10:50 +00:00
// bus outputs
assign #1 GrantData = (NextBusState == MEMREAD) | (NextBusState == MEMWRITE);
assign #1 AccessAddress = (GrantData) ? LSUBusAdr[31:0] : IFUBusAdr[31:0];
assign #1 HADDR = AccessAddress;
2021-02-26 06:03:47 +00:00
assign ISize = 3'b010; // 32 bit instructions for now; later improve for filling cache with full width; ignored on reads anyway
assign HSIZE = (GrantData) ? {1'b0, LSUBusSize[1:0]} : ISize;
2021-02-15 15:10:50 +00:00
assign HBURST = 3'b000; // Single burst only supported; consider generalizing for cache fillsfH
assign HPROT = 4'b0011; // not used; see Section 3.7
assign HTRANS = (NextBusState != IDLE) ? 2'b10 : 2'b00; // NONSEQ if reading or writing, IDLE otherwise
assign HMASTLOCK = 0; // no locking supported
2021-08-26 03:53:20 +00:00
assign HWRITE = NextBusState == MEMWRITE;
2021-03-31 02:19:27 +00:00
// delay write data by one cycle for
flop #(`XLEN) wdreg(HCLK, LSUBusHWDATA, HWDATA); // delay HWDATA by 1 cycle per spec; *** assumes AHBW = XLEN
2021-02-15 15:10:50 +00:00
// delay signals for subword writes
flop #(3) adrreg(HCLK, HADDR[2:0], HADDRD);
flop #(4) sizereg(HCLK, {UnsignedLoadM, HSIZE}, HSIZED);
flop #(1) writereg(HCLK, HWRITE, HWRITED);
2021-02-22 18:48:30 +00:00
// Route signals to Instruction and Data Caches
// *** assumes AHBW = XLEN
2021-02-24 12:25:03 +00:00
assign IFUBusHRDATA = HRDATA;
assign LSUBusHRDATA = HRDATA;
assign IFUBusAck = (BusState == INSTRREAD) & (NextBusState != INSTRREAD);
assign LSUBusAck = (BusState == MEMREAD) & (NextBusState != MEMREAD) | (BusState == MEMWRITE) & (NextBusState != MEMWRITE);
2021-01-29 06:07:17 +00:00
endmodule