x393  1.0
FPGAcodeforElphelNC393camera
mul_saxi_wr_chn.v
Go to the documentation of this file.
1 
39 `timescale 1ns/1ps
40 
42  parameter MULT_SAXI_HALF_BRAM = 1, // 0 - use full 36Kb BRAM for the buffer, 1 - use just half
43  parameter MULT_SAXI_BSLOG = 4, // number of bits to represent burst size (4 - b.s. = 16, 0 - b.s = 1)
44  parameter MULT_SAXI_ADV_WR = 4, // number of clock cycles before end of write to genearte adv_wr_done
45  parameter MULT_SAXI_ADV_RD = 3 // number of clock cycles before end of read to genearte wdata_busy (if !fifo_half_full)
46 ) (
47  input mclk, // system clock
48  input aclk, // global clock to run s_axi (@150MHz?)
49  input en, // enable this channle ( 0 - reset)
50  input has_burst, // channel has at least 1 burst (should go down immediately after read_burst if no more data)
51  // use grant_wr to request reading external data
52 // output read_burst, // request to read a burst of data from the channel
53  input valid, // data valid (same latency)
54  output rq_wr, // request to write to the buffer FIFO
55  input grant_wr, // single-cycle
56  output [(MULT_SAXI_HALF_BRAM?6:7):0] wa, // write buffer address (w/o 2 MSB - channel)
57  output reg adv_wr_done, // outputs grant_wr for short bursts, or several clocks before end of wr
58 // output pre_we, // will be registered after mux - use valid
59  output reg rq_out,
60  input grant_out, // single-cycle
61  input fifo_half_full, // output fifo is half full - use it to suspend readout
62  output [(MULT_SAXI_HALF_BRAM?6:7):0] ra, // read buffer address (w/o 2 MSB - channel)
63  output pre_re, // will be registerd after the MUX
64  output reg first_re, // reading first word (next cycle after corresponding pre_re)
65  output reg last_re, // reading lastt word (next cycle after corresponding pre_re)
66 
67  output reg wdata_busy
68 
69 );
70  localparam BURSTS_BITS= (MULT_SAXI_HALF_BRAM ? 9 : 10 ) - MULT_SAXI_BSLOG - 2; // number of bits to count number of bursts in 0-th quarter of the buffer
71 
72  reg [BURSTS_BITS-1:0] wr_burst;
74  reg [BURSTS_BITS:0] wr_num_burst; // number of bursts in the buffer chn0, as seen from the write side
75 
76  reg [BURSTS_BITS-1:0] rd_burst;
78  reg [BURSTS_BITS:0] rd_num_burst; // number of bursts in the buffer chn0, as seen from the read side
79  reg rq_wr_r;
81 // reg early_wr_done; // single-cycle pulse several clock before end of write busy
82 // reg grant_wr_r;
83 // wire grant_wr_sngl;
84 // wire grant_wr_aclk;
87 // reg grant_out_r;
88 // wire grant_out_sngl;
90  reg en_aclk;
92  reg pre_re_r; // may be interrupted if fifo_half_full
93  reg out_busy; // output data in progress
94 
95  assign wa = {wr_burst, wr_word};
96  assign ra = {rd_burst, rd_word};
97  assign rq_wr = rq_wr_r;
98 // assign grant_wr_sngl = grant_wr && !grant_wr_r;
99 // assign grant_out_sngl = grant_out && ~grant_out_r;
100  assign last_word_busy = &wr_word ; // make it earlier, use BURSTS_BITS selection (& (word | (1 <<???)))
101  assign write_last_in_burst = valid && (&wr_word);
102  assign pre_re = pre_re_r;
103 
106 
107 
108  always @ (posedge mclk) begin
109  adv_wr_done <= rq_wr_busy && (wr_word == ((ADV_WR_COUNT >= 0)? ADV_WR_COUNT : 0));
110 
111  if (!en) rq_wr_busy <= 0;
112  else if (grant_wr) rq_wr_busy <= 1;
113  else if (valid && last_word_busy) rq_wr_busy <= 0;
114 
115 
117  // Number of bursts in fifo as seen from the input
118  if (!en) wr_num_burst <= 0;
119  else if ( grant_wr && !grant_out_mclk) wr_num_burst <= wr_num_burst + 1;
120  else if (!grant_wr && grant_out_mclk) wr_num_burst <= wr_num_burst - 1;
121 
122  if (!en || grant_wr) wr_word <= 0;
123  else if (valid) wr_word <= wr_word + 1;
124 
125  if (!en) wr_burst <= 0;
126  else if (write_last_in_burst) wr_burst <= wr_burst + 1;
127 
128 
129  end
130 
131  reg early_busy; // output data in progress
132 
133  always @ (posedge aclk) begin
134  en_aclk <= en;
135  // Number of bursts in fifo as seen from the output
136  if (!en_aclk) rd_num_burst <= 0;
139 
140  if (!en_aclk) rq_out <= 0;
141  else if ( burst_written_aclk && !grant_out) rq_out <= 1;
142  else if (!burst_written_aclk && grant_out) rq_out <= |rd_num_burst[BURSTS_BITS:1]; // >=2
143 
144  if (! en_aclk || grant_out) rd_word <= 0;
145  else if (pre_re_r) rd_word <=rd_word +1;
146 
147  if (!en_aclk) rd_burst <= wr_burst; // <= 0 is OK too
148  else if (pre_re_r && (&rd_word)) rd_burst <= rd_burst + 1;
149 
150  if (!en_aclk) out_busy <= 0;
151  else if (grant_out) out_busy <= 1;
152  else if ((&rd_word) && pre_re_r) out_busy <= 0;
153 
154  if (!en_aclk || fifo_half_full || ((&rd_word) && pre_re_r)) pre_re_r <= 0;
155  else pre_re_r <= out_busy;
156 
157  first_re <= pre_re_r && !(|rd_word); // will be used to copy channel/axi_wid
158  last_re <= pre_re_r && (&rd_word); // will be used to generate axi_wlast
159 
160  if (!en_aclk || (ADV_RD_COUNT > 0)) early_busy <= 0; // small counts will never get busy
161  else if (grant_out) early_busy <= 1;
162  else if (rd_word == ADV_RD_COUNT) early_busy <= 0;
163 
164  if (!en_aclk) wdata_busy <= 0;
165  else if (grant_out) wdata_busy <= 1;
166  else if ((!fifo_half_full && !early_busy) || (&rd_word) || !out_busy) wdata_busy <= 0;
167  end
168 
169  pulse_cross_clock grant_out_mclk_i (
170  .rst (!en), // input
171  .src_clk (aclk), // input
172  .dst_clk (mclk), // input
173  .in_pulse (grant_out), // input
174  .out_pulse (grant_out_mclk), // output
175  .busy() // output
176  );
177  pulse_cross_clock write_last_in_burst_i (
178  .rst (!en_aclk), // input
179  .src_clk (mclk), // input
180  .dst_clk (aclk), // input
181  .in_pulse (write_last_in_burst), // input
182  .out_pulse (burst_written_aclk), // output
183  .busy() // output
184  );
185 endmodule
736rd_wordreg[MULT_SAXI_BSLOG-1:0]
[MULT_SAXI_HALF_BRAM?6:7:0] 721wa
732wr_burstreg[BURSTS_BITS-1:0]
734wr_num_burstreg[BURSTS_BITS:0]
write_last_in_burst_i pulse_cross_clock
735rd_burstreg[BURSTS_BITS-1:0]
747ADV_WR_COUNT(1 << MULT_SAXI_BSLOG) - MULT_SAXI_ADV_WR
737rd_num_burstreg[BURSTS_BITS:0]
731BURSTS_BITS(MULT_SAXI_HALF_BRAM ? 9 : 10 ) - MULT_SAXI_BSLOG - 2
733wr_wordreg[MULT_SAXI_BSLOG-1:0]
748ADV_RD_COUNT(1 << MULT_SAXI_BSLOG) - MULT_SAXI_ADV_RD
[MULT_SAXI_HALF_BRAM?6:7:0] 726ra