cmd_encod_linear_rd.v 15.8 KB
Newer Older
1 2 3 4
/*******************************************************************************
 * Module: cmd_encod_linear_rd
 * Date:2015-01-23  
 * Author: andrey     
Andrey Filippov's avatar
Andrey Filippov committed
5
 * Description: Command sequencer generator for reading a sequential up to 1KB page
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
 * single page access, bank and row will not be changed
 *
 * Copyright (c) 2015 <set up in Preferences-Verilog/VHDL Editor-Templates> .
 * cmd_encod_linear_rd.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_encod_linear_rd.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/> .
 *******************************************************************************/
`timescale 1ns/1ps
23

24 25
module  cmd_encod_linear_rd #(
//    parameter BASEADDR = 0,
Andrey Filippov's avatar
Andrey Filippov committed
26 27
    parameter ADDRESS_NUMBER=       15,
    parameter COLADDR_NUMBER=       10,
28
    parameter NUM_XFER_BITS=         6,    // number of bits to specify transfer length
29 30 31 32 33 34 35 36 37 38
    parameter CMD_PAUSE_BITS=       10,
    parameter CMD_DONE_BIT=         10 // VDT BUG: CMD_DONE_BIT is used in a function call parameter!
) (
    input                        rst,
    input                        clk,
// 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
    input                  [2:0] bank_in,     // bank address
    input   [ADDRESS_NUMBER-1:0] row_in,      // memory row
Andrey Filippov's avatar
Andrey Filippov committed
39
    input   [COLADDR_NUMBER-4:0] start_col,   // start memory column in 8-bursts
40
    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)
41
    input                        skip_next_page_in, // do not reset external buffer (continue)    
42
    input                        start,       // start generating commands
43
    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.
44 45 46
    output reg                   enc_wr,      // write encoded command
    output reg                   enc_done     // encoding finished
);
47
    localparam ROM_WIDTH=10;
48 49
    localparam ROM_DEPTH=4;
    
50
//    localparam ENC_BUF_PGNEXT=    0;
51 52 53 54 55 56 57
    localparam ENC_NOP=        0;
    localparam ENC_BUF_WR=     1;
    localparam ENC_DCI=        2;
    localparam ENC_SEL=        3;
    localparam ENC_CMD_SHIFT=  4; // [5:4] - command: 0 -= NOP, 1 - READ, 2 - PRECHARGE, 3 - ACTIVATE
    localparam ENC_PAUSE_SHIFT=6; // [7:6] - 2- bit pause (for NOP commandes)
    localparam ENC_PRE_DONE=   8;
58
    localparam ENC_BUF_PGNEXT=    9;
59 60 61 62 63 64 65 66
    
    localparam ENC_CMD_NOP=      0; // 2-bit locally encoded commands
    localparam ENC_CMD_READ=     1;
    localparam ENC_CMD_PRECHARGE=2;
    localparam ENC_CMD_ACTIVATE= 3;
    localparam REPEAT_ADDR=3;
    
    localparam CMD_NOP=      0; // 3-bit normal memory RCW commands (positive logic)
67
    localparam CMD_READ=     2;
68 69 70 71
    localparam CMD_PRECHARGE=5;
    localparam CMD_ACTIVATE= 4;
    
    reg   [ADDRESS_NUMBER-1:0] row;     // memory row
Andrey Filippov's avatar
Andrey Filippov committed
72
    reg   [COLADDR_NUMBER-4:0] col;     // start memory column (3 LSBs should be 0?) // VDT BUG: col is used as a function call parameter!
73
    reg                  [2:0] bank;    // memory bank;
74
    reg    [NUM_XFER_BITS-1:0] num128;  // number of 128-bit words to transfer
75
    reg                        skip_next_page;
76
    reg                        gen_run;
77
//    reg                        gen_run_d;
78 79
    reg        [ROM_DEPTH-1:0] gen_addr; // will overrun as stop comes from ROM
    
80
    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.
81 82 83 84
    wire                       pre_done;
    wire                 [1:0] rom_cmd;
    wire                 [1:0] rom_skip;
    wire                 [2:0] full_cmd;
85
//    reg                        done;
86 87 88 89 90 91 92 93 94 95 96

    assign     pre_done=rom_r[ENC_PRE_DONE] && gen_run;
    assign     rom_cmd=  rom_r[ENC_CMD_SHIFT+:2];
    assign     rom_skip= rom_r[ENC_PAUSE_SHIFT+:2];
    assign     full_cmd= rom_cmd[1]?(rom_cmd[0]?CMD_ACTIVATE:CMD_PRECHARGE):(rom_cmd[0]?CMD_READ:CMD_NOP);
    
    always @ (posedge rst or posedge clk) begin
        if (rst)           gen_run <= 0;
        else if (start)    gen_run<= 1;
        else if (pre_done) gen_run<= 0;
        
97 98
//        if (rst)           gen_run_d <= 0;
//        else               gen_run_d <= gen_run;
99 100 101

        if (rst)                     gen_addr <= 0;
        else if (!start && !gen_run) gen_addr <= 0;
102 103
        else if ((gen_addr==(REPEAT_ADDR-1)) && (num128[NUM_XFER_BITS-1:1]==0)) gen_addr <= REPEAT_ADDR+1; // skip loop alltogeter
        else if ((gen_addr !=REPEAT_ADDR) || (num128[NUM_XFER_BITS-1:1]==0)) gen_addr <= gen_addr+1; // not in a loop
Andrey Filippov's avatar
Andrey Filippov committed
104 105 106 107
//counting loops?        
        if      (rst)          num128 <= 0;
        else if (start)        num128 <= num128_in;
        else if (!gen_run)     num128 <= 0; //
108 109 110 111 112
        else if ((gen_addr == (REPEAT_ADDR-1)) || (gen_addr == REPEAT_ADDR))  num128 <= num128 -1;
    end
    
    always @ (posedge clk) if (start) begin
        row<=row_in;
Andrey Filippov's avatar
Andrey Filippov committed
113
//        col <= start_col;
114
        bank <= bank_in;
115
        skip_next_page <= skip_next_page_in;
Andrey Filippov's avatar
Andrey Filippov committed
116 117 118 119
    end
    always @ (posedge clk) begin
        if (start) col <= start_col;
        else if (rom_cmd==ENC_CMD_READ) col <= col+1;
120 121 122 123 124 125 126 127
    end
    
    // ROM-based (registered output) encoded sequence
    always @ (posedge rst or posedge clk) begin
        if (rst)           rom_r <= 0;
        else case (gen_addr)
            4'h0: rom_r <= (ENC_CMD_ACTIVATE <<  ENC_CMD_SHIFT); 
            4'h1: rom_r <= (ENC_CMD_NOP <<       ENC_CMD_SHIFT) | (1 << ENC_PAUSE_SHIFT); 
128
            4'h2: rom_r <= (ENC_CMD_READ <<      ENC_CMD_SHIFT) | (1 << ENC_NOP)         | (1 << ENC_BUF_WR) | (1 << ENC_DCI) | (1 << ENC_SEL); 
129
            4'h3: rom_r <= (ENC_CMD_READ <<      ENC_CMD_SHIFT) | (1 << ENC_NOP)         | (1 << ENC_BUF_WR) | (1 << ENC_DCI) | (1 << ENC_SEL);
130
            4'h4: rom_r <= (ENC_CMD_NOP <<       ENC_CMD_SHIFT) | (1 << ENC_PAUSE_SHIFT)                     | (1 << ENC_DCI) | (1 << ENC_SEL);
131
            4'h5: rom_r <= (ENC_CMD_NOP <<       ENC_CMD_SHIFT) | (1 << ENC_BUF_PGNEXT)                      | (1 << ENC_DCI) | (1 << ENC_SEL);
132 133 134 135 136 137 138
            4'h6: rom_r <= (ENC_CMD_PRECHARGE << ENC_CMD_SHIFT)                                              | (1 << ENC_DCI);
            4'h7: rom_r <= (ENC_CMD_NOP <<       ENC_CMD_SHIFT) | (2 << ENC_PAUSE_SHIFT)                     | (1 << ENC_DCI);
            4'h8: rom_r <= (ENC_CMD_NOP <<       ENC_CMD_SHIFT) | (1 << ENC_PRE_DONE);
            default:rom_r <= 0;
       endcase
    end
    always @ (posedge rst or posedge clk) begin
139 140
//        if (rst)           done <= 0;
//        else               done <= pre_done;
141 142
        
        if (rst)           enc_wr <= 0;
143
        else               enc_wr <= gen_run; //  || gen_run_d;
144 145
        
        if (rst)           enc_done <= 0;
146
        else               enc_done <= enc_wr && !gen_run; // !gen_run_d;
147 148
        
        if (rst)             enc_cmd <= 0;
149 150
        else if (gen_run) begin
          if (rom_cmd==0) enc_cmd <= func_encode_skip ( // encode pause
151
            {{CMD_PAUSE_BITS-2{1'b0}},rom_skip[1:0]}, // skip;   // number of extra cycles to skip (and keep all the other outputs)
152
            pre_done, // done,                                     // end of sequence 
153 154 155 156 157 158 159 160 161
            bank[2:0],                                // bank (here OK to be any)
            1'b0,                    //   odt_en;     // enable ODT
            1'b0,                    //   cke;        // disable CKE
            rom_r[ENC_SEL],          //   sel;        // first/second half-cycle, other will be nop (cke+odt applicable to both)
            1'b0,                    //   dq_en;      // enable (not tristate) DQ  lines (internal timing sequencer for 0->1 and 1->0)
            1'b0,                    //   dqs_en;     // enable (not tristate) DQS lines (internal timing sequencer for 0->1 and 1->0)
            1'b0,                    //   dqs_toggle; // enable toggle DQS according to the pattern
            rom_r[ENC_DCI],          //   dci;        // DCI disable, both DQ and DQS lines (internal logic and timing sequencer for 0->1 and 1->0)
            rom_r[ENC_BUF_WR],       //   buf_wr;     // connect to external buffer (but only if not paused)
162
            1'b0,                    //   buf_rd;     // connect to external buffer (but only if not paused)
163
            rom_r[ENC_BUF_PGNEXT] && !skip_next_page);     //   buf_rst;    // connect to external buffer (but only if not paused)
164
          else  enc_cmd <= func_encode_cmd ( // encode non-NOP command
165 166
            rom_cmd[1]?
                    row:
Andrey Filippov's avatar
Andrey Filippov committed
167
                    {{ADDRESS_NUMBER-COLADDR_NUMBER{1'b0}},col[COLADDR_NUMBER-4:0],3'b0}, //  [14:0] addr;       // 15-bit row/column adderss
168 169 170 171 172 173 174 175 176 177 178
            bank[2:0],                                // bank (here OK to be any)
            full_cmd[2:0],           //   rcw;        // RAS/CAS/WE, positive logic
            1'b0,                    //   odt_en;     // enable ODT
            1'b0,                    //   cke;        // disable CKE
            rom_r[ENC_SEL],          //   sel;        // first/second half-cycle, other will be nop (cke+odt applicable to both)
            1'b0,                    //   dq_en;      // enable (not tristate) DQ  lines (internal timing sequencer for 0->1 and 1->0)
            1'b0,                    //   dqs_en;     // enable (not tristate) DQS lines (internal timing sequencer for 0->1 and 1->0)
            1'b0,                    //   dqs_toggle; // enable toggle DQS according to the pattern
            rom_r[ENC_DCI],          //   dci;        // DCI disable, both DQ and DQS lines (internal logic and timing sequencer for 0->1 and 1->0)
            rom_r[ENC_BUF_WR],       //   buf_wr;     // connect to external buffer (but only if not paused)
            1'b0,                    //   buf_rd;     // connect to external buffer (but only if not paused)     
179
            rom_r[ENC_NOP],          //   nop;        // add NOP after the current command, keep other data
180
            rom_r[ENC_BUF_PGNEXT] && !skip_next_page);  //   buf_rst;    // connect to external buffer (but only if not paused)
181
        end
182 183 184
    end    
    
// move to include?
185 186
`include "includes/x393_mcontr_encode_cmd.vh" 
/*
187 188 189 190 191 192 193 194 195 196 197 198 199
    function [31:0] func_encode_skip;
        input [CMD_PAUSE_BITS-1:0] skip;       // number of extra cycles to skip (and keep all the other outputs)
        input                      done;       // end of sequence 
        input [2:0]                bank;       // bank (here OK to be any)
        input                      odt_en;     // enable ODT
        input                      cke;        // disable CKE
        input                      sel;        // first/second half-cycle, other will be nop (cke+odt applicable to both)
        input                      dq_en;      // enable (not tristate) DQ  lines (internal timing sequencer for 0->1 and 1->0)
        input                      dqs_en;     // enable (not tristate) DQS lines (internal timing sequencer for 0->1 and 1->0)
        input                      dqs_toggle; // enable toggle DQS according to the pattern
        input                      dci;        // DCI disable, both DQ and DQS lines (internal logic and timing sequencer for 0->1 and 1->0)
        input                      buf_wr;     // connect to external buffer (but only if not paused)
        input                      buf_rd;     // connect to external buffer (but only if not paused)
200
        input                      buf_rst;    // connect to external buffer (but only if not paused)
201 202 203 204 205 206 207 208 209 210 211 212 213 214
        begin
            func_encode_skip= func_encode_cmd (
                {{14-CMD_DONE_BIT{1'b0}}, done, skip[CMD_PAUSE_BITS-1:0]},       // 15-bit row/column adderss
                bank[2:0],  // bank (here OK to be any)
                3'b0,       // RAS/CAS/WE, positive logic
                odt_en,     // enable ODT
                cke,        // disable CKE
                sel,        // first/second half-cycle, other will be nop (cke+odt applicable to both)
                dq_en,      // enable (not tristate) DQ  lines (internal timing sequencer for 0->1 and 1->0)
                dqs_en,     // enable (not tristate) DQS lines (internal timing sequencer for 0->1 and 1->0)
                dqs_toggle, // enable toggle DQS according to the pattern
                dci,        // DCI disable, both DQ and DQS lines (internal logic and timing sequencer for 0->1 and 1->0)
                buf_wr,     // connect to external buffer (but only if not paused)
                buf_rd,     // connect to external buffer (but only if not paused)
215 216
                1'b0,       // nop
                buf_rst);
217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233
        end
    endfunction

    function [31:0] func_encode_cmd;
        input               [14:0] addr;       // 15-bit row/column adderss
        input                [2:0] bank;       // bank (here OK to be any)
        input                [2:0] rcw;        // RAS/CAS/WE, positive logic
        input                      odt_en;     // enable ODT
        input                      cke;        // disable CKE
        input                      sel;        // first/second half-cycle, other will be nop (cke+odt applicable to both)
        input                      dq_en;      // enable (not tristate) DQ  lines (internal timing sequencer for 0->1 and 1->0)
        input                      dqs_en;     // enable (not tristate) DQS lines (internal timing sequencer for 0->1 and 1->0)
        input                      dqs_toggle; // enable toggle DQS according to the pattern
        input                      dci;        // DCI disable, both DQ and DQS lines (internal logic and timing sequencer for 0->1 and 1->0)
        input                      buf_wr;     // connect to external buffer (but only if not paused)
        input                      buf_rd;     // connect to external buffer (but only if not paused)
        input                      nop;        // add NOP after the current command, keep other data
234
        input                      buf_rst;    // connect to external buffer (but only if not paused)
235 236 237 238 239 240 241 242 243 244 245 246 247 248 249
        begin
            func_encode_cmd={
            addr[14:0], // 15-bit row/column adderss
            bank [2:0], // bank
            rcw[2:0],   // RAS/CAS/WE
            odt_en,     // enable ODT
            cke,        // may be optimized (removed from here)?
            sel,        // first/second half-cycle, other will be nop (cke+odt applicable to both)
            dq_en,      // enable (not tristate) DQ  lines (internal timing sequencer for 0->1 and 1->0)
            dqs_en,     // enable (not tristate) DQS  lines (internal timing sequencer for 0->1 and 1->0)
            dqs_toggle, // enable toggle DQS according to the pattern
            dci,        // DCI disable, both DQ and DQS lines (internal logic and timing sequencer for 0->1 and 1->0)
            buf_wr,     // phy_buf_wr,   // connect to external buffer (but only if not paused)
            buf_rd,     // phy_buf_rd,    // connect to external buffer (but only if not paused)
            nop,        // add NOP after the current command, keep other data
250
            buf_rst     // Reserved for future use
251 252 253
           };
        end
    endfunction
254
*/
255 256
endmodule