diff options
Diffstat (limited to 'fpga/usrp3/lib/zynq_fifo/zf_stream_to_host.v')
-rw-r--r-- | fpga/usrp3/lib/zynq_fifo/zf_stream_to_host.v | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/fpga/usrp3/lib/zynq_fifo/zf_stream_to_host.v b/fpga/usrp3/lib/zynq_fifo/zf_stream_to_host.v new file mode 100644 index 000000000..b85b56ab8 --- /dev/null +++ b/fpga/usrp3/lib/zynq_fifo/zf_stream_to_host.v @@ -0,0 +1,154 @@ +////////////////////////////////////////////////////////////////////////////////// +// +// Copyright Ettus Research LLC +// Copyright 2014 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: LGPL-3.0-or-later +// +// The ZYNQ FIFO - read FIFO and write to DDR: +// - implements write state machine for AXI master on DDR +// - provides input fifos from external fabric +////////////////////////////////////////////////////////////////////////////////// + + +//This implementation takes many states to do individual +//64 bit xfers from FIFO to the AXI write master. +//TODO: use axi 4/full with busts, +//in this case we should be able to directly connect the fifo +//to the write lines with much less state machinery. + +module zf_stream_to_host +#( + parameter PROT = 3'b010, //data, non-secure, unpriv + parameter STRB = 4'b1111 //write all bytes +) +( + input clk, + input rst, + input enb, + + //------------------------------------------------------------------ + //-- DDR write signals - master + //------------------------------------------------------------------ + output [31:0] AXI_AWADDR, + output [2:0] AXI_AWPROT, + output AXI_AWVALID, + input AXI_AWREADY, + output [63:0] AXI_WDATA, + output [3:0] AXI_WSTRB, + output AXI_WVALID, + input AXI_WREADY, + input [1:0] AXI_BRESP, + input AXI_BVALID, + output AXI_BREADY, + + //------------------------------------------------------------------ + // FIFO streaming interfaces + //------------------------------------------------------------------ + input [63:0] i_tdata, + input i_tlast, + input i_tvalid, + output i_tready, + + //------------------------------------------------------------------ + // configuration interface + //------------------------------------------------------------------ + input [31:0] mem_addr, + input mem_valid, + output mem_ack, + + output [31:0] debug +); + +//////////////////////////////////////////////////////////////////////// +///////////////////////////// Begin R T L ////////////////////////////// +//////////////////////////////////////////////////////////////////////// + + localparam STATE_WAIT_MEM = 0; + localparam STATE_READ_LINE = 1; + localparam STATE_WRITE_ADDR = 2; + localparam STATE_WRITE_DATA = 3; + localparam STATE_WRITE_B = 4; + localparam STATE_DONE = 5; + + reg [31:0] base_addr; + reg [63:0] line; + reg last; + + reg [2:0] state; + always @(posedge clk) begin + if (rst) begin + state <= STATE_WAIT_MEM; + base_addr <= 0; + line <= 0; + last <= 0; + end + else if (enb) case (state) + STATE_WAIT_MEM: begin + if (mem_valid) begin + state <= STATE_READ_LINE; + end + base_addr <= mem_addr; + end + + STATE_READ_LINE: begin + if (i_tvalid && i_tready) begin + line <= i_tdata; + last <= i_tlast; + state <= STATE_WRITE_ADDR; + end + end + + STATE_WRITE_ADDR: begin + if (AXI_AWVALID && AXI_AWREADY) begin + state <= STATE_WRITE_DATA; + end + end + + STATE_WRITE_DATA: begin + if (AXI_WVALID && AXI_WREADY) begin + state <= STATE_WRITE_B; + end + end + + STATE_WRITE_B: begin + if (AXI_BREADY && AXI_BVALID) begin//FIXME, slave may not assert valid + if (last) state <= STATE_DONE; + else state <= STATE_READ_LINE; + base_addr <= base_addr + 32'h8; + end + end + + STATE_DONE: begin + state <= STATE_WAIT_MEM; + end + + default: state <= STATE_WAIT_MEM; + + endcase //state + end + + assign i_tready = (state == STATE_READ_LINE); + assign mem_ack = (state == STATE_DONE); + + //assign to master write + assign AXI_AWVALID = (state == STATE_WRITE_ADDR); + assign AXI_WVALID = (state == STATE_WRITE_DATA); + assign AXI_AWADDR = base_addr; + assign AXI_WDATA = {line[31:0], line[63:32]}; + + assign AXI_WSTRB = STRB; + assign AXI_AWPROT = PROT; + assign AXI_BREADY = (state == STATE_WRITE_B); + + assign debug[2:0] = state; + assign debug[4] = mem_valid; + assign debug[5] = mem_ack; + assign debug[6] = AXI_AWVALID; + assign debug[7] = AXI_AWREADY; + assign debug[8] = AXI_WVALID; + assign debug[9] = AXI_WREADY; + assign debug[10] = AXI_BVALID; + assign debug[11] = AXI_BREADY; + +endmodule //zf_stream_to_host |