Commit d42644e2 authored by Andrey Filippov's avatar Andrey Filippov

implemented channel FIFO (mult_saxi_wr_inbuf) for mult_saxi_wr

parent 41babf8a
...@@ -49,21 +49,25 @@ module mult_saxi_wr #( ...@@ -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 #( ...@@ -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 #( ...@@ -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),
......
/*******************************************************************************
* 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
...@@ -52,7 +52,7 @@ module event_logger#( ...@@ -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#( ...@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment