cmd_frame_sequencer.v 27.1 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11
/*!
 * <b>Module:</b>cmd_frame_sequencer
 * @file cmd_frame_sequencer.v
 * @date 2015-06-30  
 * @author Andrey Filippov     
 *
 * @brief Store/dispatch commands on per-frame basis
 *
 * @copyright Copyright (c) 2015 Elphel, Inc.
 *
 * <b>License:</b>
12 13 14 15 16 17 18 19 20 21 22 23 24
 *
 * cmd_frame_sequencer.v is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 *  cmd_frame_sequencer.v is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/> .
25 26 27 28 29 30
 *
 * Additional permission under GNU GPL version 3 section 7:
 * If you modify this Program, or any covered work, by linking or combining it
 * with independent modules provided by the FPGA vendor only (this permission
 * does not extend to any 3-rd party modules, "soft cores" or macros) under
 * different license terms solely for the purpose of generating binary "bitstream"
31
 * files and/or simulating the code, the copyright holders of this Program give
32 33
 * you the right to distribute the covered work without those independent modules
 * as long as the source code for them is available from the FPGA vendor free of
Andrey Filippov's avatar
Andrey Filippov committed
34
 * charge, and there is no dependence on any encrypted modules for simulating of
35 36 37
 * the combined code. This permission applies to you if the distributed code
 * contains all the components and scripts required to completely simulate it
 * with at least one of the Free Software programs.
38
 */
