x393  1.0
FPGAcodeforElphelNC393camera
simul_saxi_gp_wr.v
Go to the documentation of this file.
1 
39 `timescale 1ns/1ps
40 
42  input rst,
43  // AXI signals
44  input aclk,
45  output aresetn, // do not use?
46  // write address
47  input [31:0] awaddr,
48  input awvalid,
49  output awready,
50  input [ 5:0] awid,
51  input [ 1:0] awlock, // verify the correct values are here
52  input [ 3:0] awcache, // verify the correct values are here
53  input [ 2:0] awprot, // verify the correct values are here
54  input [ 3:0] awlen,
55  input [ 1:0] awsize,
56  input [ 1:0] awburst,
57  input [ 3:0] awqos, // verify the correct values are here
58  // write data
59  input [31:0] wdata,
60  input wvalid,
61  output wready,
62  input [ 5:0] wid,
63  input wlast,
64  input [ 3:0] wstrb,
65  // write response
66  output bvalid,
67  input bready,
68  output [ 5:0] bid,
69  output [ 1:0] bresp,
70 
71  // Simulation signals - use same aclk
72  output [31:0] sim_wr_address,
73  output [ 5:0] sim_wid,
74  output sim_wr_valid, // ready to provide simulation data
75  input sim_wr_ready, // simulation may pause this channel by keeping this signal inactive
76  output [31:0] sim_wr_data,
77  output [ 3:0] sim_wr_stb,
78  output [ 1:0] sim_wr_size,
79  input [ 3:0] sim_bresp_latency, // latency in writing data outside of the module
80  output [ 3:0] sim_wr_qos
81 );
82  localparam AW_FIFO_DEPTH = 3; // FIFO number of address bits to fit AW_FIFO_NUM (number is one bit wider)
83  localparam W_FIFO_DEPTH = 3; // FIFO number of address bits to fit W_FIFO_NUM
84  localparam [AW_FIFO_DEPTH:0] AW_FIFO_NUM = 8; // Maximal number of words in AW FIFO 8-words
85  localparam [W_FIFO_DEPTH:0] W_FIFO_NUM = 8; // Maximal number of words in AW 8-words
86 
87 
88  localparam VALID_AWLOCK = 2'b0; // TODO
89  localparam VALID_AWCACHE = 4'b0011; //
90  localparam VALID_AWPROT = 3'b000;
91  localparam VALID_AWLOCK_MASK = 2'b11; // TODO
92  localparam VALID_AWCACHE_MASK = 4'b0011; //
93  localparam VALID_AWPROT_MASK = 3'b010;
94 /*
95 http://forums.xilinx.com/t5/Embedded-Processor-System-Design/Accessing-DDR-from-PL-on-Zynq/m-p/324877#M8413
96 Solved it!
97 To make it work, I set the (AR/AW)CACHE=0x11 and (AR/AW)PROT=0x00. In the CDMA datasheet, these were the recommended values, which I confirmed with ChipScope, when attached to CDMA's master port.
98 The default values set by VHLS were 0x00 and 0x10 respectively, which is also the case in the last post.
99 Alex
100 */
101 
102  wire aw_nempty;
103  wire w_nempty;
104  reg [11:0] next_wr_address_w; // bits that are incremented in 32-bit mode (higher are kept according to AXI 4KB inc. limit)
105  reg [31:0] write_address;
106  wire fifo_wd_rd; // read data fifo
108 
109 
110  wire [5:0] awid_out; // verify it matches wid_out when outputting data
111  wire [1:0] awburst_out;
112  wire [1:0] awsize_out;
113  wire [3:0] awlen_out;
114  wire [31:0] awaddr_out;
115  wire [5:0] wid_out;
116  wire wlast_out;
117  wire [3:0] wstrb_out;
118  wire [31:0] wdata_out;
119 
122  reg [3:0] write_left;
123  reg [ 1:0] wburst; // registered burst type
124  reg [ 3:0] wlen; // registered awlen type (for wrapped over transfers)
125  reg [ 1:0] wsize;
127  wire write_in_progress_w; // should go inactive last confirmed upstream cycle
129  reg [ 7:0] num_full_data = 0; // Number of full data bursts in FIFO
130 
131  wire [5:0] wresp_num_in_fifo;
133  wire wresp_re;
134 
137 
138 
139  // documentation sais : "When set, allows the priority of a transaction at the head of the WrCmdQ to be promoted if higher
140  // priority transactions are backed up behind it." Whqt about demotion? Assuming it is not demoted
141  assign aresetn= ~rst; // probably not needed at all - docs say "do not use"
142 
143 
144  // generate ready signals for address and data
145 // assign wready= !wcount[7] && (!(&wcount[6:0]) || !fifo_data_we_d);
146  assign wready = (wcount < W_FIFO_NUM) && ((wcount < (W_FIFO_NUM-1)) || !fifo_data_we_d);
147  always @ (posedge rst or posedge aclk) begin
148  if (rst) fifo_data_we_d<=0;
149  else fifo_data_we_d <= wready && wvalid;
150  end
151 // assign awready= !wacount[5] && (!(&wacount[4:0]) || !fifo_addr_we_d);
152  assign awready = (wacount < AW_FIFO_NUM) && ((wacount < (AW_FIFO_NUM-1)) || !fifo_addr_we_d);
153  always @ (posedge rst or posedge aclk) begin
154  if (rst) fifo_addr_we_d<=0;
155  else fifo_addr_we_d <= awready && awvalid;
156  end
157 
158  // Count full data bursts ready in FIFO
159  always @ (posedge rst or posedge aclk) begin
160  if (rst) num_full_data <=0;
162  else if (!(wvalid && wready && wlast) && start_write_burst_w) num_full_data <= num_full_data - 1;
163  end
164 
165 
168  assign sim_wr_valid= write_in_progress && w_nempty; // for continuing writes
169  assign last_confirmed_write = (write_left==0) && fifo_wd_rd && wlast_out; // wlast_out should take precedence over write_left?
170  assign start_write_burst_w=
171  aw_nempty && w_nempty &&
173 
174  assign write_in_progress_w=
176 
177  // AXI: Bursts should not cross 4KB boundaries (... and to limit size of the address incrementer)
178  // in 64 bit mode - low 3 bits are preserved, next 9 are incremented
179  always @* begin
180  case (wburst)
181  2'h0: next_wr_address_w[11:0] <= write_address[11:0];
182  2'h1: next_wr_address_w[11:0] <= write_address[11:0] + (1 << wsize);
183  2'h2: case (wsize)
184  2'h3: begin
185  next_wr_address_w[11:3] <= (write_address[11:3] + 1) & {5'h1f, ~wlen[3:0]};
186  next_wr_address_w[ 2:0] <= write_address[2:0];
187  end
188  2'h2: begin
189  next_wr_address_w[11:2] <= (write_address[11:2] + 1) & {6'h3f, ~wlen[3:0]};
190  next_wr_address_w[ 1:0] <= write_address[1:0];
191  end
192  2'h1: begin
193  next_wr_address_w[11:1] <= (write_address[11:1] + 1) & {7'h7f, ~wlen[3:0]};
194  next_wr_address_w[0:0] <= write_address[0:0];
195  end
196  2'h0: begin
197  next_wr_address_w[11:0] <= (write_address[11:0] + 1) & {8'hff, ~wlen[3:0]};
198  end
199  endcase
200  2'h3: next_wr_address_w[11:0] <= 12'bx;
201  endcase
202  end
203  wire [3:0] sim_wr_mask = (awsize_out == 0)? 4'h1 : ((awsize_out == 1)? 4'h3 : 4'hf);
204  assign sim_wr_data= wdata_out;
205  assign sim_wid= wid_out;
206  assign sim_wr_stb=wstrb_out & sim_wr_mask; // limit by data size
207  assign sim_wr_size = awsize_out;
208 
209  always @ (posedge aclk) begin
210  if (start_write_burst_w) begin
211  if (awid_out != wid_out) begin
212  $display ("%m: at time %t ERROR: awid=%h, wid=%h",$time,awid_out,wid_out);
213  $stop;
214  end
215 
216  end
217  if (awvalid && awready) begin
218  if (((awlock ^ VALID_AWLOCK) & VALID_AWLOCK_MASK) != 0) begin
219  $display ("%m: at time %t ERROR: awlock = %h, valid %h with mask %h",$time, awlock, VALID_AWLOCK, VALID_AWLOCK_MASK);
220  $stop;
221  end
222  if (((awcache ^ VALID_AWCACHE) & VALID_AWCACHE_MASK) != 0) begin
223  $display ("%m: at time %t ERROR: awcache = %h, valid %h with mask %h",$time, awcache, VALID_AWCACHE, VALID_AWCACHE_MASK);
224  $stop;
225  end
226  if (((awprot ^ VALID_AWPROT) & VALID_AWPROT_MASK) != 0) begin
227  $display ("%m: at time %t ERROR: awprot = %h, valid %h with mask %h",$time, awprot, VALID_AWPROT, VALID_AWPROT_MASK);
228  $stop;
229  end
230  end
231  end
232 
233 
234 
235  always @ (posedge aclk or posedge rst) begin
236  if (rst) wburst[1:0] <= 0;
237  else if (start_write_burst_w) wburst[1:0] <= awburst_out[1:0];
238 
239  if (rst) wlen[3:0] <= 0;
240  else if (start_write_burst_w) wlen[3:0] <= awlen_out[3:0];
241 
242  if (rst) wsize[1:0] <= 0;
243  else if (start_write_burst_w) wsize[1:0] <= awsize_out[1:0];
244 
245 
246  if (rst) write_in_progress <= 0;
248 
249  if (rst) write_left <= 0;
250  else if (start_write_burst_w) write_left <= awlen_out[3:0]; // precedence over inc
251  else if (fifo_wd_rd) write_left <= write_left-1; //SuppressThisWarning ISExst Result of 32-bit expression is truncated to fit in 4-bit target.
252 
253  if (rst) write_address <= 32'bx;
254  else if (start_write_burst_w) write_address <= awaddr_out; // precedence over inc
255  else if (fifo_wd_rd) write_address <= {write_address[31:12],next_wr_address_w[11:0]};
256 
257  end
258 // localparam AW_FIFO_NUM = 8; // Maximal number of words in AW FIFO 8-words
259 // localparam W_FIFO_NUM = 8; // Maximal number of words in AW 8-words
260 
261 
262 fifo_same_clock_fill #( .DATA_WIDTH(50),.DATA_DEPTH(AW_FIFO_DEPTH)) // read - 4, write - 32?
263  waddr_i (
264  .rst (rst),
265  .clk (aclk),
266  .sync_rst (1'b0),
267  .we (awvalid && awready),
269  .data_in ({awid[5:0], awburst[1:0], awsize[1:0], awlen[3:0], awaddr[31:0], awqos[3:0]}),
270  .data_out ({awid_out[5:0], awburst_out[1:0],awsize_out[1:0],awlen_out[3:0],awaddr_out[31:0], sim_wr_qos[3:0]}),
271  .nempty (aw_nempty),
272  .half_full (), // aw_half_full),
273  .under (), // waddr_under), // output reg
274  .over (), // waddr_over), // output reg
275  .wcount (), // waddr_wcount), // output[3:0] reg
276  .rcount (), // waddr_rcount), // output[3:0] reg
277  .wnum_in_fifo (wacount), // output[3:0]
278  .rnum_in_fifo () // output[3:0]
279  );
280 fifo_same_clock_fill #( .DATA_WIDTH(43), .DATA_DEPTH(W_FIFO_DEPTH))
281  wdata_i (
282  .rst (rst),
283  .clk (aclk),
284  .sync_rst (1'b0),
285  .we (wvalid && wready),
286  .re (fifo_wd_rd), //start_write_burst_w), // wrong
287  .data_in ({wlast, wid[5:0], wstrb[3:0], wdata[31:0]}),
288  .data_out ({wlast_out,wid_out[5:0], wstrb_out[3:0], wdata_out[31:0]}),
289  .nempty (w_nempty),
290  .half_full (), //w_half_full),
291  .under (), //wdata_under), // output reg
292  .over (), //wdata_over), // output reg
293  .wcount (), //wdata_wcount), // output[3:0] reg
294  .rcount (), //wdata_rcount), // output[3:0] reg
295  .wnum_in_fifo (wcount), // output[3:0]
296  .rnum_in_fifo () // output[3:0]
297  );
298 // **** Write response channel ****
299  wire [ 1:0] bresp_value=2'b0;
300  wire [ 1:0] bresp_in;
301 
303  wire [5:0] bid_in;
304 
305 // input [ 3:0] sim_bresp_latency, // latency in writing data outside of the module
306 
308  .WIDTH(1)
309  ) bresp_dly_16_i (
310  .clk(aclk), // input
311  .rst(rst), // input
312  .dly(sim_bresp_latency[3:0]), // input[3:0]
313  .din(last_confirmed_write), //fifo_wd_rd), // input[0:0]
314  .dout(fifo_wd_rd_dly) // output[0:0]
315  );
316 
317  // first FIFO for bresp - latency outside of the module
318 // wresp per burst, not per item !
319 fifo_same_clock_fill #( .DATA_WIDTH(8),.DATA_DEPTH(5))
320  wresp_ext_i (
321  .rst (rst),
322  .clk (aclk),
323  .sync_rst (1'b0),
324  .we (last_confirmed_write), // fifo_wd_rd),
325  .re (fifo_wd_rd_dly), // not allowing RE next cycle after bvalid
326  .data_in ({wid_out[5:0],bresp_value[1:0]}),
327  .data_out ({bid_in[5:0],bresp_in[1:0]}),
328  .nempty (),
329  .half_full (), //),
330  .under (), //wresp_under), // output reg
331  .over (), //wresp_over), // output reg
332  .wcount (), //wresp_wcount), // output[3:0] reg
333  .rcount (), //wresp_rcount), // output[3:0] reg
334  .wnum_in_fifo (), // wresp_num_in_fifo) // output[3:0]
335  .rnum_in_fifo () // wresp_num_in_fifo) // output[3:0]
336  );
337 
338  assign wresp_re=bready && bvalid; // && !was_wresp_re;
339  always @ (posedge rst or posedge aclk) begin
340  if (rst) was_wresp_re<=0;
341  else was_wresp_re <= wresp_re;
342  end
343  assign bvalid=|wresp_num_in_fifo[5:1] || (!was_wresp_re && wresp_num_in_fifo[0]);
344  // second wresp FIFO (does it exist in the actual module)?
345 fifo_same_clock_fill #( .DATA_WIDTH(8),.DATA_DEPTH(5))
346  wresp_i (
347  .rst (rst),
348  .clk (aclk),
349  .sync_rst (1'b0),
350  .we (fifo_wd_rd_dly),
351  .re (wresp_re), // not allowing RE next cycle after bvalid
352  .data_in ({bid_in[5:0],bresp_in[1:0]}),
353  .data_out ({bid[5:0],bresp[1:0]}),
354  .nempty (), //bvalid),
355  .half_full (), //),
356  .under (), //wresp_under), // output reg
357  .over (), //wresp_over), // output reg
358  .wcount (), //wresp_wcount), // output[3:0] reg
359  .rcount (), //wresp_rcount), // output[3:0] reg
360  .wnum_in_fifo (), // wresp_num_in_fifo) // output[3:0]
361  .rnum_in_fifo (wresp_num_in_fifo) // wresp_num_in_fifo) // output[3:0]
362  );
363 
364 endmodule
365 
10332clk
Definition: dly_16.v:44
9268VALID_AWCACHE_MASK4'b0011
9299wcountwire[W_FIFO_DEPTH:0]
9284wdata_outwire[31:0]
[31:0] 9251sim_wr_address
[WIDTH-1:0] 10336dout
Definition: dly_16.v:48
[DATA_WIDTH-1:0] 10452data_in
9298wacountwire[AW_FIFO_DEPTH:0]
[AW_FIFO_DEPTH:0] 9262AW_FIFO_NUM8
bresp_dly_16_i dly_16
[WIDTH-1:0] 10335din
Definition: dly_16.v:47
9300sim_wr_maskwire[3:0]
[W_FIFO_DEPTH:0] 9263W_FIFO_NUM8
reg [DATA_DEPTH-1:0] 10459rcount
[DATA_DEPTH: 0] 10460wnum_in_fifo
reg [DATA_DEPTH-1:0] 10458wcount
9301bresp_valuewire[1:0]
9273write_addressreg[31:0]
[DATA_WIDTH-1:0] 10453data_out
9280awaddr_outwire[31:0]
[ 3:0] 9258sim_bresp_latency
9277awburst_outwire[1:0]
9295wresp_num_in_fifowire[5:0]
wresp_i fifo_same_clock_fill
[DATA_DEPTH: 0] 10461rnum_in_fifo
10333rst
Definition: dly_16.v:45
9272next_wr_address_wreg[11:0]
[3:0] 10334dly
Definition: dly_16.v:46