x393  1.0
FPGAcodeforElphelNC393camera
cmd_mux.v
Go to the documentation of this file.
1 
39 `timescale 1ns/1ps
40 
41 module cmd_mux #(
42  parameter AXI_WR_ADDR_BITS= 14,
43  parameter CONTROL_ADDR = 'h0000, // AXI write address of control write registers
44  parameter CONTROL_ADDR_MASK = 'h3800, // AXI write address of control registers
45  parameter NUM_CYCLES_LOW_BIT= 6, // decode addresses [NUM_CYCLES_LOW_BIT+:5] into command a/d length
46  parameter NUM_CYCLES_00 = 2, // 2-cycle 000.003f
47  parameter NUM_CYCLES_01 = 4, // 4-cycle 040.007f
48  parameter NUM_CYCLES_02 = 3, // 3-cycle 080.00bf
49  parameter NUM_CYCLES_03 = 3, // 3-cycle 0c0.00ff
50  parameter NUM_CYCLES_04 = 6, // 6-cycle 100.013f
51  parameter NUM_CYCLES_05 = 6, // 6-cycle 140.017f
52  parameter NUM_CYCLES_06 = 4, // 4-cycle 180.01bf
53  parameter NUM_CYCLES_07 = 4, // 4-cycle 1c0.01ff
54  parameter NUM_CYCLES_08 = 6, // 6-cycle 200.023f
55  parameter NUM_CYCLES_09 = 6, //
56  parameter NUM_CYCLES_10 = 6, //
57  parameter NUM_CYCLES_11 = 6, //
58  parameter NUM_CYCLES_12 = 6, //
59  parameter NUM_CYCLES_13 = 5, // 5-cycle - not yet used
60  parameter NUM_CYCLES_14 = 6, // 6-cycle - not yet used
61  parameter NUM_CYCLES_15 = 9, // single-cycle
62  parameter NUM_CYCLES_16 = 6, //
63  parameter NUM_CYCLES_17 = 6, //
64  parameter NUM_CYCLES_18 = 6, //
65  parameter NUM_CYCLES_19 = 6, //
66  parameter NUM_CYCLES_20 = 6, //
67  parameter NUM_CYCLES_21 = 6, //
68  parameter NUM_CYCLES_22 = 6, //
69  parameter NUM_CYCLES_23 = 6, //
70  parameter NUM_CYCLES_24 = 6, //
71  parameter NUM_CYCLES_25 = 6, //
72  parameter NUM_CYCLES_26 = 6, //
73  parameter NUM_CYCLES_27 = 6, //
74  parameter NUM_CYCLES_28 = 6, //
75  parameter NUM_CYCLES_29 = 6, //
76  parameter NUM_CYCLES_30 = 6, //
77  parameter NUM_CYCLES_31 = 6 //
78 
79 ) (
80  input axi_clk,
81  input mclk,
82  input mrst, // @posedge mclk - sync reset
83  input arst, // @posedge axi_clk - sync reset
84  // direct commands from AXI. No wait but for multi-cycle output and command sequencer (having higher priority)
85  input [AXI_WR_ADDR_BITS-1:0] pre_waddr, // AXI write address, before actual writes (to generate busy), valid@start_burst
86  input start_wburst, // burst start - should generate ~ready (should be AND-ed with !busy internally)
87  input [AXI_WR_ADDR_BITS-1:0] waddr, // write address, valid with wr_en
88  input wr_en, // write enable
89  input [31:0] wdata, // write data, valid with waddr and wr_en
90  output busy, // interface busy (combinatorial delay from start_wburst and pre_addr), controls AXI FIFO
91 
92  // frame-based commands from the command sequencer (no wait but for multi-cycle output
93  input [AXI_WR_ADDR_BITS-1:0] cseq_waddr, // write address, valid with cseq_wr_en
94  input cseq_wr_en, // write enable
95  input [31:0] cseq_wdata, // write data, valid with cseq_waddr and cseq_wr_en
96  output cseq_ackn, // command sequencer address/data accepted
97  // Write address /data/strobe to slaves. Both parallel and byte-serial data available. COmbined from AXI and command sequencer
98  output [AXI_WR_ADDR_BITS-1:0] par_waddr, // parallel address
99  output [31:0] par_data, // parallel 32-bit data
100  output [7:0] byte_ad, // byte-wide address/data (AL-AH-DB0-DB1-DB2-DB3)
101  output ad_stb // low address output strobe (and parallel A/D)
102 );
103 // Minimal - 1 cycle, AH=DB0=DB1=DB2=DB3=0;
104  reg busy_r=0;
105  reg selected=0; // address range to be processed here (outside - buffer(s) and command sequencer?)
106  wire fifo_half_empty; // just debugging with (* keep = "true" *)
108  wire ss; // current command (in par_waddr) is a single-cycle one
109  reg [47:0] par_ad;
110  reg ad_stb_r; // low address output strobe (and parallel A/D)
111  reg cmdseq_full_r; // address/data from the command sequencer is loaded to internal register (cseq_waddr_r,cseq_wdata_r)
112  reg [AXI_WR_ADDR_BITS-1:0] cseq_waddr_r; // registered command address from the sequencer
113  reg [31:0] cseq_wdata_r; // registered command data from the sequencer
114  reg [3:0] seq_length; // encoded ROM output - number of cycles in command sequence, [3] - single cycle
115  reg [4:0] seq_busy_r; // shift register loaded by decoded seq_length
116  wire [4:0] seq_length_rom_a; // address range used to determine command length
117 
118  wire can_start_w; // can start command cycle (either from sequencer or from AXI)
119  wire start_w; // start cycle
120  wire start_axi_w; // start cycle from the AXI (==fifo_re)
123  wire [31:0] wdata_fifo_out;
124 
126 
127  assign busy=busy_r && (start_wburst? selected_w: selected);// should be just combinatorial delay from start_wburst and decoded command
128  assign par_waddr=par_ad[AXI_WR_ADDR_BITS-1:0]; // parallel address
129  assign par_data=par_ad[47:16]; // parallel 32-bit data
130  assign byte_ad=par_ad[7:0]; // byte-wide address/data (AL-AH-DB0-DB1-DB2-DB3)
131  assign ad_stb=ad_stb_r; // low address output strobe (and parallel A/D)
132 
134  assign ss= seq_length[3];
135 
136  always @ (posedge axi_clk) begin
137  if (arst) selected <= 1'b0;
138  else if (start_wburst) selected <= selected_w;
139  if (arst) busy_r <= 1'b0;
140  else busy_r <= !fifo_half_empty;
141  end
142 
143 // ROM command length decoder TODO: put actual data
144 // always @ (seq_length_rom_a) begin
145  always @*
146  case (seq_length_rom_a) // just temporary - fill out later
147  5'h00:seq_length <= NUM_CYCLES_00;
148  5'h01:seq_length <= NUM_CYCLES_01;
149  5'h02:seq_length <= NUM_CYCLES_02;
150  5'h03:seq_length <= NUM_CYCLES_03;
151  5'h04:seq_length <= NUM_CYCLES_04;
152  5'h05:seq_length <= NUM_CYCLES_05;
153  5'h06:seq_length <= NUM_CYCLES_06;
154  5'h07:seq_length <= NUM_CYCLES_07;
155  5'h08:seq_length <= NUM_CYCLES_08;
156  5'h09:seq_length <= NUM_CYCLES_09;
157  5'h0a:seq_length <= NUM_CYCLES_10;
158  5'h0b:seq_length <= NUM_CYCLES_11;
159  5'h0c:seq_length <= NUM_CYCLES_12;
160  5'h0d:seq_length <= NUM_CYCLES_13;
161  5'h0e:seq_length <= NUM_CYCLES_14;
162  5'h0f:seq_length <= NUM_CYCLES_15;
163  5'h10:seq_length <= NUM_CYCLES_16;
164  5'h11:seq_length <= NUM_CYCLES_17;
165  5'h12:seq_length <= NUM_CYCLES_18;
166  5'h13:seq_length <= NUM_CYCLES_19;
167  5'h14:seq_length <= NUM_CYCLES_20;
168  5'h15:seq_length <= NUM_CYCLES_21;
169  5'h16:seq_length <= NUM_CYCLES_22;
170  5'h17:seq_length <= NUM_CYCLES_23;
171  5'h18:seq_length <= NUM_CYCLES_24;
172  5'h19:seq_length <= NUM_CYCLES_25;
173  5'h1a:seq_length <= NUM_CYCLES_26;
174  5'h1b:seq_length <= NUM_CYCLES_27;
175  5'h1c:seq_length <= NUM_CYCLES_28;
176  5'h1d:seq_length <= NUM_CYCLES_29;
177  5'h1e:seq_length <= NUM_CYCLES_30;
178  5'h1f:seq_length <= NUM_CYCLES_31;
179  endcase
180  always @ (posedge mclk) begin
181  if (mrst) seq_busy_r<=0;
182  else begin
183  if (ad_stb) begin
184  case (seq_length)
185  4'h2: seq_busy_r<=5'h01;
186  4'h3: seq_busy_r<=5'h03;
187  4'h4: seq_busy_r<=5'h07;
188  4'h5: seq_busy_r<=5'h0f;
189  4'h6: seq_busy_r<=5'h1f;
190  default: seq_busy_r<=5'h00;
191  endcase
192  end else seq_busy_r <= {1'b0,seq_busy_r[4:1]};
193  end
194  end
195 
196  assign can_start_w= ad_stb_r? ss: !seq_busy_r[1];
199  always @ (posedge mclk) begin
200  if (mrst) ad_stb_r <= 0;
201  else ad_stb_r <= start_w;
202  end
203  always @ (posedge mclk) begin
205  else par_ad <={8'b0,par_ad[47:8]};
206  end
207 
208  assign cseq_ackn= cseq_wr_en && (!cmdseq_full_r || can_start_w); // cmddseq_full has priority over axi, so (can_start_w && cmdseq_full_r)
209 
210  always @ (posedge mclk) begin
211  if (mrst) cmdseq_full_r <= 0;
213  end
214  always @ (posedge mclk) begin
215  if (cseq_ackn) begin
218  end
219  end
220 
221  /* FIFO to cross clock boundary **/
223  .DATA_WIDTH (AXI_WR_ADDR_BITS+32),
224  .DATA_DEPTH (4)
225  ) fifo_cross_clocks_i (
226  .rst (1'b0), // input
227  .rrst (mrst), // input
228  .wrst (arst), // input
229  .rclk (mclk), // input
230  .wclk (axi_clk), // input
231  .we (wr_en && selected), // input
232  .re (start_axi_w), // input
233  .data_in ({waddr[AXI_WR_ADDR_BITS-1:0],wdata[31:0]}), // input[15:0]
234  .data_out ({waddr_fifo_out[AXI_WR_ADDR_BITS-1:0],wdata_fifo_out[31:0]}), // output[15:0]
235  .nempty (fifo_nempty), // output
236  .half_empty (fifo_half_empty) // output
237  );
238 
239 
240 endmodule
10147NUM_CYCLES_316
Definition: cmd_mux.v:77
10157busy
Definition: cmd_mux.v:90
10136NUM_CYCLES_206
Definition: cmd_mux.v:66
10166busy_rreg
Definition: cmd_mux.v:104
10135NUM_CYCLES_196
Definition: cmd_mux.v:65
[31:0] 10156wdata
Definition: cmd_mux.v:89
10124NUM_CYCLES_086
Definition: cmd_mux.v:54
10127NUM_CYCLES_116
Definition: cmd_mux.v:57
10117NUM_CYCLES_014
Definition: cmd_mux.v:47
10125NUM_CYCLES_096
Definition: cmd_mux.v:55
10126NUM_CYCLES_106
Definition: cmd_mux.v:56
10176seq_lengthreg[3:0]
Definition: cmd_mux.v:114
10183waddr_fifo_outwire[AXI_WR_ADDR_BITS-1:0]
Definition: cmd_mux.v:122
fifo_cross_clocks_i fifo_cross_clocks
Definition: cmd_mux.v:222
10119NUM_CYCLES_033
Definition: cmd_mux.v:49
10123NUM_CYCLES_074
Definition: cmd_mux.v:53
10149mclk
Definition: cmd_mux.v:81
10145NUM_CYCLES_296
Definition: cmd_mux.v:75
10146NUM_CYCLES_306
Definition: cmd_mux.v:76
10165ad_stb
Definition: cmd_mux.v:101
10120NUM_CYCLES_046
Definition: cmd_mux.v:50
10143NUM_CYCLES_276
Definition: cmd_mux.v:73
[DATA_WIDTH-1:0] 10404data_out
10139NUM_CYCLES_236
Definition: cmd_mux.v:69
10144NUM_CYCLES_286
Definition: cmd_mux.v:74
10118NUM_CYCLES_023
Definition: cmd_mux.v:48
10131NUM_CYCLES_159
Definition: cmd_mux.v:61
10140NUM_CYCLES_246
Definition: cmd_mux.v:70
10134NUM_CYCLES_186
Definition: cmd_mux.v:64
10148axi_clk
Definition: cmd_mux.v:80
10129NUM_CYCLES_135
Definition: cmd_mux.v:59
10167selectedreg
Definition: cmd_mux.v:105
10178seq_length_rom_awire[4:0]
Definition: cmd_mux.v:116
10138NUM_CYCLES_226
Definition: cmd_mux.v:68
10155wr_en
Definition: cmd_mux.v:88
10142NUM_CYCLES_266
Definition: cmd_mux.v:72
10133NUM_CYCLES_176
Definition: cmd_mux.v:63
10168fifo_half_emptywire
Definition: cmd_mux.v:106
10132NUM_CYCLES_166
Definition: cmd_mux.v:62
10128NUM_CYCLES_126
Definition: cmd_mux.v:58
[AXI_WR_ADDR_BITS-1:0] 10162par_waddr
Definition: cmd_mux.v:98
10159cseq_wr_en
Definition: cmd_mux.v:94
10141NUM_CYCLES_256
Definition: cmd_mux.v:71
10112AXI_WR_ADDR_BITS14
Definition: cmd_mux.v:42
[7:0] 10164byte_ad
Definition: cmd_mux.v:100
[AXI_WR_ADDR_BITS-1:0] 10158cseq_waddr
Definition: cmd_mux.v:93
[AXI_WR_ADDR_BITS-1:0] 10152pre_waddr
Definition: cmd_mux.v:85
10161cseq_ackn
Definition: cmd_mux.v:96
[31:0] 10163par_data
Definition: cmd_mux.v:99
10130NUM_CYCLES_146
Definition: cmd_mux.v:60
10175cseq_wdata_rreg[31:0]
Definition: cmd_mux.v:113
10179can_start_wwire
Definition: cmd_mux.v:118
10174cseq_waddr_rreg[AXI_WR_ADDR_BITS-1:0]
Definition: cmd_mux.v:112
10184wdata_fifo_outwire[31:0]
Definition: cmd_mux.v:123
[31:0] 10160cseq_wdata
Definition: cmd_mux.v:95
10170sswire
Definition: cmd_mux.v:108
10122NUM_CYCLES_064
Definition: cmd_mux.v:52
[DATA_WIDTH-1:0] 10403data_in
10137NUM_CYCLES_216
Definition: cmd_mux.v:67
10177seq_busy_rreg[4:0]
Definition: cmd_mux.v:115
10169selected_wwire
Definition: cmd_mux.v:107
10113CONTROL_ADDR'h0000
Definition: cmd_mux.v:43
10181start_axi_wwire
Definition: cmd_mux.v:120
10171par_adreg[47:0]
Definition: cmd_mux.v:109
[AXI_WR_ADDR_BITS-1:0] 10154waddr
Definition: cmd_mux.v:87
10114CONTROL_ADDR_MASK'h3800
Definition: cmd_mux.v:44
10115NUM_CYCLES_LOW_BIT6
Definition: cmd_mux.v:45
10180start_wwire
Definition: cmd_mux.v:119
10172ad_stb_rreg
Definition: cmd_mux.v:110
10121NUM_CYCLES_056
Definition: cmd_mux.v:51
10173cmdseq_full_rreg
Definition: cmd_mux.v:111
10153start_wburst
Definition: cmd_mux.v:86
10151arst
Definition: cmd_mux.v:83
10150mrst
Definition: cmd_mux.v:82
10116NUM_CYCLES_002
Definition: cmd_mux.v:46
10182fifo_nemptywire
Definition: cmd_mux.v:121