Commit d899569e authored by Andrey Filippov's avatar Andrey Filippov
Browse files

debugging/simulation

parent 9acfc5c3
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -943,7 +943,7 @@ module ddr3 (
            {1'bx, DIFF_BANK , REFRESH  , PRECHARGE} ,
            {1'bx, DIFF_BANK , REFRESH  , ACTIVATE } ,
            {1'bx, DIFF_BANK , REFRESH  , ZQ       } ,
            {1'bx, DIFF_BANK , REFRESH  , SELF_REF } : begin if ($time - tm_refresh < TRFC_MIN)                                                                                $display ("%m: at time %t ERROR:  tRFC violation during %s", $time, cmd_string[cmd]);                         end
            {1'bx, DIFF_BANK , REFRESH  , SELF_REF } : begin if ($time - tm_refresh < TRFC_MIN)                                                                                $display ("%m: at time %t ERROR:  tRFC violation during %s (%t < %t)", $time, cmd_string[cmd],$time - tm_refresh,TRFC_MIN);                         end
            {1'bx, DIFF_BANK , REFRESH  , PWR_DOWN } : begin if (ck_cntr - ck_refresh < TREFPDEN)                                                                              $display ("%m: at time %t ERROR:  tREFPDEN violation during %s", $time, cmd_string[cmd]);                     end

            // precharge
+4 −7
Original line number Diff line number Diff line
@@ -82,11 +82,8 @@ module mcntrl_ps_pio#(
 wire                     channel_pgm_en=channel_pgm_en0 || channel_pgm_en1;
 wire                     seq_done= seq_done0 || seq_done1;

// TODO: implement logic, move pages to command-based registers,
// Implement genearation of sequencer address specification, request/grant logic, 
// Port memory buffer (4 pages each, R/W fixed, port 0 - AXI read from DDR, port 1 - AXI write to DDR
// generate 16-bit data commands (and set defaults to registers)
 wire               [4:0] cmd_a;

 wire               [4:0] cmd_a; // just to compare
 wire              [31:0] cmd_data;
 wire                     cmd_we;
 wire               [1:0] status_data;
@@ -102,7 +99,7 @@ module mcntrl_ps_pio#(
 reg                [1:0] en_reset;//
 wire                     chn_rst = ~en_reset[0]; // resets command, including fifo;
 wire                     chn_en = &en_reset[1];   // enable requests by channle (continue ones in progress)
 reg                      mem_run;              // sequencere pgm granted and set, waiting/executing memory transfer to/from buffur 0/1
 reg                      mem_run;              // sequencer pgm granted and set, waiting/executing memory transfer to/from buffur 0/1
 wire                     busy;
 wire                     start;
 reg                [1:0] page;
@@ -147,7 +144,7 @@ module mcntrl_ps_pio#(
        end
        
        if (rst)                      mem_run <=0;
        else if (chn_rst && seq_done) mem_run <=0;
        else if (chn_rst || seq_done) mem_run <=0;
        else if (channel_pgm_en)      mem_run <=1;
        
        if (rst)          cmd_set <= 0;
+66 −64

File changed.

Preview size limit exceeded, changes collapsed.

+20 −5
Original line number Diff line number Diff line
@@ -128,7 +128,8 @@ module mcontr_sequencer #(
// Controller run interface, posedge mclk
    input               [10:0]   run_addr, // controller sequencer start address (0..11'h3ff - cmd0, 11'h400..11'h7ff - cmd1)
    input                [3:0]   run_chn,  // data channel to use
    input                        run_seq,  // start controller sequence (will and with !ddr_rst for stable mclk)
    input                        run_refresh, // command is refresh (invalidates channel)
    input                        run_seq,  // start controller sequence (will end with !ddr_rst for stable mclk)
    output                       run_done, // controller sequence finished
    output                       run_busy, // controller sequence in progress
    output                       mcontr_reset, // == ddr_reset that also resets sequencer  
@@ -146,6 +147,7 @@ module mcontr_sequencer #(
    output                       ext_buf_rpage_nxt, // increment external buffer read address to next page start
//    output                 [6:0] ext_buf_raddr, // valid with ext_buf_rd, 2 page MSB to be generated externally
    output                 [3:0] ext_buf_rchn,   // ==run_chn_d valid 1 cycle ahead opf ext_buf_rd!, maybe not needed - will be generated externally
    output                       ext_buf_rrefresh, // was refresh, invalidates ext_buf_rchn
    input                 [63:0] ext_buf_rdata, // Latency of ram_1kx32w_512x64r plus 2
    
//  Interface to memory read channels (up to 16)   
@@ -154,7 +156,8 @@ module mcontr_sequencer #(
    output                       ext_buf_wr,
    output                       ext_buf_wpage_nxt, // increment external buffer write address to next page start
//    output                 [6:0] ext_buf_waddr,  // valid with ext_buf_wr
    output                 [3:0] ext_buf_wchn,   // ==run_chn_d valid 1 cycle ahead of ext_buf_wr!, maybe not needed - will be generated externally
    output                 [3:0] ext_buf_wchn,   // external buffer channel with timing matching buffer writes
    output                       ext_buf_wrefresh, // was refresh, invalidates ext_buf_wchn
    output                [63:0] ext_buf_wdata,   // valid with ext_buf_wr
// temporary debug data    
    output                [11:0] tmp_debug
@@ -244,9 +247,14 @@ module mcontr_sequencer #(
 //   reg                   [1:0]  buf_page;      // one of 4 pages in the channel buffer to use for R/W
 //   reg                  [15:0]  buf_sel_1hot; // 1 hot channel buffer select
    wire                  [3:0]  run_chn_w_d; // run chn delayed to match buf_wr delay
    wire                         run_refresh_w_d; // run refresh delayed to match buf_wr delay
    
    
    reg                   [3:0]  run_chn_d;
    reg                          run_refresh_d;
    
    reg                   [3:0]  run_chn_w_d_negedge;
    reg                          run_refresh_w_d_negedge;
    
//    reg                        run_seq_d; 
    
@@ -275,12 +283,14 @@ module mcontr_sequencer #(
    assign ext_buf_rpage_nxt=buf_raddr_reset;
//    assign ext_buf_raddr=    buf_raddr;
    assign ext_buf_rchn=     run_chn_d;
    assign ext_buf_rrefresh= run_refresh_d;
    assign buf_rdata[63:0] = ext_buf_rdata;
    
    assign ext_buf_wr=       buf_wr_negedge;
    assign ext_buf_wpage_nxt=buf_waddr_reset_negedge;
//    assign ext_buf_waddr=    buf_waddr_negedge;
    assign ext_buf_wchn=     run_chn_w_d_negedge;
    assign ext_buf_wrefresh= run_refresh_w_d_negedge;
    assign ext_buf_wdata=    buf_wdata_negedge;
    
// generation of the control signals from byte-serial channel
@@ -445,6 +455,10 @@ module mcontr_sequencer #(

        if (rst)          run_chn_d <= 0;
        else if (run_seq) run_chn_d <= run_chn;
        
        if (rst)          run_refresh_d <= 0;
        else if (run_seq) run_refresh_d <= run_refresh;
        
//        if (rst) run_seq_d <= 0;
//        else run_seq_d <= run_seq;
        
@@ -456,6 +470,7 @@ module mcontr_sequencer #(
        buf_wr_negedge <= buf_wr;
        buf_wdata_negedge <= buf_wdata;
        run_chn_w_d_negedge <= run_chn_w_d; //run_chn_d;
        run_refresh_w_d_negedge <= run_refresh_w_d;
        
    end
// Command sequence memories:
@@ -595,12 +610,12 @@ module mcontr_sequencer #(
    );
    assign wbuf_delay_m1=wbuf_delay-1;

    dly_16 #(4) buf_wchn_dly_i (
    dly_16 #(5) buf_wchn_dly_i (
        .clk(mclk), // input
        .rst(1'b0), // input
        .dly(wbuf_delay_m1), //wbuf_delay[3:0]-1), // input[3:0] 
        .din(run_chn_d), // input
        .dout(run_chn_w_d) // output reg 
        .din({run_refresh_d,   run_chn_d}), // input
        .dout({run_refresh_w_d,run_chn_w_d}) // output reg 
    );
//run_chn_w_d
endmodule
+51 −40
Original line number Diff line number Diff line
@@ -21,44 +21,45 @@
`timescale 1ns/1ps

module  scheduler16 #(
    parameter width=16
    parameter width=16, // counter number of bits
    parameter n_chn=16  // number of channels
)(
    input             rst,
    input             clk,
    input [width-1:0] chn_en,    // channel enable mask  
    input [width-1:0] want_rq,   // both want_rq and need_rq should go inactive after being granted  
    input [width-1:0] need_rq,
    input [n_chn-1:0] chn_en,    // channel enable mask  
    input [n_chn-1:0] want_rq,   // both want_rq and need_rq should go inactive after being granted  
    input [n_chn-1:0] need_rq,
    input             en_schedul,    // needs to be disabled before next access can be scheduled
    output            need,      // granted access is "needed" one, not just "wanted"
    output            grant,     // single-cycle granted channel access
    output      [3:0] grant_chn, // granted  channel number, valid with grant, stays valid until en_schedul is deasserted
    // todo: add programming  sequencer address for software sequencer program? Or should it come from the channel?
    input       [3:0] pgm_addr,  // channel address to program priority
    input [width-1:0] pgm_data,  // priority data for the channel
    input             pgm_en     // enable programming priority data (use different clock?)
);
    reg [width*16-1:0] pri_reg;
    reg [15:0] want_conf, need_conf,need_want_conf;
    wire [15:0] want_set,need_set;
    reg [15:0] want_set_r,need_set_r;
    reg need_r;
    reg [width*16-1:0] sched_state;
    wire need_some=|(need_rq & & chn_en);
    wire [15:0] next_want_conf,next_need_conf;
    reg [width*n_chn-1:0] pri_reg; // priorities for each channel (start values for priority counters)
    reg       [n_chn-1:0] want_conf, need_conf,need_want_conf,need_want_conf_d;
    wire      [n_chn-1:0] want_set,need_set;
//    reg       [n_chn-1:0] want_set_r,need_set_r;
    reg       [n_chn-1:0] want_need_set_r;
    reg                   need_r, need_r2;
    reg [width*n_chn-1:0] sched_state; // priority counters for each channel
    wire                  need_some=|(need_rq & chn_en);
    wire      [n_chn-1:0] next_want_conf,next_need_conf;
    wire      [n_chn-1:0] need_want_conf_w;
    wire            [3:0] index; // channel index to select
    wire                  index_valid; // selected index valid ("needed" or "wanted")
    reg                   grant_r;      // 1 cycle long
    reg                   grant_sent; // turns on after grant, until en_schedul is de-asserted
    reg             [3:0] grant_chn_r;
    wire                  grant_w;
    assign next_want_conf=(want_conf &  want_rq & chn_en) | want_set;
    assign next_need_conf=(need_conf &  need_rq & chn_en) | need_set;
    assign grant=grant_r;
    assign grant_chn=grant_chn_r;
    assign grant_w=en_schedul && index_valid && !grant_sent;
    assign grant_w=en_schedul && index_valid && !grant_sent && !grant;
// Setting priority for each channel    
    generate
        genvar i;
        for (i=0;i<16;i=i+1) begin: pri_reg_block
        for (i=0;i<n_chn;i=i+1) begin: pri_reg_block
            always @ (posedge rst or posedge clk) begin
                if      (rst)                     pri_reg[width*i +: width] <= 0;
                else if (pgm_en && (pgm_addr==i)) pri_reg[width*i +: width] <= pgm_data; 
@@ -66,7 +67,9 @@ module scheduler16 #(
        end
    endgenerate        

    pri1hot16 i_pri1hot16_want(
// priority 1-hot encoders to make sure only one want/need request is "confirmed" in each clock cycle
// TODO: Make pri1hot16 parameter-configurable to be able to change priorities later
    pri1hot16 i_pri1hot16_want( // priority encoder, 1-hot output (lowest bit has highest priority)
        .in(want_rq & ~want_conf & chn_en),
        .out(want_set),
        .some());
@@ -75,6 +78,9 @@ module scheduler16 #(
        .out(need_set),
        .some());
        
    assign next_want_conf=  (want_conf &  want_rq & chn_en) | want_set;
    assign next_need_conf=  (need_conf &  need_rq & chn_en) | need_set;
    assign need_want_conf_w=need_some? next_need_conf: next_want_conf;
    always @(posedge rst or posedge clk) begin
        if (rst) begin
            want_conf <= 0;
@@ -82,13 +88,16 @@ module scheduler16 #(
        end else begin
            want_conf <= next_want_conf;
            need_conf <= next_need_conf;
            need_want_conf<= need_some? next_need_conf: next_want_conf; 
            need_want_conf  <= need_want_conf_w; // need_some? next_need_conf: next_want_conf; 
            need_want_conf_d <= need_want_conf &  need_want_conf_w; // delay for on, no delay for off
        end
    end
    always @ (posedge clk) begin
        want_set_r<=want_set;
        need_set_r<=need_set;
//        want_set_r<=want_set;
//        need_set_r<=need_set;
        want_need_set_r <= want_set | need_set;
        need_r  <= need_some;
        need_r2 <= need_r;
    end
    // TODO: want remains, need is removed (both need and want should be deactivated on grant!)
    // Block that sets initial process state and increments it on every change of the requests
@@ -96,9 +105,11 @@ module scheduler16 #(
        genvar i1;
        for (i1=0;i1<16;i1=i1+1) begin: sched_state_block
            always @ (posedge rst or posedge clk) begin
                if (rst) pri_reg[width*i1 +: width] <= 0; // not needed?
                else begin
                    if (want_set_r[i1] || need_set_r[i1])  sched_state[width*i1 +: width] <= pri_reg[width*i1 +: width];
//                if (rst) sched_state[width*i1 +: width] <= 0; // not needed?
//                else
                begin
//                    if (want_set_r[i1] || need_set_r[i1])          sched_state[width*i1 +: width] <= pri_reg[width*i1 +: width];
                    if (want_need_set_r[i1])          sched_state[width*i1 +: width] <= pri_reg[width*i1 +: width];
                    // increment, but do not roll over
                    else if (&sched_state[width*i1 +: width] == 0) sched_state[width*i1 +: width] <= sched_state[width*i1 +: width]+1; 
                end 
@@ -109,8 +120,8 @@ module scheduler16 #(
    index_max_16 #(width) i_index_max_16(
        .clk      (clk),
        .values   (sched_state),
        .mask(need_want_conf),
        .need_in(need_r),
        .mask     (need_want_conf_d),
        .need_in  (need_r2),
        .index    (index[3:0]),
        .valid    (index_valid),
        .need_out (need));
Loading