Commit d42644e2 authored by Andrey Filippov's avatar Andrey Filippov
Browse files

implemented channel FIFO (mult_saxi_wr_inbuf) for mult_saxi_wr

parent 41babf8a
Loading
Loading
Loading
Loading
+10 −6
Original line number Original line Diff line number Diff line
@@ -49,21 +49,25 @@ module mult_saxi_wr #(
    output                     status_rq,     // input request to send status downstream
    output                     status_rq,     // input request to send status downstream
    input                      status_start,  // Acknowledge of the first status packet byte (address)
    input                      status_start,  // Acknowledge of the first status packet byte (address)


    output                     en_chn0,       // @mclk enable channel 0 input FIFO ( 0 - reset)
    input                      has_burst0,    // channel has at least 1 burst (should go down immediately after read_burst0 if no more data)
    input                      has_burst0,    // channel has at least 1 burst (should go down immediately after read_burst0 if no more data)
    output                     read_burst0,   // request to read a burst of data from channel 0
    output                     read_burst0,   // request to read a burst of data from channel 0
    input               [31:0] data_in_chn0,  // data read from channel 0 (with some latency)
    input               [31:0] data_in_chn0,  // data read from channel 0 (with some latency)
    input                      pre_valid_chn0,// data valid (same latency)
    input                      pre_valid_chn0,// data valid (same latency)
    
    
    output                     en_chn1,       // @mclk enable channel 1 input FIFO ( 0 - reset)
    input                      has_burst1,    // channel has at least 1 burst (should go down immediately after read_burst0 if no more data)
    input                      has_burst1,    // channel has at least 1 burst (should go down immediately after read_burst0 if no more data)
    output                     read_burst1,   // request to read a burst of data from channel 0
    output                     read_burst1,   // request to read a burst of data from channel 0
    input               [31:0] data_in_chn1,  // data read from channel 0 (with some latency)
    input               [31:0] data_in_chn1,  // data read from channel 0 (with some latency)
    input                      pre_valid_chn1,// data valid (same latency)
    input                      pre_valid_chn1,// data valid (same latency)
    
    
    output                     en_chn2,       // @mclk enable channel 2 input FIFO ( 0 - reset)
    input                      has_burst2,    // channel has at least 1 burst (should go down immediately after read_burst0 if no more data)
    input                      has_burst2,    // channel has at least 1 burst (should go down immediately after read_burst0 if no more data)
    output                     read_burst2,   // request to read a burst of data from channel 0
    output                     read_burst2,   // request to read a burst of data from channel 0
    input               [31:0] data_in_chn2,  // data read from channel 0 (with some latency)
    input               [31:0] data_in_chn2,  // data read from channel 0 (with some latency)
    input                      pre_valid_chn2,// data valid (same latency)
    input                      pre_valid_chn2,// data valid (same latency)
    
    
    output                     en_chn3,       // @mclk enable channel 3 input FIFO ( 0 - reset)
    input                      has_burst3,    // channel has at least 1 burst (should go down immediately after read_burst0 if no more data)
    input                      has_burst3,    // channel has at least 1 burst (should go down immediately after read_burst0 if no more data)
    output                     read_burst3,   // request to read a burst of data from channel 0
    output                     read_burst3,   // request to read a burst of data from channel 0
    input               [31:0] data_in_chn3,  // data read from channel 0 (with some latency)
    input               [31:0] data_in_chn3,  // data read from channel 0 (with some latency)
@@ -145,10 +149,7 @@ module mult_saxi_wr #(
    wire                       we_ctrl;
    wire                       we_ctrl;
    wire                       cmd_we_sa_len;
    wire                       cmd_we_sa_len;
    
    
    always @ (posedge rst or posedge mclk) begin
    assign {en_chn3, en_chn2, en_chn1, en_chn0} = en_chn_mclk; 
        if      (rst)                  mode_reg <= 0;
        else if (we_ctrl && !cmd_a[0]) mode_reg <= cmd_data[7:0];
    end


    assign {read_burst3, read_burst2, read_burst1, read_burst0} = grant_wr; // single clock pulse
    assign {read_burst3, read_burst2, read_burst1, read_burst0} = grant_wr; // single clock pulse
    assign data_in[0] = data_in_chn0;
    assign data_in[0] = data_in_chn0;
@@ -160,9 +161,12 @@ module mult_saxi_wr #(
    assign en_chn_mclk =  mode_reg[3:0];
    assign en_chn_mclk =  mode_reg[3:0];
    assign run_chn_mclk = mode_reg[7:4];
    assign run_chn_mclk = mode_reg[7:4];
    
    