39
`timescale 1ns/1ps
40
// Comments from the x353 code:
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
// This command sequencer is designed (together with i2c sequencer) to provide
// pipelined operation of the sensor, FPGA pre-processor and compressor, to avoid
// requirement of resetting the circuitry and loosing several frames when the sensor
// acquisition parameters are changed (especially geometry - WOI, decimation).
// It also reduces real-time requirements to the software, as it is possible to
// program parameters related to the events several frames in the future.
//
// 
// Controller is programmed through 32 locations. Each registers but the control require two writes:
// First write - register address (AXI_WR_ADDR_BITS bits), second - register data (32 bits)
// Writing to the contol register (0x1f) resets the first/second counter so the next write will be "first"
// 0x0..0xf write directly to the frame number [3:0] modulo 16, except if you write to the frame
//          "just missed" - in that case data will go to the current frame.
// 0x10 - write seq commands to be sent ASAP
// 0x11 - write seq commands to be sent after the next frame starts 
//
// 0x1e - write seq commands to be sent after the next 14 frame start pulses
// 0x1f - control register:
//     [14] -   reset all FIFO (takes 32 clock pulses), also - stops seq until run command
//     [13:12] - 3 - run seq, 2 - stop seq , 1,0 - no change to run state
61 62
// New - [1:0] - 0: NOP, 1: clear IRQ, 2 - Clear IE, 3: set IE

63
module  cmd_frame_sequencer#(
64
    parameter CMDFRAMESEQ_ADDR=                'h780,
65
    parameter CMDFRAMESEQ_MASK=                'h7e0,
66 67 68 69 70 71
    parameter AXI_WR_ADDR_BITS =                14,
    parameter CMDFRAMESEQ_DEPTH =               64, // 32/64/128
    parameter CMDFRAMESEQ_ABS =                 0,
    parameter CMDFRAMESEQ_REL =                 16,
    parameter CMDFRAMESEQ_CTRL =                31,
    parameter CMDFRAMESEQ_RST_BIT =             14,
72 73
    parameter CMDFRAMESEQ_RUN_BIT =             13,
    parameter CMDFRAMESEQ_IRQ_BIT =             0 // [1:0] used
74
)(
Andrey Filippov's avatar
Andrey Filippov committed
75
    input                         mrst,
76 77 78 79
    input                         mclk, // for command/status
     // programming interface
    input                   [7:0] cmd_ad,      // byte-serial command address/data (up to 6 bytes: AL-AH-D0-D1-D2-D3 
    input                         cmd_stb,     // strobe (with first byte) for the command a/d
80
    // frame sync and frame number
81 82 83 84 85 86
    input                         frame_sync,  // @posedge mclk
    output                 [ 3:0] frame_no,    // @posedge mclk
    // command mux interface    
    output [AXI_WR_ADDR_BITS-1:0] waddr,   // write address, valid with wr_en_out
    output                        valid,   // output data valid 
    output                 [31:0] wdata,   // write data, valid with waddr_out and wr_en_out
87 88 89 90
    input                         ackn,    // command sequencer address/data accepted
    // Interrupt mask, status, request
    output                        is,      // interrupt status (not masked)
    output                        im       // interrupt mask
91 92 93
);
    localparam PNTR_WIDH = (CMDFRAMESEQ_DEPTH > 32) ?((CMDFRAMESEQ_DEPTH > 64) ? 7 : 6) : 5;
    wire                  [4:0] cmd_a;     // 3 cycles before data
94
    reg                   [3:0] cmd_a_r;   // 2 cycles before data
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
    wire                        cmd_we;    // 3 cycles befor data
    reg                   [2:0] cmd_we_r;  // cmd_we_r[2] - with cmd_data
    wire                 [31:0] cmd_data;
    
    reg                   [3:0] wpage_asap;     // FIFO page were ASAP writes go
    reg                   [3:0] wpage_prev;     // unused page, currently being cleared
    reg                   [3:0] wpage_next;     // next page to be used
    reg                   [3:0] wpage_w;        // FIFO page where current writes go 
    reg                   [1:0] wpage_inc;      // increment wpage_asap (after frame sync or during reset), and [1] next clock cycle after [0]
    
    wire                        reset_cmd;
    wire                        run_cmd;
    reg                         reset_on;       // reset FIFO in progress
    reg                         seq_enrun=0;      // enable seq
    reg                         we_fifo_wp;     // enable writing to fifo write pointer memory
    reg                         next_frame_rq;  // request to switch to the new frame page, clear pointer for the one just left
    wire                        pre_wpage_inc;
Andrey Filippov's avatar
Andrey Filippov committed
112
    reg         [PNTR_WIDH-1:0] fifo_wr_pointers_ram [0:15];
113 114
    wire        [PNTR_WIDH-1:0] fifo_wr_pointers_outw=fifo_wr_pointers_ram[wpage_w];
    wire        [PNTR_WIDH-1:0] fifo_wr_pointers_outr=fifo_wr_pointers_ram[page_r];
115 116 117
    
    reg         [PNTR_WIDH-1:0] fifo_wr_pointers_outw_r;
    reg         [PNTR_WIDH-1:0] fifo_wr_pointers_outr_r;
118
//    reg                         d_na;  // register counting address(0) or data(1) when writing sequences
119 120 121 122 123 124
    reg  [AXI_WR_ADDR_BITS-1:0] address_hold; // register to hold command address to write to the sequencer simultaneously with data
    wire                 [63:0] cmdseq_di = {{32 - AXI_WR_ADDR_BITS{1'b0}},address_hold,cmd_data};      // data to write to the command sequencer
    reg                   [2:0] por=0;                //power on reset
    reg                         initialized;        // command fifo initialized
    
    wire                        cmd_we_ctl_w = cmd_we && (cmd_a ==       CMDFRAMESEQ_CTRL); // 3 cycles before data
125
    reg                   [2:0] cmd_we_ctl_r;   // cmd_we_ctl_r[2] - with data   
126
    wire                        cmd_we_abs_w = cmd_we && ((cmd_a & 'h10) == CMDFRAMESEQ_ABS);  // 3 cycles before data
127
    reg                         cmd_we_abs_r;   // 2 cycles before data  
128
    wire                        cmd_we_rel_w = cmd_we && ((cmd_a & 'h10) == CMDFRAMESEQ_REL) && (cmd_a != CMDFRAMESEQ_CTRL);  // 3 cycles before data   
129 130 131 132 133 134
    reg                         cmd_we_rel_r;   // 2 cycles before data  
//    reg                         cmd_we_any_r;   // any of the abs or rel (valid 2 cycles before data)
    reg                   [2:0] data_cycle_r;      // [2] write to command memory (only with data)  
    reg                         pend_abs;       // got address in absolute mode, waiting to write data
    reg                         pend_rel;       // got address in relative mode, waiting to write data
    
135 136 137 138 139 140 141 142 143
    wire                        reset_seq_done;
    
    reg         [PNTR_WIDH+3:0] seq_cmd_wa;     // width of in-page pointer plus 4 (number of pages)
    wire        [PNTR_WIDH+3:0] seq_cmd_ra;     // width of in-page pointer plus 4 (number of pages)
    
    reg                   [3:0] page_r;         // FIFO page from where commands are generated
    reg                   [1:0] page_r_inc;     // increment page_r - signal and delayed version
    reg         [PNTR_WIDH-1:0] rpointer;       // FIFO read pointer for current page
    reg                   [1:0] read_busy;      // reading and sending command  
144 145 146
    wire                        conf_send_w;    // valid && ackn
    reg                         conf_send_r;    // valid && ackn
    
147 148 149 150 151 152
    wire                        commands_pending; // wants to send some commands
    reg                   [1:0] ren;             // 1-hot ren to BRAM, then regen to BRAM
    wire                        pre_cmd_seq_w;  // 1 cycle before starting command read/send sequence
    reg                         valid_r;

    wire                 [63:0] cmdseq_do; // output data from the sequence
153 154 155 156 157
    
    wire                  [1:0] irq_bits = cmd_data[CMDFRAMESEQ_IRQ_BIT +: 2];
    reg                         is_r;      // interrupt status (not masked)
    reg                         im_r;       // interrtupt mask
    wire                        irq_ctrl;
158 159
    wire                        we_seq_data;
    
160
    assign conf_send_w = valid && ackn;
161
    assign we_seq_data = data_cycle_r[2];
162 163 164 165 166
    
    assign is =  is_r;      // interrupt status (not masked)
    assign im =  im_r;       // interrtupt mask
    assign irq_ctrl = cmd_we_ctl_r[2] && (|irq_bits);
    
167 168 169 170 171 172 173 174 175 176 177 178 179 180
    assign waddr = cmdseq_do[32 +:AXI_WR_ADDR_BITS];
    assign wdata = cmdseq_do[31:0];
    assign seq_cmd_ra = {page_r,rpointer};
    
    
    assign frame_no = wpage_asap;
    
    assign reset_cmd = (!reset_on && cmd_we_ctl_r[2] && cmd_data[CMDFRAMESEQ_RST_BIT]) || (por[1] && !por[2]);
    assign run_cmd =   (!reset_on && cmd_we_ctl_r[2] && cmd_data[CMDFRAMESEQ_RUN_BIT]);
//    assign reset_seq_done = reset_on && wpage_inc[0] && (wpage_asap == 4'hf);
    assign reset_seq_done = reset_on && wpage_inc[0] && (&wpage_asap[3:1]); // ends after 'he 
    
//    assign pre_wpage_inc = (!cmd_we && !(|cmd_we_r) ) && (!wpage_inc[0] && !wpage_inc[1]) && ((next_frame_rq && initialized) || reset_on) ; 
    // During reset_on write pointer every cycle:
181 182
//    assign pre_wpage_inc = (!cmd_we && !(|cmd_we_r) ) && ((next_frame_rq && initialized) || reset_on) ;
    assign pre_wpage_inc = (!cmd_we && !(|cmd_we_r) ) && ((next_frame_rq && !wpage_inc[0] && initialized) || reset_on) ;
183
    assign commands_pending = rpointer != fifo_wr_pointers_outr_r; // only look at the current page different pages will trigger page increment first
184
//    assign pre_cmd_seq_w = commands_pending & ~(|page_r_inc) & seq_enrun;
185 186
//    assign pre_cmd_seq_w = commands_pending & ~(|page_r_inc) & seq_enrun && !ren[0]; // counter lags
    assign pre_cmd_seq_w = commands_pending & ~(|page_r_inc) & seq_enrun && !read_busy[0]; // counter lags
187
//    
188
    assign valid = valid_r;
189 190 191 192 193 194 195 196 197 198 199 200
    
//    parameter CMDFRAMESEQ_IRQ_BIT =             0,
//    parameter CMDFRAMESEQ_IRQ_BITS =            2
    always @ (posedge mclk) begin
        if      (mrst)                            is_r <= 0;
        else if (frame_sync)                      is_r <= 1;
        else if (irq_ctrl && (irq_bits == 2'b01)) is_r <= 0;
        
        if      (mrst)                            im_r <= 0;
        else if (irq_ctrl && irq_bits[1])         im_r <= irq_bits[0];
    end    
    
Andrey Filippov's avatar
Andrey Filippov committed
201 202 203
    always @ (posedge mclk) begin
        if (mrst) por <= 0;
        else      por <= {por[1:0], 1'b1};
204
        
Andrey Filippov's avatar
Andrey Filippov committed
205
        if      (mrst)      seq_enrun <= 0;
206 207 208
        else if (reset_cmd) seq_enrun <= 0;
        else if (run_cmd)   seq_enrun <=  cmd_data[CMDFRAMESEQ_RUN_BIT-1];
    
Andrey Filippov's avatar
Andrey Filippov committed
209
        if      (mrst)           initialized <= 0;
210 211
        else if (reset_seq_done) initialized <= 1;
        
212 213 214 215 216
//        if      (mrst)         d_na <= 0;
//        else if (cmd_we_ctl_w) d_na <= 0;
//        else if (cmd_we)       d_na <= ~ d_na;
//        else if (cmd_we_r[1])  d_na <= ~ d_na; // same cycle it is used
        
217
        
Andrey Filippov's avatar
Andrey Filippov committed
218
        if      (mrst)   valid_r <= 0;
219 220 221 222 223 224
        else if (ren[1]) valid_r <= 1;
        else if (ackn)   valid_r <= 0;
    
    end
   
    always @ (posedge mclk) begin
225
        cmd_a_r <=      cmd_a[3:0];
226 227
        cmd_we_ctl_r <= {cmd_we_ctl_r[1:0],cmd_we_ctl_w};
        cmd_we_r <=     {cmd_we_r[1:0], cmd_we};
228 229 230 231 232 233 234 235 236 237 238 239 240
        cmd_we_abs_r <= cmd_we_abs_w & ~(pend_abs | pend_rel); // only first (address) of the 2
        cmd_we_rel_r <= cmd_we_rel_w & ~(pend_abs | pend_rel); // only first (address) of the 2
//        cmd_we_any_r <= cmd_we_abs_w | cmd_we_rel_w;
        
//        if (reset_cmd || !por[1] || cmd_we_ctl_w || we_seq_data) pend_abs <= 0;
        if (reset_cmd || !por[1] || cmd_we_ctl_w || data_cycle_r[0]) pend_abs <= 0;
        else if (cmd_we_abs_w)                                       pend_abs <= 1;

//        if (reset_cmd || !por[1] || cmd_we_ctl_w || we_seq_data) pend_rel <= 0;
        if (reset_cmd || !por[1] || cmd_we_ctl_w || data_cycle_r[0]) pend_rel <= 0;
        else if (cmd_we_rel_w)                                       pend_rel <= 1;
        
        
241
// signals related to writing to seq FIFO
242 243 244
//        if (cmd_we_r[1] && !d_na) address_hold <= cmd_data[AXI_WR_ADDR_BITS-1:0];
//        if (cmd_we_r[1] && (pend_abs || pend_rel)) address_hold <= cmd_data[AXI_WR_ADDR_BITS-1:0];
        if (cmd_we_r[2] && (pend_abs || pend_rel)) address_hold <= cmd_data[AXI_WR_ADDR_BITS-1:0];
245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267
// decoded commands        
// write pointer memory
        wpage_inc <= (&por[1:0]) ? {wpage_inc[0],pre_wpage_inc} : 2'b0;

        if (reset_cmd || !por[1]) wpage_next <= 1;
        else if (wpage_inc[0])    wpage_next <= wpage_next + 1; //

        if (reset_cmd || !por[1]) wpage_asap <= 0;
        else if (wpage_inc[0])    wpage_asap <= wpage_next; // valid at cmd_we_*_r
        
        if (reset_cmd || !por[1]) wpage_prev <= 4'hf;
        else if (wpage_inc[0])    wpage_prev <= wpage_asap; // valid at cmd_we_*_r
        
        if      (!por[1])         reset_on <= 0;
        else if (reset_cmd)       reset_on <= 1;
        else if (reset_seq_done)  reset_on <= 0;
        
        if      (!por[1])         next_frame_rq <= 0;
        else if (frame_sync)      next_frame_rq <= 1;
        else if (wpage_inc[0])    next_frame_rq <= 0;
        

// now cmd_we_abs_r or cmd_we_rel_r can not happen with wpage_inc[0] - earliest at the next cycle
268 269 270 271 272
// BUG: cmd_a[3:0] was valid cycle before
//        if      (cmd_we_abs_r)    wpage_w <= (cmd_a[3:0] == wpage_prev)? wpage_asap : cmd_a[3:0];
//        else if (cmd_we_rel_r)    wpage_w <= wpage_asap + cmd_a[3:0];
        if      (cmd_we_abs_r)    wpage_w <= (cmd_a_r[3:0] == wpage_prev)? wpage_asap : cmd_a_r[3:0];
        else if (cmd_we_rel_r)    wpage_w <= wpage_asap + cmd_a_r[3:0];
273
        else if (wpage_inc[0])    wpage_w <= wpage_asap; // will now be previous (switched at the same cycle)
274 275 276 277 278 279 280 281 282 283
//BUG: Only should be active each other cycle (with data)
//        we_fifo_wp <= cmd_we_any_r[1] || wpage_inc[0];
        we_fifo_wp <= data_cycle_r[1] || wpage_inc[0];
//        data_cycle_r <=  {data_cycle_r[1:0],  cmd_we_any_r &  d_na};
//        data_cycle_r <=  {data_cycle_r[1:0],  (cmd_we_abs_w | cmd_we_rel_w) &  d_na};
//        data_cycle_r <=  {data_cycle_r[1:0],  cmd_we_abs_w &  (pend_abs | pend_rel)}; // any write command is considered second (data)
        data_cycle_r <=  {data_cycle_r[1:0],  (cmd_we_abs_w | cmd_we_rel_w) &  (pend_abs | pend_rel)}; // 
        
//        if (cmd_we_any_r[1])  fifo_wr_pointers_outw_r <= fifo_wr_pointers_outw; // register pointer RAM output (write port)
        if (data_cycle_r[1])     fifo_wr_pointers_outw_r <= fifo_wr_pointers_outw; // register pointer RAM output (write port)
284 285
        
        // write to pointer RAM (to the same address as just read from if read)
286
        if (we_fifo_wp) fifo_wr_pointers_ram[wpage_w] <= wpage_inc[1] ? {PNTR_WIDH{1'b0}}:(fifo_wr_pointers_outw_r + 1); 
287 288
//        if (cmd_we_any_r[1]) seq_cmd_wa <= {wpage_w, fifo_wr_pointers_outw};
        if (data_cycle_r[1])  seq_cmd_wa <= {wpage_w, fifo_wr_pointers_outw};
289 290 291
        
        fifo_wr_pointers_outr_r <= fifo_wr_pointers_outr; // just register write pointer for the read page 
        page_r_inc <= {page_r_inc[0],
292 293
//                      (~read_busy[0] | conf_send_r) & // not busy or will not be busy next cycle (when page_r_inc active)
                      (~read_busy[0] | conf_send_w) & // not busy or will not be busy next cycle (when page_r_inc active)
294 295 296 297 298 299 300 301 302 303 304
                      ~(|page_r_inc) & // read_page was not just incremented, so updated read pointer had a chance to propagate
                       (rpointer == fifo_wr_pointers_outr_r) & // nothing left in the frame FIFO pointed  page_r
                       (page_r != wpage_asap)};  // the page commands are taken from is not the ASAP (current) page
                      
        if      (!por[1] || reset_on) page_r <= 0;
        else if (page_r_inc[0])       page_r <= page_r+1;

//        if      (reset_on || reset_cmd || page_r_inc[0]) rpointer <= 0; // TODO: move to rst ?
        if      (!por[1] || reset_on || page_r_inc[0]) rpointer <= 0; // TODO: move to rst ?
        else if (ren[0])                               rpointer <= rpointer + 1;
        
305
        conf_send_r <= conf_send_w; // valid && ackn;
306 307 308 309

//        if (reset_on || reset_cmd) read_busy <= 0;
        if (!por[1] || reset_on) read_busy <= 0;
        else                     read_busy <= {read_busy[0],
310 311
//                                               read_busy[0]? (~conf_send_r) : pre_cmd_seq_w};
                                               read_busy[0]? (~conf_send_w) : pre_cmd_seq_w};
312 313 314 315 316 317 318 319 320 321 322 323 324
        ren <= {ren[0], pre_cmd_seq_w};
// TODO: check generation of the reset sequence

    end

    cmd_deser #(
        .ADDR       (CMDFRAMESEQ_ADDR),
        .ADDR_MASK  (CMDFRAMESEQ_MASK),
        .NUM_CYCLES (6),
        .ADDR_WIDTH (5),
        .DATA_WIDTH (32),
        .WE_EARLY   (3) // generate cmd_we and cmd_a three cycles before cmd_data is valid
    ) cmd_deser_32bit_i (
Andrey Filippov's avatar
Andrey Filippov committed
325
        .rst        (1'b0), // rst),      // input
326
        .clk        (mclk),     // input
Andrey Filippov's avatar
Andrey Filippov committed
327
        .srst       (mrst),      // input
328 329 330 331 332 333 334 335 336 337 338
        .ad         (cmd_ad),   // input[7:0] 
        .stb        (cmd_stb),  // input
        .addr       (cmd_a),    // output[3:0] 
        .data       (cmd_data), // output[31:0] 
        .we         (cmd_we)    // output
    );

// Generate one  x64 BRAM, 3 of x32 or 3 x64, depending on the sequnecer depth (CMDFRAMESEQ_DEPTH): 32/64/128 commands per frame
    generate
        if (CMDFRAMESEQ_DEPTH == 32) begin
            ram_var_w_var_r #(
339
                .COMMENT("cmd_frame_sequencer_CMDFRAMESEQ_DEPTH_32"),
340 341 342 343 344 345 346 347 348 349 350 351 352 353 354
                .REGISTERS(1),
                .LOG2WIDTH_WR(6),
                .LOG2WIDTH_RD(6),
                .DUMMY(0)
            ) ram_var_w_var_r_i (
                .rclk          (mclk),                   // input
//              .raddr         (seq_cmd_ra),             // input[8:0] 
                .raddr         ({seq_cmd_ra[PNTR_WIDH+3 -:4],seq_cmd_ra[4:0]}), // input[8:0] 
                .ren           (ren[0]),                 // input
                .regen         (ren[1]),                 // input
                .data_out      (cmdseq_do),              // output[63:0] 
                .wclk          (mclk),                   // input
                // VDT TODO: make conditions in generate skip parsing if condition does not match
//              .waddr         (seq_cmd_wa),             // input[8:0] 
                .waddr         ({seq_cmd_wa[PNTR_WIDH+3 -:4],seq_cmd_wa[4:0]}), // input[8:0] // just to make VDT happy
355
                .we            (we_seq_data),        // input
356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375
                .web           (8'hff),                  // input[7:0] 
                .data_in       (cmdseq_di)               // input[63:0] 
            );
        
        end
        else if (CMDFRAMESEQ_DEPTH == 64) begin
            ram18_var_w_var_r #(
                .REGISTERS(1),
                .LOG2WIDTH_WR(4),
                .LOG2WIDTH_RD(4),
                .DUMMY(0)
            ) ram18_var_w_var_r_dl_i (
                .rclk          (mclk), // input
//              .raddr         (seq_cmd_ra),             // input[9:0] 
                .raddr         ({seq_cmd_ra[PNTR_WIDH+3 -:4],seq_cmd_ra[5:0]}), // input[9:0] 
                .ren           (ren[0]),                 // input
                .regen         (ren[1]),                 // input
                .data_out      (cmdseq_do[15:0]),        // output[15:0] 
                .wclk          (mclk),                   // input
//              .waddr         (seq_cmd_wa),             // input[9:0] 
376 377 378
//                .waddr         ({seq_cmd_ra[PNTR_WIDH+3 -:4],seq_cmd_ra[5:0]}), // input[9:0] 
                .waddr         ({seq_cmd_wa[PNTR_WIDH+3 -:4],seq_cmd_wa[5:0]}), // input[9:0] 
                .we            (we_seq_data),        // input
379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396
                .web           (4'hf),                   // input[3:0] 
                .data_in       (cmdseq_di[15:0])         // input[15:0] 
            );
 
            ram18_var_w_var_r #(
                .REGISTERS(1),
                .LOG2WIDTH_WR(4),
                .LOG2WIDTH_RD(4),
                .DUMMY(0)
            ) ram18_var_w_var_r_dh_i (
                .rclk          (mclk), // input
//              .raddr         (seq_cmd_ra),             // input[9:0] 
                .raddr         ({seq_cmd_ra[PNTR_WIDH+3 -:4],seq_cmd_ra[5:0]}), // input[9:0] 
                .ren           (ren[0]),                 // input
                .regen         (ren[1]),                 // input
                .data_out      (cmdseq_do[31:16]),       // output[15:0] 
                .wclk          (mclk),                   // input
//              .waddr         (seq_cmd_wa),             // input[9:0] 
397 398 399
//                .waddr         ({seq_cmd_ra[PNTR_WIDH+3 -:4],seq_cmd_ra[5:0]}), // input[9:0] 
                .waddr         ({seq_cmd_wa[PNTR_WIDH+3 -:4],seq_cmd_wa[5:0]}), // input[9:0] 
                .we            (we_seq_data),        // input
400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417
                .web           (4'hf),                   // input[3:0] 
                .data_in       (cmdseq_di[31:16])        // input[15:0] 
            );

            ram18_var_w_var_r #(
                .REGISTERS(1),
                .LOG2WIDTH_WR(4),
                .LOG2WIDTH_RD(4),
                .DUMMY(0)
            ) ram18_var_w_var_r_ad_i (
                .rclk          (mclk), // input
//              .raddr         (seq_cmd_ra),             // input[9:0] 
                .raddr         ({seq_cmd_ra[PNTR_WIDH+3 -:4],seq_cmd_ra[5:0]}), // input[9:0] 
                .ren           (ren[0]),                 // input
                .regen         (ren[1]),                 // input
                .data_out      (cmdseq_do[47:32]),       // output[15:0] 
                .wclk          (mclk),                   // input
//              .waddr         (seq_cmd_wa),             // input[9:0] 
418 419 420
//                .waddr         ({seq_cmd_ra[PNTR_WIDH+3 -:4],seq_cmd_ra[5:0]}), // input[9:0] 
                .waddr         ({seq_cmd_wa[PNTR_WIDH+3 -:4],seq_cmd_wa[5:0]}), // input[9:0] 
                .we            (we_seq_data),        // input
421 422 423 424 425 426 427 428
                .web           (4'hf),                   // input[3:0] 
                .data_in       (cmdseq_di[47:32])        // input[15:0] 
            );
        
        end
        
        else if (CMDFRAMESEQ_DEPTH == 128)  begin
            ram_var_w_var_r #(
429
                .COMMENT("cmd_frame_sequencer_CMDFRAMESEQ_DEPTH_128A"),
430 431 432 433 434 435 436 437 438 439 440 441 442
                .REGISTERS(1),
                .LOG2WIDTH_WR(4),
                .LOG2WIDTH_RD(4),
                .DUMMY(0)
            ) ram_var_w_var_r_dl_i (
                .rclk          (mclk), // input
//              .raddr         (seq_cmd_ra),             // input[10:0] 
                .raddr         ({seq_cmd_ra[PNTR_WIDH+3 -:4],seq_cmd_ra[6:0]}), // input[10:0] 
                .ren           (ren[0]),                 // input
                .regen         (ren[1]),                 // input
                .data_out      (cmdseq_do[15:0]),        // output[15:0] 
                .wclk          (mclk),                   // input
//              .waddr         (seq_cmd_wa),             // input[9:0] 
443 444 445
//                .waddr         ({seq_cmd_ra[PNTR_WIDH+3 -:4],seq_cmd_ra[6:0]}), // input[10:0] 
                .waddr         ({seq_cmd_wa[PNTR_WIDH+3 -:4],seq_cmd_wa[6:0]}), // input[10:0] 
                .we            (we_seq_data),        // input
446 447 448 449 450
                .web           (8'hff),                  // input[7:0] 
                .data_in       (cmdseq_di[15:0])         // input[15:0] 
            );
        
            ram_var_w_var_r #(
451
                .COMMENT("cmd_frame_sequencer_CMDFRAMESEQ_DEPTH_128B"),
452 453 454 455 456 457 458 459 460 461 462 463 464 465
                .REGISTERS(1),
                .LOG2WIDTH_WR(4),
                .LOG2WIDTH_RD(4),
                .DUMMY(0)
            ) ram_var_w_var_r_dh_i (
                .rclk          (mclk), // input
//              .raddr         (seq_cmd_ra),             // input[10:0] 
                .raddr         ({seq_cmd_ra[PNTR_WIDH+3 -:4],seq_cmd_ra[6:0]}), // input[10:0] 
                .ren           (ren[0]),                 // input
                .regen         (ren[1]),                 // input
                .data_out      (cmdseq_do[31:16]),       // output[15:0] 
                .wclk          (mclk),                   // input
//              .waddr         (seq_cmd_wa),             // input[9:0] 
                .waddr         ({seq_cmd_ra[PNTR_WIDH+3 -:4],seq_cmd_ra[6:0]}), // input[10:0] 
466
                .we            (we_seq_data),        // input
467 468 469 470 471
                .web           (8'hff),                  // input[7:0] 
                .data_in       (cmdseq_di[31:16])        // input[15:0] 
            );
        
            ram_var_w_var_r #(
472
                .COMMENT("cmd_frame_sequencer_CMDFRAMESEQ_DEPTH_128C"),
473 474 475 476 477 478 479 480 481 482 483 484 485 486
                .REGISTERS(1),
                .LOG2WIDTH_WR(4),
                .LOG2WIDTH_RD(4),
                .DUMMY(0)
            ) ram_var_w_var_r_ad_i (
                .rclk          (mclk), // input
//              .raddr         (seq_cmd_ra),             // input[10:0] 
                .raddr         ({seq_cmd_ra[PNTR_WIDH+3 -:4],seq_cmd_ra[6:0]}), // input[10:0] 
                .ren           (ren[0]),                 // input
                .regen         (ren[1]),                 // input
                .data_out      (cmdseq_do[47:32]),       // output[15:0] 
                .wclk          (mclk),                   // input
//              .waddr         (seq_cmd_wa),             // input[9:0] 
                .waddr         ({seq_cmd_ra[PNTR_WIDH+3 -:4],seq_cmd_ra[6:0]}), // input[10:0] 
487
                .we            (we_seq_data),        // input
488 489 490 491 492 493 494 495 496 497 498 499
                .web           (8'hff),                  // input[7:0] 
                .data_in       (cmdseq_di[47:32])        // input[15:0] 
            );
        
        end
        else begin
            // cause some error - invalid CMDFRAMESEQ_DEPTH
        end
    endgenerate

endmodule