x393  1.0
FPGAcodeforElphelNC393camera
simul_axi_hp_wr.v
Go to the documentation of this file.
1 
39 `timescale 1ns/1ps
40 
42  parameter [1:0] HP_PORT=0
43 ) (
44  input rst,
45  // AXI signals
46  input aclk,
47  output aresetn, // do not use?
48  // write address
49  input [31:0] awaddr,
50  input awvalid,
51  output awready,
52  input [ 5:0] awid,
53  input [ 1:0] awlock, // verify the correct values are here
54  input [ 3:0] awcache, // verify the correct values are here
55  input [ 2:0] awprot, // verify the correct values are here
56  input [ 3:0] awlen,
57  input [ 1:0] awsize,
58  input [ 1:0] awburst,
59  input [ 3:0] awqos, // verify the correct values are here
60  // write data
61  input [63:0] wdata,
62  input wvalid,
63  output wready,
64  input [ 5:0] wid,
65  input wlast,
66  input [ 7:0] wstrb,
67  // write response
68  output bvalid,
69  input bready,
70  output [ 5:0] bid,
71  output [ 1:0] bresp,
72  // PL extra (non-AXI) signals
73  output [ 7:0] wcount,
74  output [ 5:0] wacount, // racount has only 3 bits
75  input wrissuecap1en, // do not use yet
76  // Simulation signals - use same aclk
77  output [31:0] sim_wr_address,
78  output [ 5:0] sim_wid,
79  output sim_wr_valid, // ready to provide simulation data
80  input sim_wr_ready, // simulation may pause this channel by keeping this signal inactive
81  output [63:0] sim_wr_data,
82  output [ 7:0] sim_wr_stb,
83  input [ 3:0] sim_bresp_latency, // latency in writing data outside of the module
84  output [ 2:0] sim_wr_cap,
85  output [ 3:0] sim_wr_qos,
86  input [31:0] reg_addr,
87  input reg_wr,
88  input reg_rd,
89  input [31:0] reg_din,
90  output [31:0] reg_dout,
91  output reg_dvalid
92 );
93 // localparam ADDRESS_BITS=32;
94  localparam AFI_BASECTRL= 32'hf8008000+ (HP_PORT << 12);
95  localparam AFI_WRCHAN_CTRL= AFI_BASECTRL + 'h14;
96  localparam AFI_WRCHAN_ISSUINGCAP= AFI_BASECTRL + 'h18;
97  localparam AFI_WRQOS= AFI_BASECTRL + 'h1c;
98  localparam AFI_WRDATAFIFO_LEVEL= AFI_BASECTRL + 'h20;
99  localparam AFI_WRDEBUG= AFI_BASECTRL + 'h24; // SuppressThisWarning VEditor - not yet used
100 
101  localparam VALID_AWLOCK = 2'b0; // TODO
102  localparam VALID_AWCACHE = 4'b0011; //
103  localparam VALID_AWPROT = 3'b000;
104  localparam VALID_AWLOCK_MASK = 2'b11; // TODO
105  localparam VALID_AWCACHE_MASK = 4'b0011; //
106  localparam VALID_AWPROT_MASK = 3'b010;
107 /*
108 http://forums.xilinx.com/t5/Embedded-Processor-System-Design/Accessing-DDR-from-PL-on-Zynq/m-p/324877#M8413
109 Solved it!
110 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.
111 The default values set by VHLS were 0x00 and 0x10 respectively, which is also the case in the last post.
112 Alex
113 UPDATE: Xilinx docs say that (AR/AW)CACHE is ignored
114 
115 */
116 
117  reg [3:0] WrDataThreshold = 'hf;
118  reg [1:0] WrCmdReleaseMode = 0;
121  reg wrFabricQosEn = 0;
122  reg wr32BitEn = 0; // verify it i 0
123  reg [2:0] wrIssueCap1 = 0;
124  reg [2:0] wrIssueCap0 = 7;
125  reg [3:0] staticQos = 0;
126 
127  wire [3:0] wr_qos_in;
128  wire [3:0] wr_qos_out;
129 
130  wire aw_nempty;
131  wire w_nempty;
132  wire enough_data; // enough data to start a new burst
133  wire [11:3] next_wr_address; // bits that are incrtemented in 64-bit mode (higher are kept according to AXI 4KB inc. limit)
134  reg [31:0] write_address;
135  reg [5:0] awid_r; // awid registered with write_address
136  wire fifo_wd_rd; // read data fifo
138 
139 
140  wire [5:0] awid_out; // verify it matches wid_out when outputting data
141  wire [1:0] awburst_out;
142  wire [1:0] awsize_out; // verify it is 3'h3
143  wire [3:0] awlen_out;
144  wire [31:0] awaddr_out;
145  wire [5:0] wid_out;
146  wire wlast_out;
147  wire [7:0] wstrb_out;
148  wire [63:0] wdata_out;
149 
152  reg [3:0] write_left;
153  reg [ 1:0] wburst; // registered burst type
154  reg [ 3:0] wlen; // registered awlen type (for wrapped over transfers)
156  reg start_write_burst_r; // next after start_write_burst_w
157  wire write_in_progress_w; // should go inactive last confirmed upstream cycle
159 
160  wire [5:0] wresp_num_in_fifo;
162  wire wresp_re;
163 
164  reg [ 7:0] num_full_data = 0; // Number of full data bursts in FIFO
166 
167  // documentation sais : "When set, allows the priority of a transaction at the head of the WrCmdQ to be promoted if higher
168  // priority transactions are backed up behind it." Whqt about demotion? Assuming it is not demoted
171  assign wr_qos_in = wrFabricQosEn?(awqos & {4{awvalid}}) : staticQos;
172  //awqos & {4{awvalid}}
173  assign aresetn= ~rst; // probably not needed at all - docs say "do not use"
174  // Supported control register fields
176  {24'b0,wcount}:
177  ( (reg_rd && (reg_addr==AFI_WRCHAN_CTRL))?
180  {25'b0,wrIssueCap1,1'b0,wrIssueCap0}:
181  ( (reg_rd && (reg_addr==AFI_WRQOS))?
182  {28'b0,staticQos}:32'bz)));
183  assign reg_dvalid = (reg_rd && ((reg_addr==AFI_WRDATAFIFO_LEVEL) ||
186  (reg_addr==AFI_WRQOS))) ? 1 : 0;
187 
188  always @ (posedge aclk or posedge rst) begin
189  if (rst) begin
190  WrDataThreshold <= 'hf;
191  WrCmdReleaseMode <= 0;
192  wrQosHeadOfCmdQEn <= 0;
193  wrFabricOutCmdEn <= 0;
194  wrFabricQosEn <= 0;
195  wr32BitEn <= 0;
196  end else if (reg_wr && (reg_addr==AFI_WRCHAN_CTRL)) begin
197  WrDataThreshold <= reg_din[11:8];
198  WrCmdReleaseMode <= reg_din[5:4];
201  wrFabricQosEn <= reg_din[1];
202  wr32BitEn <= reg_din[0];
203  end
204  if (rst) begin
205  wrIssueCap1 <= 0;
206  wrIssueCap0 <= 7;
207  end else if (reg_wr && (reg_addr==AFI_WRCHAN_ISSUINGCAP)) begin
208  wrIssueCap1 <= reg_din[6:4];
209  wrIssueCap0 <= reg_din[2:0];
210  end
211  if (rst) begin
212  staticQos <= 0;
213  end else if (reg_wr && (reg_addr==AFI_WRQOS)) begin
214  staticQos <= reg_din[3:0];
215  end
216  end
217 
218  // generate ready signals for address and data
219  assign wready= !wcount[7] && (!(&wcount[6:0]) || !fifo_data_we_d);
220  always @ (posedge rst or posedge aclk) begin
221  if (rst) fifo_data_we_d<=0;
222  else fifo_data_we_d <= wready && wvalid;
223  end
224  assign awready= !wacount[5] && (!(&wacount[4:0]) || !fifo_addr_we_d);
225  always @ (posedge rst or posedge aclk) begin
226  if (rst) fifo_addr_we_d<=0;
227  else fifo_addr_we_d <= awready && awvalid;
228  end
229 
230  // Count full data bursts ready in FIFO
231  always @ (posedge rst or posedge aclk) begin
232  if (rst) num_full_data <=0;
235  end
236 
237 
239  assign enough_data=|num_full_data || ((WrCmdReleaseMode==2'b01) && (wcount > {4'b0,WrDataThreshold}));
241  assign sim_wr_valid= write_in_progress && w_nempty; // for continuing writes
242  assign last_confirmed_write = (write_left==0) && fifo_wd_rd && wlast_out; // wlast_out should take precedence over write_left?
243  assign start_write_burst_w=
244  aw_nempty && enough_data &&
246 
247  assign write_in_progress_w=
249 
250  // AXI: Bursts should not cross 4KB boundaries (... and to limit size of the address incrementer)
251  // in 64 bit mode - low 3 bits are preserved, next 9 are incremented
252  assign next_wr_address[11:3] =
253  wburst[1]?
254  (wburst[0]? {9'bx}:((write_address[11:3] + 1) & {5'h1f, ~wlen[3:0]})):
255  (wburst[0]? (write_address[11:3]+1):(write_address[11:3]));
256  assign sim_wr_data= wdata_out;
257  assign sim_wid= wid_out;
258  assign sim_wr_stb=wstrb_out;
259 
260  always @ (posedge aclk) begin
262  if (start_write_burst_r) begin
263  if (awid_r != wid_out) begin
264  $display ("%m: at time %t ERROR: awid=%h, wid=%h",$time,awid_out,wid_out);
265  $stop;
266  end
267  end
268  if (start_write_burst_w) begin
269  if (awsize_out != 2'h3) begin
270  $display ("%m: at time %t ERROR: awsize_out=%h, currently only 'h3 (8 bytes) is valid",$time,awsize_out);
271  $stop;
272  end
273  end
274  if (awvalid && awready) begin
275  if (((awlock ^ VALID_AWLOCK) & VALID_AWLOCK_MASK) != 0) begin
276  $display ("%m: at time %t ERROR: awlock = %h, valid %h with mask %h",$time, awlock, VALID_AWLOCK, VALID_AWLOCK_MASK);
277  $stop;
278  end
279  if (((awcache ^ VALID_AWCACHE) & VALID_AWCACHE_MASK) != 0) begin
280  $display ("%m: at time %t ERROR: awcache = %h, valid %h with mask %h",$time, awcache, VALID_AWCACHE, VALID_AWCACHE_MASK);
281  $stop;
282  end
283  if (((awprot ^ VALID_AWPROT) & VALID_AWPROT_MASK) != 0) begin
284  $display ("%m: at time %t ERROR: awprot = %h, valid %h with mask %h",$time, awprot, VALID_AWPROT, VALID_AWPROT_MASK);
285  $stop;
286  end
287  end
288  end
289 
290 
291 
292  always @ (posedge aclk or posedge rst) begin
293  if (rst) wburst[1:0] <= 0;
294  else if (start_write_burst_w) wburst[1:0] <= awburst_out[1:0];
295 
296  if (rst) wlen[3:0] <= 0;
297  else if (start_write_burst_w) wlen[3:0] <= awlen_out[3:0];
298 
299  if (rst) write_in_progress <= 0;
301 
302  if (rst) write_left <= 0;
303  else if (start_write_burst_w) write_left <= awlen_out[3:0]; // precedence over inc
304  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.
305 
306  if (rst) write_address <= 32'bx;
307  else if (start_write_burst_w) write_address <= awaddr_out; // precedence over inc
308  else if (fifo_wd_rd) write_address <= {write_address[31:12],next_wr_address[11:3],write_address[2:0]};
309 
310  if (rst) awid_r <= 6'bx;
311  else if (start_write_burst_w) awid_r <= awid_out; // precedence over inc
312 
313  end
314 
315 
316 
317 fifo_same_clock_fill #( .DATA_WIDTH(50),.DATA_DEPTH(5)) // read - 4, write - 32?
318  waddr_i (
319  .rst (rst),
320  .clk (aclk),
321  .sync_rst (1'b0),
322  .we (awvalid && awready),
324  .data_in ({awid[5:0], awburst[1:0], awsize[1:0], awlen[3:0], awaddr[31:0], wr_qos_in[3:0]}),
325  .data_out ({awid_out[5:0], awburst_out[1:0],awsize_out[1:0],awlen_out[3:0],awaddr_out[31:0], wr_qos_out[3:0]}),
326  .nempty (aw_nempty),
327  .half_full (), //aw_half_full),
328  .under (), //waddr_under), // output reg
329  .over (), //waddr_over), // output reg
330  .wcount (), //waddr_wcount), // output[3:0] reg
331  .rcount (), //waddr_rcount), // output[3:0] reg
332  .wnum_in_fifo (wacount), // output[3:0]
333  .rnum_in_fifo () // output[3:0]
334  );
335 fifo_same_clock_fill #( .DATA_WIDTH(79),.DATA_DEPTH(7))
336  wdata_i (
337  .rst (rst),
338  .clk (aclk),
339  .sync_rst (1'b0),
340  .we (wvalid && wready),
341  .re (fifo_wd_rd), //start_write_burst_w), // wrong
342  .data_in ({wlast, wid[5:0], wstrb[7:0], wdata[63:0]}),
343  .data_out ({wlast_out,wid_out[5:0], wstrb_out[7:0], wdata_out[63:0]}),
344  .nempty (w_nempty),
345  .half_full (), //w_half_full),
346  .under (), //wdata_under), // output reg
347  .over (), //wdata_over), // output reg
348  .wcount (), //wdata_wcount), // output[3:0] reg
349  .rcount (), //wdata_rcount), // output[3:0] reg
350  .wnum_in_fifo (wcount), // output[3:0]
351  .rnum_in_fifo () // output[3:0]
352  );
353 // **** Write response channel ****
354  wire [ 1:0] bresp_value=2'b0;
355  wire [ 1:0] bresp_in;
356 
358  wire [5:0] bid_in;
359 
360 // input [ 3:0] sim_bresp_latency, // latency in writing data outside of the module
361 
363  .WIDTH(1)
364  ) bresp_dly_16_i (
365  .clk (aclk), // input
366  .rst (rst), // input
367  .dly (sim_bresp_latency[3:0]), // input[3:0]
368  .din (last_confirmed_write), //fifo_wd_rd), // input[0:0]
369  .dout (fifo_wd_rd_dly) // output[0:0]
370  );
371 
372  // first FIFO for bresp - latency outside of the module
373 // wresp per burst, not per item !
374 fifo_same_clock_fill #( .DATA_WIDTH(8),.DATA_DEPTH(5))
375  wresp_ext_i (
376  .rst (rst),
377  .clk (aclk),
378  .sync_rst (1'b0),
379  .we (last_confirmed_write), // fifo_wd_rd),
380  .re (fifo_wd_rd_dly), // not allowing RE next cycle after bvalid
381  .data_in ({wid_out[5:0],bresp_value[1:0]}),
382  .data_out ({bid_in[5:0],bresp_in[1:0]}),
383  .nempty (),
384  .half_full (), //),
385  .under (), //wresp_under), // output reg
386  .over (), //wresp_over), // output reg
387  .wcount (), //wresp_wcount), // output[3:0] reg
388  .rcount (), //wresp_rcount), // output[3:0] reg
389  .wnum_in_fifo (), // wresp_num_in_fifo) // output[3:0]
390  .rnum_in_fifo () // wresp_num_in_fifo) // output[3:0]
391  );
392 
393  assign wresp_re=bready && bvalid; // && !was_wresp_re;
394  always @ (posedge rst or posedge aclk) begin
395  if (rst) was_wresp_re<=0;
396  else was_wresp_re <= wresp_re;
397  end
398  assign bvalid=|wresp_num_in_fifo[5:1] || (!was_wresp_re && wresp_num_in_fifo[0]);
399  // second wresp FIFO (does it exist in the actual module)?
400 fifo_same_clock_fill #( .DATA_WIDTH(8),.DATA_DEPTH(5))
401  wresp_i (
402  .rst (rst),
403  .clk (aclk),
404  .sync_rst (1'b0),
405  .we (fifo_wd_rd_dly),
406  .re (wresp_re), // not allowing RE next cycle after bvalid
407  .data_in ({bid_in[5:0],bresp_in[1:0]}),
408  .data_out ({bid[5:0],bresp[1:0]}),
409  .nempty (), //bvalid),
410  .half_full (), //),
411  .under (), //wresp_under), // output reg
412  .over (), //wresp_over), // output reg
413  .wcount (), //wresp_wcount), // output[3:0] reg
414  .rcount (), //wresp_rcount), // output[3:0] reg
415  .wnum_in_fifo (), // wresp_num_in_fifo) // output[3:0]
416  .rnum_in_fifo (wresp_num_in_fifo) // wresp_num_in_fifo) // output[3:0]
417  );
418 
419 endmodule
420 
10332clk
Definition: dly_16.v:44
[ 7:0] 8983sim_wr_stb
9014wr_qos_inwire[3:0]
9000VALID_AWCACHE4'b0011
9015wr_qos_outwire[3:0]
wresp_i fifo_same_clock_fill
9004VALID_AWPROT_MASK3'b010
9045num_full_datareg[7:0]
9025awburst_outwire[1:0]
9011wrIssueCap1reg[2:0]
9035write_leftreg[3:0]
[WIDTH-1:0] 10336dout
Definition: dly_16.v:48
bresp_dly_16_i dly_16
[DATA_WIDTH-1:0] 10452data_in
9024awid_outwire[5:0]
[31:0] 8978sim_wr_address
[ 3:0] 8984sim_bresp_latency
9029wid_outwire[5:0]
9003VALID_AWCACHE_MASK4'b0011
[ 2:0] 8985sim_wr_cap
9019next_wr_addresswire[11:3]
[63:0] 8982sim_wr_data
[WIDTH-1:0] 10335din
Definition: dly_16.v:47
[31:0] 8987reg_addr
[ 3:0] 8986sim_wr_qos
9032wdata_outwire[63:0]
9031wstrb_outwire[7:0]
9006WrCmdReleaseModereg[1:0]
reg [DATA_DEPTH-1:0] 10459rcount
[DATA_DEPTH: 0] 10460wnum_in_fifo
reg [DATA_DEPTH-1:0] 10458wcount
9012wrIssueCap0reg[2:0]
9048bresp_inwire[1:0]
9027awlen_outwire[3:0]
8995AFI_WRCHAN_ISSUINGCAPAFI_BASECTRL + 'h18
9026awsize_outwire[1:0]
[DATA_WIDTH-1:0] 10453data_out
9047bresp_valuewire[1:0]
8997AFI_WRDATAFIFO_LEVELAFI_BASECTRL + 'h20
8994AFI_WRCHAN_CTRLAFI_BASECTRL + 'h14
9042wresp_num_in_fifowire[5:0]
8993AFI_BASECTRL32'hf8008000+ (HP_PORT << 12
9005WrDataThresholdreg[3:0]
8998AFI_WRDEBUGAFI_BASECTRL + 'h24
9020write_addressreg[31:0]
8996AFI_WRQOSAFI_BASECTRL + 'h1c
[DATA_DEPTH: 0] 10461rnum_in_fifo
10333rst
Definition: dly_16.v:45
[31:0] 8991reg_dout
9028awaddr_outwire[31:0]
[3:0] 10334dly
Definition: dly_16.v:46