[flash_ctrl] Replace tlul_to_fifo with tlul_adapter_sram
- Add ErrOnRead in adapter_sram
- Adapter sram expects sram-like behavior and waits for data
to be available in the next cycle
diff --git a/hw/ip/flash_ctrl/flash_ctrl.core b/hw/ip/flash_ctrl/flash_ctrl.core
index de905c7..9db1e8d 100644
--- a/hw/ip/flash_ctrl/flash_ctrl.core
+++ b/hw/ip/flash_ctrl/flash_ctrl.core
@@ -18,7 +18,6 @@
- rtl/flash_erase_ctrl.sv
- rtl/flash_prog_ctrl.sv
- rtl/flash_rd_ctrl.sv
- - rtl/flash_tlul_to_fifo.sv
- rtl/flash_mp.sv
- rtl/flash_phy.sv
file_type: systemVerilogSource
diff --git a/hw/ip/flash_ctrl/rtl/flash_ctrl.sv b/hw/ip/flash_ctrl/rtl/flash_ctrl.sv
index f3e770d..e7e4a93 100644
--- a/hw/ip/flash_ctrl/rtl/flash_ctrl.sv
+++ b/hw/ip/flash_ctrl/rtl/flash_ctrl.sv
@@ -74,7 +74,8 @@
// FIFO Connections
logic prog_fifo_wready;
logic prog_fifo_rvalid;
- logic prog_fifo_wvalid;
+ logic prog_fifo_req;
+ logic prog_fifo_wen;
logic prog_fifo_ren;
logic [DataWidth-1:0] prog_fifo_wdata;
logic [DataWidth-1:0] prog_fifo_rdata;
@@ -127,20 +128,25 @@
// Since the program and read FIFOs are never used at the same time, it should really be one
// FIFO with muxed inputs and outputs. This should be addressed once the flash integration
// strategy has been identified
- flash_tlul_to_fifo #(
- .Size(DataWidth),
- .Dir(0)
+ tlul_adapter_sram #(
+ .SramAw(1), //address unused
+ .SramDw(DataWidth),
+ .ByteAccess(0), //flash may not support byte access
+ .ErrOnRead(1) //reads not supported
) u_to_prog_fifo (
.clk_i,
.rst_ni,
- .tl_i (tl_fifo_h2d[0]),
- .tl_o (tl_fifo_d2h[0]),
- .fifo_wen_o (prog_fifo_wvalid),
- .fifo_wdata_o (prog_fifo_wdata),
- .fifo_full_i (~prog_fifo_wready),
- .fifo_ren_o (),
- .fifo_empty_i (1'b1),
- .fifo_rdata_i ('0)
+ .tl_i (tl_fifo_h2d[0]),
+ .tl_o (tl_fifo_d2h[0]),
+ .req_o (prog_fifo_req),
+ .gnt_i (prog_fifo_wready),
+ .we_o (prog_fifo_wen),
+ .addr_o (),
+ .wmask_o (),
+ .wdata_o (prog_fifo_wdata),
+ .rdata_i (DataWidth'(0)),
+ .rvalid_i (1'b0),
+ .rerror_i (2'b0)
);
prim_fifo_sync #(
@@ -149,7 +155,7 @@
) u_prog_fifo (
.clk_i,
.rst_ni (rst_ni & ~reg2hw.control.fifo_rst.q),
- .wvalid (prog_fifo_wvalid),
+ .wvalid (prog_fifo_req & prog_fifo_wen),
.wready (prog_fifo_wready),
.wdata (prog_fifo_wdata),
.depth (prog_fifo_depth),
@@ -188,21 +194,35 @@
);
// Read FIFO
- flash_tlul_to_fifo #(
- .Size(DataWidth),
- .Dir(1) //change this to something in package file later
+ logic adapter_rvalid;
+ always_ff @(posedge clk_i or negedge rst_ni) begin
+ if (!rst_ni) begin
+ adapter_rvalid <= 1'b0;
+ end else begin
+ adapter_rvalid <= rd_fifo_ren && rd_fifo_rvalid;
+ end
+ end
+
+ tlul_adapter_sram #(
+ .SramAw(1), //address unused
+ .SramDw(DataWidth),
+ .ByteAccess(0), //flash may not support byte access
+ .ErrOnWrite(1) //writes not supported
) u_to_rd_fifo (
.clk_i,
.rst_ni,
- .tl_i (tl_fifo_h2d[1]),
- .tl_o (tl_fifo_d2h[1]),
- .fifo_wen_o (),
- .fifo_wdata_o (),
- .fifo_full_i (1'b1),
- .fifo_ren_o (rd_fifo_ren),
- .fifo_empty_i (~rd_fifo_rvalid),
- .fifo_rdata_i (rd_fifo_rdata)
- );
+ .tl_i (tl_fifo_h2d[1]),
+ .tl_o (tl_fifo_d2h[1]),
+ .req_o (rd_fifo_ren),
+ .gnt_i (rd_fifo_rvalid),
+ .we_o (),
+ .addr_o (),
+ .wmask_o (),
+ .wdata_o (),
+ .rdata_i (rd_fifo_rdata),
+ .rvalid_i (adapter_rvalid),
+ .rerror_i (2'b0)
+ );
prim_fifo_sync #(
.Width(DataWidth),
@@ -215,7 +235,9 @@
.wdata (rd_fifo_wdata),
.depth (rd_fifo_depth),
.rvalid (rd_fifo_rvalid),
- .rready (rd_fifo_ren),
+ //adapter_rvalid is used here because adapter_sram does not accept data the same cycle.
+ //It expects an sram like interface where data arrives during the next cycle
+ .rready (adapter_rvalid),
.rdata (rd_fifo_rdata)
);
diff --git a/hw/ip/flash_ctrl/rtl/flash_tlul_to_fifo.sv b/hw/ip/flash_ctrl/rtl/flash_tlul_to_fifo.sv
deleted file mode 100644
index 1f8da5f..0000000
--- a/hw/ip/flash_ctrl/rtl/flash_tlul_to_fifo.sv
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright lowRISC contributors.
-// Licensed under the Apache License, Version 2.0, see LICENSE for details.
-// SPDX-License-Identifier: Apache-2.0
-//
-// tlul to wfifo interface
-//
-//
-
-module flash_tlul_to_fifo #(
- parameter Dir = 0, //write0, read1
- parameter Size = 32
-) (
- input clk_i,
- input rst_ni,
- input tlul_pkg::tl_h2d_t tl_i,
- output tlul_pkg::tl_d2h_t tl_o,
- output fifo_wen_o,
- output [Size-1:0] fifo_wdata_o,
- input fifo_full_i,
- output fifo_ren_o,
- input fifo_empty_i,
- input [Size-1:0] fifo_rdata_i
-);
-
- import tlul_pkg::*;
- import flash_ctrl_pkg::*;
-
- // This module just takes a tlul input interface and converts it to a FIFO wr side interface
- // Normally this can easily wired up, but this module will be used to to do some basic error
- // checking and response generation
-
- logic accepted;
- logic [top_pkg::TL_SZW-1:0] size;
- logic [top_pkg::TL_AIW-1:0] source;
- logic err;
- logic vld_op;
- logic req_stall;
- logic rsp_stall;
-
- if (Dir == WriteDir) begin : gen_valid_wr_ops
- // Only support write operations
- assign vld_op = tl_i.a_opcode == PutFullData | tl_i.a_opcode == PutPartialData;
- assign req_stall = fifo_full_i | rsp_stall;
- assign tl_o.d_opcode = AccessAck;
- end else begin : gen_valid_rd_ops
- // Only support read operations
- assign vld_op = tl_i.a_opcode == Get;
- assign req_stall = fifo_empty_i | rsp_stall;
- assign tl_o.d_opcode = AccessAckData;
- end
-
- // If a response is held of by host, stop accepting new requests
- assign rsp_stall = accepted & ~tl_i.d_ready;
-
- // assignments to fifo interface
- assign fifo_wen_o = tl_i.a_valid & ~req_stall;
- assign fifo_wdata_o = tl_i.a_data;
- assign fifo_ren_o = accepted;
-
- // Generate response on the following cycle of request acceptance
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- accepted <= 1'b0;
- size <= '0;
- source <= '0;
- err <= '0;
- end else if (fifo_wen_o) begin
- accepted <= 1'b1;
- size <= tl_i.a_size;
- source <= tl_i.a_source;
- err <= ~vld_op;
- end else if (accepted && tl_i.d_ready) begin
- accepted <= 1'b0;
- err <= 1'b0;
- end
- end
-
- // assignments to tlul interface
- assign tl_o.d_valid = accepted;
- assign tl_o.d_param = '0;
- assign tl_o.d_size = size;
- assign tl_o.d_source = source;
- assign tl_o.d_sink = 1'b0;
- assign tl_o.d_data = fifo_rdata_i;
- assign tl_o.d_user = '0;
- assign tl_o.d_error = err;
- assign tl_o.a_ready = ~req_stall;
-
-
- //unused nets
- logic [top_pkg::TL_AW-1:0] unused_addr;
- logic [top_pkg::TL_DBW-1:0] unused_mask;
- logic [2:0] unused_param;
- tl_a_user_t unused_user_bits;
- logic unused_full;
- logic unused_empty;
-
- assign unused_addr = tl_i.a_address;
- assign unused_mask = tl_i.a_mask;
- assign unused_param = tl_i.a_param;
- assign unused_user_bits = tl_i.a_user;
-
- if (Dir == WriteDir) begin : gen_wr_unused
- assign unused_empty = fifo_empty_i;
- assign unused_full = 1'b0;
- end else begin : gen_rd_unused
- assign unused_full = fifo_full_i;
- assign unused_empty = 1'b0;
- end
-
-
-
-endmodule // flash_tlul_to_wfifo
diff --git a/hw/ip/tlul/rtl/tlul_adapter_sram.sv b/hw/ip/tlul/rtl/tlul_adapter_sram.sv
index ea8ca68..0d76cea 100644
--- a/hw/ip/tlul/rtl/tlul_adapter_sram.sv
+++ b/hw/ip/tlul/rtl/tlul_adapter_sram.sv
@@ -14,7 +14,8 @@
parameter int SramDw = 32, // Current version supports TL-UL width only
parameter int Outstanding = 1, // Only one request is accepted
parameter bit ByteAccess = 1, // 1: true, 0: false
- parameter bit ErrOnWrite = 0 // 1: Writes not allowed, automatically error
+ parameter bit ErrOnWrite = 0, // 1: Writes not allowed, automatically error
+ parameter bit ErrOnRead = 0 // 1: Reads not allowed, automatically error
) (
input clk_i,
input rst_ni,
@@ -76,6 +77,7 @@
logic error_internal; // Internal protocol error checker
logic wr_attr_error;
logic wr_vld_error;
+ logic rd_vld_error;
logic tlul_error; // Error from `tlul_err` module
logic a_ack, d_ack, unused_sram_ack;
@@ -168,6 +170,12 @@
assign wr_vld_error = 1'b0;
end
+ if (ErrOnRead == 1) begin: gen_no_reads
+ assign rd_vld_error = tl_i.a_opcode == Get;
+ end else begin : gen_reads_allowed
+ assign rd_vld_error = 1'b0;
+ end
+
tlul_err u_err (
.clk_i,
.rst_ni,
@@ -175,7 +183,7 @@
.err_o (tlul_error)
);
- assign error_internal = wr_attr_error | wr_vld_error | tlul_error;
+ assign error_internal = wr_attr_error | wr_vld_error | rd_vld_error | tlul_error;
//-- End: Request Error Detection -------------------------------------------
assign reqfifo_wvalid = a_ack ; // Push to FIFO only when granted
@@ -255,4 +263,7 @@
// even though the RspFifo is full)
`ASSERT(rvalidHighWhenRspFifoFull, rvalid_i |-> rspfifo_wready, clk_i, !rst_ni)
+ // If both ErrOnWrite and ErrOnRead are set, this block is useless
+ `ASSERT_INIT(adapterNoReadOrWrite, (ErrOnWrite & ErrOnRead) == 0)
+
endmodule