x393  1.0
FPGAcodeforElphelNC393camera
cmd_encod_linear_rd.v
Go to the documentation of this file.
1 
40 `timescale 1ns/1ps
41 
43 // parameter BASEADDR = 0,
44  parameter ADDRESS_NUMBER= 15,
45  parameter COLADDR_NUMBER= 10,
46  parameter NUM_XFER_BITS= 6, // number of bits to specify transfer length
47  parameter CMD_PAUSE_BITS= 10,
48  parameter CMD_DONE_BIT= 10, // VDT BUG: CMD_DONE_BIT is used in a function call parameter!
49  parameter RSEL= 1'b1
50 ) (
51  input mrst,
52  input clk,
53 // programming interface
54 // input [7:0] cmd_ad, // byte-serial command address/data (up to 6 bytes: AL-AH-D0-D1-D2-D3
55 // input cmd_stb, // strobe (with first byte) for the command a/d
56  input [2:0] bank_in, // bank address
57  input [ADDRESS_NUMBER-1:0] row_in, // memory row
58  input [COLADDR_NUMBER-4:0] start_col, // start memory column in 8-bursts
59  input [NUM_XFER_BITS-1:0] num128_in, // number of 128-bit words to transfer (8*16 bits) - full bursts of 8 ( 0 - maximal length, 64)
60  input skip_next_page_in, // do not reset external buffer (continue)
61  input start, // start generating commands
62  output reg [31:0] enc_cmd, // encoded command SuppressThisWarning VivadoSynthesis [Synth 8-3332] Sequential element cmd_encod_linear_rd.enc_cmd_reg[10:9,7:5,2] is unused and will be removed from module cmd_encod_linear_rd.
63  output reg enc_wr, // write encoded command
64  output reg enc_done // encoding finished
65 );
66  localparam ROM_WIDTH=10;
67  localparam ROM_DEPTH=4;
68 
69 // localparam ENC_BUF_PGNEXT= 0;
70  localparam ENC_NOP= 0;
71  localparam ENC_BUF_WR= 1;
72  localparam ENC_DCI= 2;
73  localparam ENC_SEL= 3;
74  localparam ENC_CMD_SHIFT= 4; // [5:4] - command: 0 -= NOP, 1 - READ, 2 - PRECHARGE, 3 - ACTIVATE
75  localparam ENC_PAUSE_SHIFT=6; // [7:6] - 2- bit pause (for NOP commandes)
76  localparam ENC_PRE_DONE= 8;
77  localparam ENC_BUF_PGNEXT= 9;
78 
79  localparam ENC_CMD_NOP= 0; // 2-bit locally encoded commands
80  localparam ENC_CMD_READ= 1;
81  localparam ENC_CMD_PRECHARGE=2;
82  localparam ENC_CMD_ACTIVATE= 3;
83  localparam REPEAT_ADDR=3;
84 
85  localparam CMD_NOP= 0; // 3-bit normal memory RCW commands (positive logic)
86  localparam CMD_READ= 2;
87  localparam CMD_PRECHARGE=5;
88  localparam CMD_ACTIVATE= 4;
89 
90  reg [ADDRESS_NUMBER-1:0] row; // memory row
91  reg [COLADDR_NUMBER-4:0] col; // start memory column (3 LSBs should be 0?) // VDT BUG: col is used as a function call parameter!
92  reg [2:0] bank; // memory bank;
93  reg [NUM_XFER_BITS-1:0] num128; // number of 128-bit words to transfer
95  reg gen_run;
96 // reg gen_run_d;
97  reg [ROM_DEPTH-1:0] gen_addr; // will overrun as stop comes from ROM
98 
99  reg [ROM_WIDTH-1:0] rom_r; // SuppressThisWarning VivadoSynthesis [Synth 8-3332] Sequential element cmd_encod_linear_rd.rom_r_reg[0] is unused and will be removed from module cmd_encod_linear_rd.
100  wire pre_done;
101  wire [1:0] rom_cmd;
102  wire [1:0] rom_skip;
103  wire [2:0] full_cmd;
104 // reg done;
105 
106  assign pre_done=rom_r[ENC_PRE_DONE] && gen_run;
107  assign rom_cmd= rom_r[ENC_CMD_SHIFT+:2];
108  assign rom_skip= rom_r[ENC_PAUSE_SHIFT+:2];
110 
111  always @ (posedge clk) begin
112  if (mrst) gen_run <= 0;
113  else if (start) gen_run<= 1;
114  else if (pre_done) gen_run<= 0;
115 
116 
117  if (mrst) gen_addr <= 0;
118  else if (!start && !gen_run) gen_addr <= 0;
119 /// else if ((gen_addr==(REPEAT_ADDR-1)) && (num128[NUM_XFER_BITS-1:1]==0)) gen_addr <= REPEAT_ADDR+1; // skip loop alltogeter
120 // AF 2015/09/12 : num128[NUM_XFER_BITS-1:0] == 0 for the full 64-bursts!
121  else if ((gen_addr==(REPEAT_ADDR-1)) && (num128[NUM_XFER_BITS-1:0] == 1)) gen_addr <= REPEAT_ADDR+1; // skip loop alltogeter
122  else if ((gen_addr !=REPEAT_ADDR) || (num128[NUM_XFER_BITS-1:1]==0)) gen_addr <= gen_addr+1; // not in a loop
123 //counting loops?
124  if (mrst) num128 <= 0;
125  else if (start) num128 <= num128_in;
126  else if (!gen_run) num128 <= 0; //
127  else if ((gen_addr == (REPEAT_ADDR-1)) || (gen_addr == REPEAT_ADDR)) num128 <= num128 -1;
128  end
129 
130  always @ (posedge clk) if (start) begin
131  row<=row_in;
132 // col <= start_col;
133  bank <= bank_in;
135  end
136  always @ (posedge clk) begin
137  if (start) col <= start_col;
138  else if (rom_cmd==ENC_CMD_READ) col <= col+1;
139  end
140 
141  // ROM-based (registered output) encoded sequence
142  always @ (posedge clk) begin
143  if (mrst) rom_r <= 0;
144  else case (gen_addr)
145  4'h0: rom_r <= (ENC_CMD_ACTIVATE << ENC_CMD_SHIFT);
146  4'h1: rom_r <= (ENC_CMD_NOP << ENC_CMD_SHIFT) | (1 << ENC_PAUSE_SHIFT);
147  4'h2: rom_r <= (ENC_CMD_READ << ENC_CMD_SHIFT) | (1 << ENC_NOP) | (1 << ENC_BUF_WR) | (1 << ENC_DCI) | (RSEL << ENC_SEL);
148  4'h3: rom_r <= (ENC_CMD_READ << ENC_CMD_SHIFT) | (1 << ENC_NOP) | (1 << ENC_BUF_WR) | (1 << ENC_DCI) | (RSEL << ENC_SEL);
149  4'h4: rom_r <= (ENC_CMD_NOP << ENC_CMD_SHIFT) | (1 << ENC_PAUSE_SHIFT) | (1 << ENC_DCI) | (RSEL << ENC_SEL);
150  4'h5: rom_r <= (ENC_CMD_NOP << ENC_CMD_SHIFT) | (1 << ENC_BUF_PGNEXT) | (1 << ENC_DCI) | (RSEL << ENC_SEL);
151  4'h6: rom_r <= (ENC_CMD_PRECHARGE << ENC_CMD_SHIFT) | (1 << ENC_DCI);
152  4'h7: rom_r <= (ENC_CMD_NOP << ENC_CMD_SHIFT) | (2 << ENC_PAUSE_SHIFT) | (1 << ENC_DCI);
153  4'h8: rom_r <= (ENC_CMD_NOP << ENC_CMD_SHIFT) | (1 << ENC_PRE_DONE);
154  default:rom_r <= 0;
155  endcase
156  end
157  always @ (posedge clk) begin
158 
159  if (mrst) enc_wr <= 0;
160  else enc_wr <= gen_run; // || gen_run_d;
161 
162  if (mrst) enc_done <= 0;
163  else enc_done <= enc_wr && !gen_run; // !gen_run_d;
164 
165  if (mrst) enc_cmd <= 0;
166  else if (gen_run) begin
167  if (rom_cmd==0) enc_cmd <= func_encode_skip ( // encode pause
168  {{CMD_PAUSE_BITS-2{1'b0}},rom_skip[1:0]}, // skip; // number of extra cycles to skip (and keep all the other outputs)
169  pre_done, // done, // end of sequence
170  bank[2:0], // bank (here OK to be any)
171  1'b0, // odt_en; // enable ODT
172  1'b0, // cke; // disable CKE
173  rom_r[ENC_SEL], // sel; // first/second half-cycle, other will be nop (cke+odt applicable to both)
174  1'b0, // dq_en; // enable (not tristate) DQ lines (internal timing sequencer for 0->1 and 1->0)
175  1'b0, // dqs_en; // enable (not tristate) DQS lines (internal timing sequencer for 0->1 and 1->0)
176  1'b0, // dqs_toggle; // enable toggle DQS according to the pattern
177  rom_r[ENC_DCI], // dci; // DCI disable, both DQ and DQS lines (internal logic and timing sequencer for 0->1 and 1->0)
178  rom_r[ENC_BUF_WR], // buf_wr; // connect to external buffer (but only if not paused)
179  1'b0, // buf_rd; // connect to external buffer (but only if not paused)
180  rom_r[ENC_BUF_PGNEXT] && !skip_next_page); // buf_rst; // connect to external buffer (but only if not paused)
181  else enc_cmd <= func_encode_cmd ( // encode non-NOP command
182  rom_cmd[1]?
183  row:
184  {{ADDRESS_NUMBER-COLADDR_NUMBER{1'b0}},col[COLADDR_NUMBER-4:0],3'b0}, // [14:0] addr; // 15-bit row/column address
185  bank[2:0], // bank (here OK to be any)
186  full_cmd[2:0], // rcw; // RAS/CAS/WE, positive logic
187  1'b0, // odt_en; // enable ODT
188  1'b0, // cke; // disable CKE
189  rom_r[ENC_SEL], // sel; // first/second half-cycle, other will be nop (cke+odt applicable to both)
190  1'b0, // dq_en; // enable (not tristate) DQ lines (internal timing sequencer for 0->1 and 1->0)
191  1'b0, // dqs_en; // enable (not tristate) DQS lines (internal timing sequencer for 0->1 and 1->0)
192  1'b0, // dqs_toggle; // enable toggle DQS according to the pattern
193  rom_r[ENC_DCI], // dci; // DCI disable, both DQ and DQS lines (internal logic and timing sequencer for 0->1 and 1->0)
194  rom_r[ENC_BUF_WR], // buf_wr; // connect to external buffer (but only if not paused)
195  1'b0, // buf_rd; // connect to external buffer (but only if not paused)
196  rom_r[ENC_NOP], // nop; // add NOP after the current command, keep other data
197  rom_r[ENC_BUF_PGNEXT] && !skip_next_page); // buf_rst; // connect to external buffer (but only if not paused)
198  end
199  end
200 
201 // move to include?/*!
202  * @file x393_mcontr_encode_cmd.vh
203  * @date 2015-02-09
204  * @author Andrey Filippov
205  *
206  * @brief Functions used to encode memory controller sequences
207  *
208  * @copyright Copyright (c) 2015 Elphel, Inc.
209  *
210  * <b>License:</b>
211  *
212  * x393_mcontr_encode_cmd.vh is free software; you can redistribute it and/or modify
213  * it under the terms of the GNU General Public License as published by
214  * the Free Software Foundation, either version 3 of the License, or
215  * (at your option) any later version.
216  *
217  * x393_mcontr_encode_cmd.vh is distributed in the hope that it will be useful,
218  * but WITHOUT ANY WARRANTY; without even the implied warranty of
219  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
220  * GNU General Public License for more details.
221  *
222  * You should have received a copy of the GNU General Public License
223  * along with this program. If not, see <http://www.gnu.org/licenses/> .
224  *
225  * Additional permission under GNU GPL version 3 section 7:
226  * If you modify this Program, or any covered work, by linking or combining it
227  * with independent modules provided by the FPGA vendor only (this permission
228  * does not extend to any 3-rd party modules, "soft cores" or macros) under
229  * different license terms solely for the purpose of generating binary "bitstream"
230  * files and/or simulating the code, the copyright holders of this Program give
231  * you the right to distribute the covered work without those independent modules
232  * as long as the source code for them is available from the FPGA vendor free of
233  * charge, and there is no dependence on any encrypted modules for simulating of
234  * the combined code. This permission applies to you if the distributed code
235  * contains all the components and scripts required to completely simulate it
236  * with at least one of the Free Software programs.
237  */
238 
239  function [31:0] func_encode_cmd;
240  input [14:0] addr; // 15-bit row/column address
241  input [2:0] bank; // bank (here OK to be any)
242  input [2:0] rcw; // RAS/CAS/WE, positive logic
243  input odt_en; // enable ODT
244  input cke; // disable CKE
245  input sel; // first/second half-cycle, other will be nop (cke+odt applicable to both)
246  input dq_en; // enable (not tristate) DQ lines (internal timing sequencer for 0->1 and 1->0)
247  input dqs_en; // enable (not tristate) DQS lines (internal timing sequencer for 0->1 and 1->0)
248  input dqs_toggle; // enable toggle DQS according to the pattern
249  input dci; // DCI disable, both DQ and DQS lines (internal logic and timing sequencer for 0->1 and 1->0)
250  input buf_wr; // connect to external buffer (but only if not paused)
251  input buf_rd; // connect to external buffer (but only if not paused)
252  input nop; // add NOP after the current command, keep other data
253  input buf_rst; // connect to external buffer (but only if not paused)
254  begin
255  func_encode_cmd={
256  addr[14:0], // 15-bit row/column address
257  bank [2:0], // bank
258  rcw[2:0], // RAS/CAS/WE
259  odt_en, // enable ODT
260  cke, // may be optimized (removed from here)?
261  sel, // first/second half-cycle, other will be nop (cke+odt applicable to both)
262  dq_en, // enable (not tristate) DQ lines (internal timing sequencer for 0->1 and 1->0)
263  dqs_en, // enable (not tristate) DQS lines (internal timing sequencer for 0->1 and 1->0)
264  dqs_toggle, // enable toggle DQS according to the pattern
265  dci, // DCI disable, both DQ and DQS lines (internal logic and timing sequencer for 0->1 and 1->0)
266  buf_wr, // phy_buf_wr, // connect to external buffer (but only if not paused)
267  buf_rd, // phy_buf_rd, // connect to external buffer (but only if not paused)
268  nop, // add NOP after the current command, keep other data
269  buf_rst // Reserved for future use
270  };
271  end
272  endfunction
273 
274  function [31:0] func_encode_skip;
275  input [CMD_PAUSE_BITS-1:0] skip; // number of extra cycles to skip (and keep all the other outputs)
276  input done; // end of sequence
277  input [2:0] bank; // bank (here OK to be any)
278  input odt_en; // enable ODT
279  input cke; // disable CKE
280  input sel; // first/second half-cycle, other will be nop (cke+odt applicable to both)
281  input dq_en; // enable (not tristate) DQ lines (internal timing sequencer for 0->1 and 1->0)
282  input dqs_en; // enable (not tristate) DQS lines (internal timing sequencer for 0->1 and 1->0)
283  input dqs_toggle; // enable toggle DQS according to the pattern
284  input dci; // DCI disable, both DQ and DQS lines (internal logic and timing sequencer for 0->1 and 1->0)
285  input buf_wr; // connect to external buffer (but only if not paused)
286  input buf_rd; // connect to external buffer (but only if not paused)
287  input buf_rst; // connect to external buffer (but only if not paused)
288  begin
289  func_encode_skip= func_encode_cmd (
290  {{14-CMD_DONE_BIT{1'b0}}, done, skip[CMD_PAUSE_BITS-1:0]}, // 15-bit row/column address
291  bank[2:0], // bank (here OK to be any)
292  3'b0, // RAS/CAS/WE, positive logic
293  odt_en, // enable ODT
294  cke, // disable CKE
295  sel, // first/second half-cycle, other will be nop (cke+odt applicable to both)
296  dq_en, // enable (not tristate) DQ lines (internal timing sequencer for 0->1 and 1->0)
297  dqs_en, // enable (not tristate) DQS lines (internal timing sequencer for 0->1 and 1->0)
298  dqs_toggle, // enable toggle DQS according to the pattern
299  dci, // DCI disable, both DQ and DQS lines (internal logic and timing sequencer for 0->1 and 1->0)
300  buf_wr, // connect to external buffer (but only if not paused)
301  buf_rd, // connect to external buffer (but only if not paused)
302  1'b0, // nop
303  buf_rst);
304  end
305  endfunction
306 
307 
308 endmodule
309 
3986gen_addrreg[ROM_DEPTH-1:0]
3987rom_rreg[ROM_WIDTH-1:0]
3980rowreg[ADDRESS_NUMBER-1:0]
[NUM_XFER_BITS-1:0] 3955num128_in
3983num128reg[NUM_XFER_BITS-1:0]
[ADDRESS_NUMBER-1:0] 3953row_in
3981colreg[COLADDR_NUMBER-4:0]
[COLADDR_NUMBER-4:0] 3954start_col