Loading axi/mult_saxi_wr.v +10 −6 Original line number Original line Diff line number Diff line Loading @@ -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) Loading Loading @@ -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; Loading @@ -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), Loading axi/mult_saxi_wr_inbuf.v 0 → 100644 +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 logger/event_logger.v +3 −3 Original line number Original line Diff line number Diff line Loading @@ -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 Loading Loading @@ -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); Loading Loading
axi/mult_saxi_wr.v +10 −6 Original line number Original line Diff line number Diff line Loading @@ -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) Loading Loading @@ -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; Loading @@ -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), Loading
axi/mult_saxi_wr_inbuf.v 0 → 100644 +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
logger/event_logger.v +3 −3 Original line number Original line Diff line number Diff line Loading @@ -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 Loading Loading @@ -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); Loading