0
votes

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

I have added the suggestion. Could I put the data on the pins with a for loop? The following is my code segment and the bottom part is the shift register and outputting to a pin:

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

`

1

1 Answers

0
votes

Basically, you'd want to do something like the following:

  • Fetch an item from the fifo into a 32 bit register (lets call data)
  • Each clock cycle, put the lsb of data onto the pin, and then right shift data by one value.
  • Keep repeating this shifting for 32 clock cycles, until all of the data has been shifted out.
  • Toggle the value of en_Q, and fetch another 32 bit item.

You should be able to make a small state machine that can handle this sequence. You can't shift out all 32 bits in a single clock cycle as you have done in your pseudo-code, unless you also have a 32x clock available, and that would likely be a more complicated design.