140 lines
4.1 KiB
Verilog
140 lines
4.1 KiB
Verilog
//////////////////////////////////////////////////////////////////////////////////
|
|
// Copyright Ettus Research LLC
|
|
// The ZYNQ FIFO - read DDR and write to FIFO:
|
|
// - implements read state machine for AXI master on DDR
|
|
// - provides output fifos to external fabric
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
module zf_host_to_stream
|
|
#(
|
|
parameter PROT = 3'b010 //data, non-secure, unpriv
|
|
)
|
|
(
|
|
input clk,
|
|
input rst,
|
|
input enb,
|
|
|
|
//------------------------------------------------------------------
|
|
//-- DDR read signals - master
|
|
//------------------------------------------------------------------
|
|
output [31:0] AXI_ARADDR,
|
|
output [2:0] AXI_ARPROT,
|
|
output AXI_ARVALID,
|
|
input AXI_ARREADY,
|
|
input [63:0] AXI_RDATA,
|
|
input [1:0] AXI_RRESP,
|
|
input AXI_RVALID,
|
|
output AXI_RREADY,
|
|
|
|
//------------------------------------------------------------------
|
|
// FIFO streaming interfaces
|
|
//------------------------------------------------------------------
|
|
output [63:0] o_tdata,
|
|
output o_tlast,
|
|
output o_tvalid,
|
|
input o_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_WRITE_ADDR = 1;
|
|
localparam STATE_READ_DATA = 2;
|
|
localparam STATE_WRITE_LINE = 3;
|
|
localparam STATE_DONE = 4;
|
|
|
|
reg [31:0] base_addr;
|
|
reg [63:0] line;
|
|
reg [15:0] line32_count;
|
|
reg first_line;
|
|
|
|
reg [2:0] state;
|
|
always @(posedge clk) begin
|
|
if (rst) begin
|
|
state <= STATE_WAIT_MEM;
|
|
base_addr <= 0;
|
|
line <= 0;
|
|
line32_count <= 0;
|
|
first_line <= 1;
|
|
end
|
|
else if (enb) case (state)
|
|
STATE_WAIT_MEM: begin
|
|
if (mem_valid) begin
|
|
state <= STATE_WRITE_ADDR;
|
|
end
|
|
base_addr <= mem_addr;
|
|
first_line <= 1;
|
|
end
|
|
|
|
STATE_WRITE_ADDR: begin
|
|
if (AXI_ARVALID && AXI_ARREADY) begin
|
|
state <= STATE_READ_DATA;
|
|
end
|
|
end
|
|
|
|
STATE_READ_DATA: begin
|
|
if (AXI_RVALID && AXI_RREADY) begin
|
|
line <= AXI_RDATA;
|
|
state <= STATE_WRITE_LINE;
|
|
if (first_line) begin
|
|
//round up to multiple of 64 minus one line
|
|
//Note! words32 are swapped here, inspect lower for length
|
|
line32_count <= AXI_RDATA[15:0] - 16'b1;
|
|
first_line <= 0;
|
|
end
|
|
end
|
|
end
|
|
|
|
STATE_WRITE_LINE: begin
|
|
if (o_tvalid && o_tready) begin
|
|
if (o_tlast) state <= STATE_DONE;
|
|
else state <= STATE_WRITE_ADDR;
|
|
base_addr <= base_addr + 32'h8;
|
|
line32_count <= line32_count - 16'h2;
|
|
end
|
|
end
|
|
|
|
STATE_DONE: begin
|
|
state <= STATE_WAIT_MEM;
|
|
end
|
|
|
|
default: state <= STATE_WAIT_MEM;
|
|
|
|
endcase //state
|
|
end
|
|
|
|
assign o_tdata = {line[31:0], line[63:32]};
|
|
assign o_tlast = (line32_count[15:1] == 15'b0); //ignore low bit
|
|
assign o_tvalid = (state == STATE_WRITE_LINE);
|
|
assign mem_ack = (state == STATE_DONE);
|
|
|
|
//the master read address always comes from the reg
|
|
assign AXI_ARADDR = base_addr;
|
|
assign AXI_ARVALID = (state == STATE_WRITE_ADDR);
|
|
assign AXI_RREADY = (state == STATE_READ_DATA);
|
|
assign AXI_ARPROT = PROT;
|
|
|
|
assign debug[2:0] = state;
|
|
assign debug[3] = first_line;
|
|
assign debug[4] = mem_valid;
|
|
assign debug[5] = mem_ack;
|
|
assign debug[6] = AXI_ARVALID;
|
|
assign debug[7] = AXI_ARREADY;
|
|
assign debug[8] = AXI_RVALID;
|
|
assign debug[9] = AXI_RREADY;
|
|
|
|
endmodule //zf_host_to_stream
|