Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
11 years ago

Outputting a bitstream onto a pin in verilog

I need to output a 32bit bit-stream onto a pin in verilog. I know verilog has the streaming operators pack and unpack but I do not believe they will do what I want it to do.

I have 32x512 FIFO RAM in which data is stored. Data for the variable "I" stored on the first 32 bits and the data for variable "Q" is stored on the next 32 bits (the rest of FIFO saves data in this alternating fashion). I need to continually get a 32bit stream off the FIFO RAM and output the 32bit data stream onto a pin. My FIFO has three output signals(a signal for the 32 bit data stream(32_data), a signal to say when the FIFO is empty (32_empty), and a signal to say when the FIFO is full(32_full)) My sudo code is the following (It's sudo code because I know how to do everything else but the part I need help with and I wanted to keep it simple for understanding):


    process @ posedge clock
    begin
      if (32_empty != 1) then //if the FIFO has data
        if (32_full == 1) then //if the FIFO is full, then we lose data (for testing purposes to know if I need to make the RAM bigger
           PIN_1 <= 1; //output onto a pin that the FIFO is full
           PIN_2 <= 0; //clear pin 2 from outputting data for "I"
           PIN_3 <= 0; //clear pin 3 from outputting data for "Q"
        else if (en_Q == 0)
           (stream 32bit data for variable "I" onto pin 2) //variable "I" output//HELP-This is where I need help figuring out how to stream the output, 32_data, onto a pin
           en_Q <= ~en_Q; // toggle en_Q so next 32bit stream will be for "Q"
        else if (en_Q ==1)
           (stream 32bit data for variable "Q" onto pin 3) //variable "Q" output//HELP-This is where I need help figuring out how to stream the output, 32_data, onto a pin
           en_Q <= ~en_Q; // toggle en_Q so next 32bit stream will be for "I"
    end                 

If you could help me with figuring out how to stream a 32 bit data stream onto a pin, that would be great!

Thanks in advance

2 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    If I correctly understand your request, you need to implement a shift-register to serialize (=stream) out of Q-I pins.

    This is roughly what you have to do:

    - define a 5 bit counter which continuosly counts from 0 to 31 again and again

    - at count=0 latch 32bit FIFO data into a register

    - for each count up to 31 (included count=0) put data[0] onto output pin and shift the register ( data <= data >> 1 ) and again
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Rather than a counter could I do a for loop? The following is my code section with the shift-register to serialize part which is implemented at the bottom:

    // 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; // Bogus data source

    // The slowdown register limits the data pace to 1/32 the bus_clk

    // when capture_clk = bus_clk. This is necessary, because the

    // core in the evaluation kit is configured for simplicity, and

    // not for performance. Sustained data rates of 200 MB/sec are

    // easily reached with performance-oriented setting.

    // The slowdown register has no function in a real-life application.

    slowdown <= slowdown + 1;

    // 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 &&

    (slowdown == 0);

    // 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)

    );

    reg Q_en = 1'b0; //starting value is 0 because first 32bit is I

    reg [31:0] data_outI;

    reg [31:0] data_outQ;

    reg I;

    reg Q;

    integer counter;

    always @(posedge bus_clk) begin

    if(Q_en == 1'b0) begin //To output to I signal

    data_outI <= user_r_read_32_data;

    for (counter = 0; counter < 32; counter = counter + 1) begin //output to pins

    I = data_outI[0];

    data_outI <= (data_outI >> 1);

    Q = data_outQ[0];

    data_outQ <= (data_outQ >> 1);

    end

    Q_en <= ~Q_en;

    end

    else if(Q_en == 1'b1) begin //To output to Q signal

    data_outQ <= user_r_read_32_data;

    for (counter = 0; counter < 32; counter = counter + 1) begin //output to pins

    I = data_outI[0];

    data_outI <= (data_outI >> 1);

    Q = data_outQ[0];

    data_outQ <= (data_outQ >> 1);

    end

    Q_en <= ~Q_en;

    end

    end

    assign PS_GPIO_ONE_I = I; //Assign Pin I

    assign PS_GPIO_TWO_Q = Q; //Assign Pin Q