Hi,
I was trying to do a simple test of continuously and asynchronously storing data in a FIFO. Then serialize that data onto a pin. (Later I will need to take the data off the FIFO, do some processing on it, and then output it onto a pin). Right now I'm just trying to take the data off the FIFO and put it onto a pin. I tried to just make a simple asynchronous FIFO and combine it with the logic from the example in xillycapture along with my custom IP Core which just has a read and write 32. However, I can't seem to get the data from the FIFO to serialize it onto a pin. I'm using a Zybo board. How do I get the data from the FIFO and put it onto a pin? I've included
// Clock and quiesce
wire bus_clk;
wire quiesce;
// Wires related to /dev/xillybus_read_32
wire user_r_read_32_rden;
wire user_r_read_32_empty;
wire [31:0] user_r_read_32_data;
wire user_r_read_32_eof;
wire user_r_read_32_open;
// Wires related to /dev/xillybus_write_32
wire user_w_write_32_wren;
wire user_w_write_32_full;
wire [31:0] user_w_write_32_data;
wire user_w_write_32_open;
// Wires related to Xillybus Lite
wire user_clk;
wire user_wren;
wire user_rden;
wire [3:0] user_wstrb;
wire [31:0] user_addr;
wire [31:0] user_rd_data;
wire [31:0] user_wr_data;
wire user_irq;
xillybus xillybus_ins (
// Ports related to /dev/xillybus_read_32
// FPGA to CPU signals:
.user_r_read_32_rden(user_r_read_32_rden),
.user_r_read_32_empty(user_r_read_32_empty),
.user_r_read_32_data(user_r_read_32_data),
.user_r_read_32_eof(user_r_read_32_eof),
.user_r_read_32_open(user_r_read_32_open),
// Ports related to /dev/xillybus_write_32
// CPU to FPGA signals:
.user_w_write_32_wren(user_w_write_32_wren),
.user_w_write_32_full(user_w_write_32_full),
.user_w_write_32_data(user_w_write_32_data),
.user_w_write_32_open(user_w_write_32_open),
// Ports related to Xillybus Lite
.user_clk(user_clk),
.user_wren(user_wren),
.user_rden(user_rden),
.user_wstrb(user_wstrb),
.user_addr(user_addr),
.user_rd_data(user_rd_data),
.user_wr_data(user_wr_data),
.user_irq(user_irq),
// General signals
.PS_CLK(PS_CLK),
.PS_PORB(PS_PORB),
.PS_SRSTB(PS_SRSTB),
.clk_100(clk_100),
.otg_oc(otg_oc),
.DDR_Addr(DDR_Addr),
.DDR_BankAddr(DDR_BankAddr),
.DDR_CAS_n(DDR_CAS_n),
.DDR_CKE(DDR_CKE),
.DDR_CS_n(DDR_CS_n),
.DDR_Clk(DDR_Clk),
.DDR_Clk_n(DDR_Clk_n),
.DDR_DM(DDR_DM),
.DDR_DQ(DDR_DQ),
.DDR_DQS(DDR_DQS),
.DDR_DQS_n(DDR_DQS_n),
.DDR_DRSTB(DDR_DRSTB),
.DDR_ODT(DDR_ODT),
.DDR_RAS_n(DDR_RAS_n),
.DDR_VRN(DDR_VRN),
.DDR_VRP(DDR_VRP),
.MIO(MIO),
.PS_GPIO(PS_GPIO),
.DDR_WEB(DDR_WEB),
.GPIO_LED(GPIO_LED),
.bus_clk(bus_clk),
.hdmi_clk_n(hdmi_clk_n),
.hdmi_clk_p(hdmi_clk_p),
.hdmi_d_n(hdmi_d_n),
.hdmi_d_p(hdmi_d_p),
.hdmi_out_en(hdmi_out_en),
.quiesce(quiesce),
.vga4_blue(vga4_blue),
.vga4_green(vga4_green),
.vga4_red(vga4_red),
.vga_hsync(vga_hsync),
.vga_vsync(vga_vsync)
);
// Wires and registers related to data capturing
wire capture_clk;
reg [31:0] capture_data;
wire capture_en;
reg [4:0] slowdown;
wire capture_full;
reg capture_open;
reg capture_open_cross;
reg capture_has_been_full;
reg capture_has_been_nonfull;
reg has_been_full_cross;
reg has_been_full;
// Data capture section
// ====================
always @(posedge capture_clk)
begin
if (capture_en)
capture_data <= user_w_write_32_data; //Take data written to this file
// capture_has_been_full remembers that the FIFO has been full
// until the file is closed. capture_has_been_nonfull prevents
// capture_has_been_full to respond to the initial full condition
// every FIFO displays on reset.
if (!capture_full)
capture_has_been_nonfull <= 1;
else if (!capture_open)
capture_has_been_nonfull <= 0;
if (capture_full && capture_has_been_nonfull)
capture_has_been_full <= 1;
else if (!capture_open)
capture_has_been_full <= 0;
end
// The dependency on slowdown is only for bogus data
assign capture_en = capture_open && !capture_full &&
!capture_has_been_full;
// Clock crossing logic: bus_clk -> capture_clk
always @(posedge capture_clk)
begin
capture_open_cross <= user_r_read_32_open;
capture_open <= capture_open_cross;
end
// Clock crossing logic: capture_clk -> bus_clk
always @(posedge bus_clk)
begin
has_been_full_cross <= capture_has_been_full;
has_been_full <= has_been_full_cross;
end
// The user_r_read_32_eof signal is required to go from '0' to '1' only on
// a clock cycle following an asserted read enable, according to Xillybus'
// core API. This is assured, since it's a logical AND between
// user_r_read_32_empty and has_been_full. has_been_full goes high when the
// FIFO is full, so it's guaranteed that user_r_read_32_empty is low when
// that happens. On the other hand, user_r_read_32_empty is a FIFO's empty
// signal, which naturally meets the requirement.
assign user_r_read_32_eof = user_r_read_32_empty && has_been_full;
assign user_w_write_32_full = 0;
// The data capture clock here is bus_clk for simplicity, but clock domain
// crossing is done properly, so capture_clk can be an independent clock
// without any other changes.
assign capture_clk = bus_clk;
async_fifo_32x512 fifo_32 //FIFO created using Xilinx FIFO Generator Wizard
(
.rst(!user_r_read_32_open),
.wr_clk(capture_clk),
.rd_clk(bus_clk),
.din(capture_data),
.wr_en(capture_en),
.rd_en(user_r_read_32_rden),
.dout(user_r_read_32_data),
.full(capture_full),
.empty(user_r_read_32_empty)
);
//Signals for use in later programming after the test works
reg Q_en = 1'b0; //starting value is 0 because first 32bit is I
reg [31:0] data_outI = 32'd0;
reg [31:0] data_outQ = 32'd0;
reg I = 1'b0;
reg Q = 1'b0;
reg [5:0] counter_32_shift = 6'b000000;
reg temp = 1'b0;
reg serialization = 1'b0;
reg [31:0] fifo_data;
always @(posedge bus_clk) begin //serialization of bits onto pins I and Q
if (serialization == 1'b0 && counter_32_shift == 6'b000000) begin
fifo_data <= user_r_read_32_data; //read in fifo data to register to begin serializing
serialization <= 1'b1; //begin serializing
end else if (serialization == 1'b1) begin
if (counter_32_shift == 6'b100000) begin //counter_32_shift == 32
I <= fifo_data[0];
fifo_data <= (fifo_data >> 1);
Q <= fifo_data[0];
fifo_data <= (fifo_data >> 1);
counter_32_shift <= 6'b000000;
serialization <= 1'b0;
temp <= ~temp; //testing to make counter resets
end else begin
I <= fifo_data[0];
fifo_data <= (fifo_data >> 1);
Q <= fifo_data[0];
fifo_data <= (fifo_data >> 1);
counter_32_shift <= counter_32_shift + 6'b000001;
end
end // serialization check
end //end always
assign PS_GPIO_ONE_I = I; //Assign Pin I
assign PS_GPIO_TWO_Q = Q; //Assign Pin Q
assign PS_GPIO_FOUR_FULL = temp; //Assign testing pins
assign user_w_write_32_full = 0;
assign user_irq = 0; // No interrupts for now
Thank you!