// Arbiter requests on copying from one of teh input channels to the internal buffer
    always @ (posedge rst or posedge mclk) begin
    
        if      (rst)                  mode_reg <= 0;
        else if (we_ctrl && !cmd_a[0]) mode_reg <= cmd_data[7:0];
    end


// Arbiter requests on copying from one of teh input channels to the internal buffer


    mult_saxi_wr_chn #(
    mult_saxi_wr_chn #(
        .MULT_SAXI_HALF_BRAM (MULT_SAXI_HALF_BRAM),
        .MULT_SAXI_HALF_BRAM (MULT_SAXI_HALF_BRAM),
+143 −0
Original line number Original line Diff line number Diff line
/*******************************************************************************
 * Module: mult_saxi_wr_inbuf
 * Date:2015-07-11  
 * Author: andrey     
 * Description: Channel buffer with width conversion to 32 to use with mult_saxi_wr
 *
 * Copyright (c) 2015 Elphel, Inc .
 * mult_saxi_wr_inbuf.v is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 *  mult_saxi_wr_inbuf.v is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/> .
 *******************************************************************************/
`timescale 1ns/1ps

module  mult_saxi_wr_inbuf#(
    parameter MULT_SAXI_HALF_BRAM_IN =      1,     // 0 - use full 36Kb BRAM for the buffer, 1 - use just half
    parameter MULT_SAXI_BSLOG =             4,     // number of bits to represent burst size (4 - b.s. = 16, 0 - b.s = 1)
    parameter MULT_SAXI_WLOG =              4      // number of bits for the input data ( 3 - 8 bit, 4 - 16-bit, 5 - 32-bit
)(
    input                               mclk,        // system clock
    input                               en,          // enable channel,  0 - reset FIFO @mclk

    // Input data port. No check on buffer overflow
    input                               iclk,        // input data clock
    input [(1 << MULT_SAXI_WLOG) - 1:0] data_in,     // @posedge iclk input data
    input                               valid,       // @posedge iclk input data valid

    output reg                          has_burst,    // channel has at least 1 burst (should go down immediately after read_burst if no more data)
    input                               read_burst,   // request to read a burst of data from this channel
    output                       [31:0] data_out,     // data read from this channel
    output                              pre_valid_chn // data valid

);
    localparam INA_WIDTH =  (MULT_SAXI_HALF_BRAM_IN ? 14 : 15) - MULT_SAXI_WLOG;
    localparam OUTA_WIDTH = (MULT_SAXI_HALF_BRAM_IN ? 14 : 15) - 5;
    localparam INW_CNTR_WIDTH =  MULT_SAXI_BSLOG + 5 -MULT_SAXI_WLOG; // width of the input word counter (in a burst)
    localparam OUTW_CNTR_WIDTH = MULT_SAXI_BSLOG; // width of the output word counter (in a burst)
    localparam BURST_WIDTH = OUTA_WIDTH - OUTW_CNTR_WIDTH;
    
    reg                          en_iclk;
    reg     [INW_CNTR_WIDTH-1:0] inw_cntr;
    reg        [BURST_WIDTH-1:0] in_burst;
    reg    [OUTW_CNTR_WIDTH-1:0] outw_cntr;
    reg        [BURST_WIDTH-1:0] out_burst;
    reg          [BURST_WIDTH:0] num_out_bursts;
    
    wire         [INA_WIDTH-1:0] waddr = {in_burst,inw_cntr};
    wire        [OUTA_WIDTH-1:0] raddr = {out_burst,outw_cntr};
    
    wire                         put_burst_mclk;
    wire                         wr_last_word = valid && (&inw_cntr);
    
    wire                         re_last_word = buf_re[0] && (&outw_cntr);
    reg                    [1:0] buf_re;
    
    assign pre_valid_chn = buf_re[1];
    always @ (posedge iclk) begin
        en_iclk <= en;

        if   (!en_iclk) inw_cntr <= 0;
        else if (valid) inw_cntr <= inw_cntr + 1;
         
        if      (!en_iclk)     in_burst <= 0;
        else if (wr_last_word) in_burst <= in_burst + 1;
    end
    
    always @ (posedge mclk) begin
        if (!en) buf_re <= 0;
        else buf_re <= {buf_re[0], read_burst | (buf_re[0] & ~(&outw_cntr))};
        
        if      (!en)       outw_cntr <= 0;
        else if (buf_re[0]) outw_cntr <= outw_cntr + 1;
        
        if      (!en)          out_burst <= 0;
        else if (re_last_word) out_burst <= out_burst + 1;
        
        if      (!en)                            num_out_bursts <= 0;
        else if ( put_burst_mclk && !read_burst) num_out_bursts <= num_out_bursts + 1;
        else if (!put_burst_mclk &&  read_burst) num_out_bursts <= num_out_bursts - 1;
        
        if (!en)  has_burst <= 0;
        else has_burst <= (|num_out_bursts[BURST_WIDTH:1]) || (num_out_bursts[0] && !read_burst);
        
    end

    pulse_cross_clock #(.EXTRA_DLY(1)) put_burst_mclk_i (
            .rst(!en_iclk),
            .src_clk(iclk),
            .dst_clk(mclk),
            .in_pulse(wr_last_word),
            .out_pulse(put_burst_mclk),
            .busy());
    
    generate
        if (MULT_SAXI_HALF_BRAM_IN)
            ram18_var_w_var_r #(
                .REGISTERS(1),
                .LOG2WIDTH_WR(MULT_SAXI_WLOG),
                .LOG2WIDTH_RD(5),
                .DUMMY(0)
            ) ram_var_w_var_r_i (
                .rclk      (mclk), // input
                .raddr     (raddr[8:0]), // input[9:0] 
                .ren       (buf_re[0]), // input
                .regen     (buf_re[1]), // input
                .data_out  (data_out), // output[31:0] 
                .wclk      (iclk), // input
                .waddr     (waddr[13-MULT_SAXI_WLOG:0]), // input[9:0] 
                .we        (valid), // input
                .web       (4'hff), // input[7:0] 
                .data_in   (data_in) // input[31:0] 
            );
        else
            ram_var_w_var_r #(
                .REGISTERS(1),
                .LOG2WIDTH_WR(MULT_SAXI_WLOG),
                .LOG2WIDTH_RD(5),
                .DUMMY(0)
            ) ram_var_w_var_r_i (
                .rclk      (mclk), // input
                .raddr     ({raddr[OUTA_WIDTH-1],raddr[8:0]}), // {buf_ra[BRAM_A_WDTH-1],buf_ra[8:0]}), // input[9:0] 
                .ren       (buf_re[0]), // input
                .regen     (buf_re[1]), // input
                .data_out  (data_out), // output[31:0] 
                .wclk      (iclk), // input
                .waddr     ({waddr[INA_WIDTH-1],waddr[13-MULT_SAXI_WLOG:0]}), // {buf_wa[BRAM_A_WDTH-1],buf_wa[8:0]}), // input[9:0] 
                .we        (valid), // input
                .web       (8'hff), // input[7:0] 
                .data_in   (data_in) // input[31:0] 
            );
    endgenerate


endmodule
+3 −3
Original line number Original line Diff line number Diff line
@@ -52,7 +52,7 @@ module event_logger#(
    parameter GPIO_N =                     10 // number of GPIO bits to control
    parameter GPIO_N =                     10 // number of GPIO bits to control
)(
)(
    input                         rst,
    input                         rst,
    input                         mclk,        // system clock, negedge TODO:COnvert to posedge!
    input                         mclk,        // system clock
    input                         xclk,        // half frequency (80 MHz nominal)
    input                         xclk,        // half frequency (80 MHz nominal)
    // programming interface
    // programming interface
    input                   [7:0] cmd_ad,      // byte-serial command address/data (up to 6 bytes: AL-AH-D0-D1-D2-D3 
    input                   [7:0] cmd_ad,      // byte-serial command address/data (up to 6 bytes: AL-AH-D0-D1-D2-D3 
@@ -87,8 +87,8 @@ module event_logger#(
    
    
    
    
// TODO: Convert to 32-bit?    
// TODO: Convert to 32-bit?    
    output                 [15:0] data_out,    // 16-bit data out to DMA1 (@negedge mclk)
    output                 [15:0] data_out,    // 16-bit data out to DMA1 (@posdge mclk)
    output                        data_out_stb,// data out valid (@negedge mclk)
    output                        data_out_stb,// data out valid (@posedge mclk)
//                       sample_counter, // could be DMA latency, safe to use sample_counter-1
//                       sample_counter, // could be DMA latency, safe to use sample_counter-1
    output                 [31:0] debug_state);
    output                 [31:0] debug_state);