Verilog DataSender

Date:

3 Oct 2019

What is the idea?

  • In this project we want to make a 16 channel counter to count photon numbers. Each Channel is 32 bits. So we need to send 16*32=512 bits of data via a FIFO each word of which is 32 bits.

  • We separate the 32 bits data of each channel to 2 parts, thus there are 32 parts to send. Each part has 16 bits, we combine this with a label called sendIndex into the 32 bits data that we send to the FIFO: FIFOwriteData[32] = {actualData[16],sendIndex[16]} .

  • So that when we receive data from the FIFO, we know which part the data is.

Code

module DataSender(
    input clk,
    output        FIFOwriteRequest,
    output [31:0] FIFOwriteData,
    input         FIFOwriteFull,

    input [511:0] zippedData,   // 16 channels * 32 bits per channel = 512 bits

    output debug_slowClk,
    output debug_state,
    output [15:0] debug_sendIndex
);
    // Begin debug
        assign debug_slowClk = slowClk;
        assign debug_state = state;
        assign debug_sendIndex = sendIndex;
    // End debug

    // Begin generate slow clock to send the data
        reg [31:0] counter;
        wire slowClk;
        reg last_slowClk;
        assign slowClk = counter[3];
        always @(posedge clk) begin
            counter <= counter+1;
            last_slowClk <= slowClk;
        end
    // End generate slow clock to send the data

    // Begin state machine
        reg state;
        localparam idle = 0;
        localparam send = 1;

        reg [15:0] sendIndex;
        localparam sendIndexMax = 31;  // 16 channels * 2 sends per channel = 32

        always @(posedge clk) begin
            case(state)
                idle:
                    if(slowClk != last_slowClk) begin
                        state <= send;
                        sendIndex <=0;
                    end
                send:
                    if(!FIFOwriteFull) begin
                        if(sendIndex < sendIndexMax)  sendIndex <= sendIndex+1;
                        else  state<= idle;
                    end
            endcase
        end

        // Data format: FIFOwriteData[32] = {actualData[16],sendIndex[16]}
        assign FIFOwriteData = { 16'hFFFF & (zippedData >> sendIndex*16), sendIndex };
        assign FIFOwriteRequest = state;
    // End state machine
endmodule

Simulation Result

  • The following is simulated by Quartus -> Files -> New -> University Program VWF

../_images/Stage-3_DataSender_More.webp
../_images/Stage-3_DataSender_Less.webp