Commit d899569e authored by Andrey Filippov's avatar Andrey Filippov

debugging/simulation

parent 9acfc5c3
...@@ -943,7 +943,7 @@ module ddr3 ( ...@@ -943,7 +943,7 @@ module ddr3 (
{1'bx, DIFF_BANK , REFRESH , PRECHARGE} , {1'bx, DIFF_BANK , REFRESH , PRECHARGE} ,
{1'bx, DIFF_BANK , REFRESH , ACTIVATE } , {1'bx, DIFF_BANK , REFRESH , ACTIVATE } ,
{1'bx, DIFF_BANK , REFRESH , ZQ } , {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 {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 // precharge
......
...@@ -82,11 +82,8 @@ module mcntrl_ps_pio#( ...@@ -82,11 +82,8 @@ module mcntrl_ps_pio#(
wire channel_pgm_en=channel_pgm_en0 || channel_pgm_en1; wire channel_pgm_en=channel_pgm_en0 || channel_pgm_en1;
wire seq_done= seq_done0 || seq_done1; 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, wire [4:0] cmd_a; // just to compare
// 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 [31:0] cmd_data; wire [31:0] cmd_data;
wire cmd_we; wire cmd_we;
wire [1:0] status_data; wire [1:0] status_data;
...@@ -102,7 +99,7 @@ module mcntrl_ps_pio#( ...@@ -102,7 +99,7 @@ module mcntrl_ps_pio#(
reg [1:0] en_reset;// reg [1:0] en_reset;//
wire chn_rst = ~en_reset[0]; // resets command, including fifo; wire chn_rst = ~en_reset[0]; // resets command, including fifo;
wire chn_en = &en_reset[1]; // enable requests by channle (continue ones in progress) 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 busy;
wire start; wire start;
reg [1:0] page; reg [1:0] page;
...@@ -147,7 +144,7 @@ module mcntrl_ps_pio#( ...@@ -147,7 +144,7 @@ module mcntrl_ps_pio#(
end end
if (rst) mem_run <=0; 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; else if (channel_pgm_en) mem_run <=1;
if (rst) cmd_set <= 0; if (rst) cmd_set <= 0;
......
This diff is collapsed.
...@@ -128,7 +128,8 @@ module mcontr_sequencer #( ...@@ -128,7 +128,8 @@ module mcontr_sequencer #(
// Controller run interface, posedge mclk // Controller run interface, posedge mclk
input [10:0] run_addr, // controller sequencer start address (0..11'h3ff - cmd0, 11'h400..11'h7ff - cmd1) 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 [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_done, // controller sequence finished
output run_busy, // controller sequence in progress output run_busy, // controller sequence in progress
output mcontr_reset, // == ddr_reset that also resets sequencer output mcontr_reset, // == ddr_reset that also resets sequencer
...@@ -146,6 +147,7 @@ module mcontr_sequencer #( ...@@ -146,6 +147,7 @@ module mcontr_sequencer #(
output ext_buf_rpage_nxt, // increment external buffer read address to next page start 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 [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 [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 input [63:0] ext_buf_rdata, // Latency of ram_1kx32w_512x64r plus 2
// Interface to memory read channels (up to 16) // Interface to memory read channels (up to 16)
...@@ -154,7 +156,8 @@ module mcontr_sequencer #( ...@@ -154,7 +156,8 @@ module mcontr_sequencer #(
output ext_buf_wr, output ext_buf_wr,
output ext_buf_wpage_nxt, // increment external buffer write address to next page start 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 [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 output [63:0] ext_buf_wdata, // valid with ext_buf_wr
// temporary debug data // temporary debug data
output [11:0] tmp_debug output [11:0] tmp_debug
...@@ -244,9 +247,14 @@ module mcontr_sequencer #( ...@@ -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 [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 // 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 [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 [3:0] run_chn_d;
reg run_refresh_d;
reg [3:0] run_chn_w_d_negedge; reg [3:0] run_chn_w_d_negedge;
reg run_refresh_w_d_negedge;
// reg run_seq_d; // reg run_seq_d;
...@@ -275,12 +283,14 @@ module mcontr_sequencer #( ...@@ -275,12 +283,14 @@ module mcontr_sequencer #(
assign ext_buf_rpage_nxt=buf_raddr_reset; assign ext_buf_rpage_nxt=buf_raddr_reset;
// assign ext_buf_raddr= buf_raddr; // assign ext_buf_raddr= buf_raddr;
assign ext_buf_rchn= run_chn_d; assign ext_buf_rchn= run_chn_d;
assign ext_buf_rrefresh= run_refresh_d;
assign buf_rdata[63:0] = ext_buf_rdata; assign buf_rdata[63:0] = ext_buf_rdata;
assign ext_buf_wr= buf_wr_negedge; assign ext_buf_wr= buf_wr_negedge;
assign ext_buf_wpage_nxt=buf_waddr_reset_negedge; assign ext_buf_wpage_nxt=buf_waddr_reset_negedge;
// assign ext_buf_waddr= buf_waddr_negedge; // assign ext_buf_waddr= buf_waddr_negedge;
assign ext_buf_wchn= run_chn_w_d_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; assign ext_buf_wdata= buf_wdata_negedge;
// generation of the control signals from byte-serial channel // generation of the control signals from byte-serial channel
...@@ -445,6 +455,10 @@ module mcontr_sequencer #( ...@@ -445,6 +455,10 @@ module mcontr_sequencer #(
if (rst) run_chn_d <= 0; if (rst) run_chn_d <= 0;
else if (run_seq) run_chn_d <= run_chn; 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; // if (rst) run_seq_d <= 0;
// else run_seq_d <= run_seq; // else run_seq_d <= run_seq;
...@@ -456,6 +470,7 @@ module mcontr_sequencer #( ...@@ -456,6 +470,7 @@ module mcontr_sequencer #(
buf_wr_negedge <= buf_wr; buf_wr_negedge <= buf_wr;
buf_wdata_negedge <= buf_wdata; buf_wdata_negedge <= buf_wdata;
run_chn_w_d_negedge <= run_chn_w_d; //run_chn_d; run_chn_w_d_negedge <= run_chn_w_d; //run_chn_d;
run_refresh_w_d_negedge <= run_refresh_w_d;
end end
// Command sequence memories: // Command sequence memories:
...@@ -595,12 +610,12 @@ module mcontr_sequencer #( ...@@ -595,12 +610,12 @@ module mcontr_sequencer #(
); );
assign wbuf_delay_m1=wbuf_delay-1; assign wbuf_delay_m1=wbuf_delay-1;
dly_16 #(4) buf_wchn_dly_i ( dly_16 #(5) buf_wchn_dly_i (
.clk(mclk), // input .clk(mclk), // input
.rst(1'b0), // input .rst(1'b0), // input
.dly(wbuf_delay_m1), //wbuf_delay[3:0]-1), // input[3:0] .dly(wbuf_delay_m1), //wbuf_delay[3:0]-1), // input[3:0]
.din(run_chn_d), // input .din({run_refresh_d, run_chn_d}), // input
.dout(run_chn_w_d) // output reg .dout({run_refresh_w_d,run_chn_w_d}) // output reg
); );
//run_chn_w_d //run_chn_w_d
endmodule endmodule
......
...@@ -21,52 +21,55 @@ ...@@ -21,52 +21,55 @@
`timescale 1ns/1ps `timescale 1ns/1ps
module scheduler16 #( module scheduler16 #(
parameter width=16 parameter width=16, // counter number of bits
parameter n_chn=16 // number of channels
)( )(
input rst, input rst,
input clk, input clk,
input [width-1:0] chn_en, // channel enable mask input [n_chn-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 [n_chn-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] need_rq,
input en_schedul, // needs to be disabled before next access can be scheduled input en_schedul, // needs to be disabled before next access can be scheduled
output need, // granted access is "needed" one, not just "wanted" output need, // granted access is "needed" one, not just "wanted"
output grant, // single-cycle granted channel access 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 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 [3:0] pgm_addr, // channel address to program priority
input [width-1:0] pgm_data, // priority data for the channel input [width-1:0] pgm_data, // priority data for the channel
input pgm_en // enable programming priority data (use different clock?) input pgm_en // enable programming priority data (use different clock?)
); );
reg [width*16-1:0] pri_reg; reg [width*n_chn-1:0] pri_reg; // priorities for each channel (start values for priority counters)
reg [15:0] want_conf, need_conf,need_want_conf; reg [n_chn-1:0] want_conf, need_conf,need_want_conf,need_want_conf_d;
wire [15:0] want_set,need_set; wire [n_chn-1:0] want_set,need_set;
reg [15:0] want_set_r,need_set_r; // reg [n_chn-1:0] want_set_r,need_set_r;
reg need_r; reg [n_chn-1:0] want_need_set_r;
reg [width*16-1:0] sched_state; reg need_r, need_r2;
wire need_some=|(need_rq & & chn_en); reg [width*n_chn-1:0] sched_state; // priority counters for each channel
wire [15:0] next_want_conf,next_need_conf; wire need_some=|(need_rq & chn_en);
wire [3:0] index; // channel index to select wire [n_chn-1:0] next_want_conf,next_need_conf;
wire index_valid; // selected index valid ("needed" or "wanted") wire [n_chn-1:0] need_want_conf_w;
reg grant_r; // 1 cycle long wire [3:0] index; // channel index to select
reg grant_sent; // turns on after grant, until en_schedul is de-asserted wire index_valid; // selected index valid ("needed" or "wanted")
reg [3:0] grant_chn_r; reg grant_r; // 1 cycle long
wire grant_w; reg grant_sent; // turns on after grant, until en_schedul is de-asserted
assign next_want_conf=(want_conf & want_rq & chn_en) | want_set; reg [3:0] grant_chn_r;
assign next_need_conf=(need_conf & need_rq & chn_en) | need_set; wire grant_w;
assign grant=grant_r; assign grant=grant_r;
assign grant_chn=grant_chn_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 generate
genvar i; 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 always @ (posedge rst or posedge clk) begin
if (rst) pri_reg[width*i +: width] <= 0; if (rst) pri_reg[width*i +: width] <= 0;
else if (pgm_en && (pgm_addr==i)) pri_reg[width*i +: width] <= pgm_data; else if (pgm_en && (pgm_addr==i)) pri_reg[width*i +: width] <= pgm_data;
end end
end end
endgenerate 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), .in(want_rq & ~want_conf & chn_en),
.out(want_set), .out(want_set),
.some()); .some());
...@@ -75,6 +78,9 @@ module scheduler16 #( ...@@ -75,6 +78,9 @@ module scheduler16 #(
.out(need_set), .out(need_set),
.some()); .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 always @(posedge rst or posedge clk) begin
if (rst) begin if (rst) begin
want_conf <= 0; want_conf <= 0;
...@@ -82,13 +88,16 @@ module scheduler16 #( ...@@ -82,13 +88,16 @@ module scheduler16 #(
end else begin end else begin
want_conf <= next_want_conf; want_conf <= next_want_conf;
need_conf <= next_need_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
end end
always @ (posedge clk) begin always @ (posedge clk) begin
want_set_r<=want_set; // want_set_r<=want_set;
need_set_r<=need_set; // need_set_r<=need_set;
need_r<= need_some; want_need_set_r <= want_set | need_set;
need_r <= need_some;
need_r2 <= need_r;
end end
// TODO: want remains, need is removed (both need and want should be deactivated on grant!) // 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 // Block that sets initial process state and increments it on every change of the requests
...@@ -96,24 +105,26 @@ module scheduler16 #( ...@@ -96,24 +105,26 @@ module scheduler16 #(
genvar i1; genvar i1;
for (i1=0;i1<16;i1=i1+1) begin: sched_state_block for (i1=0;i1<16;i1=i1+1) begin: sched_state_block
always @ (posedge rst or posedge clk) begin always @ (posedge rst or posedge clk) begin
if (rst) pri_reg[width*i1 +: width] <= 0; // not needed? // if (rst) sched_state[width*i1 +: width] <= 0; // not needed?
else begin // else
if (want_set_r[i1] || need_set_r[i1]) sched_state[width*i1 +: width] <= pri_reg[width*i1 +: width]; 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 // 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; else if (&sched_state[width*i1 +: width] == 0) sched_state[width*i1 +: width] <= sched_state[width*i1 +: width]+1;
end end
end end
end end
endgenerate endgenerate
// Select the process to run // Select the process to run
index_max_16 #(width) i_index_max_16( index_max_16 #(width) i_index_max_16(
.clk(clk), .clk (clk),
.values(sched_state), .values (sched_state),
.mask(need_want_conf), .mask (need_want_conf_d),
.need_in(need_r), .need_in (need_r2),
.index(index[3:0]), .index (index[3:0]),
.valid(index_valid), .valid (index_valid),
.need_out(need)); .need_out (need));
always @(posedge rst or posedge clk) begin always @(posedge rst or posedge clk) begin
if (rst) begin if (rst) begin
grant_r <=0; grant_r <=0;
......
...@@ -35,11 +35,19 @@ module index_max_16 #( ...@@ -35,11 +35,19 @@ module index_max_16 #(
wire [width-1:0] max0001020304050607,max0809101112131415; wire [width-1:0] max0001020304050607,max0809101112131415;
wire sel0001,sel0203,sel0405,sel0607,sel0809,sel1011,sel1213,sel1415,sel00010203,sel04050607; wire sel0001,sel0203,sel0405,sel0607,sel0809,sel1011,sel1213,sel1415,sel00010203,sel04050607;
wire sel08091011, sel12131415, sel0001020304050607,sel0809101112131415, sel; wire sel08091011, sel12131415, sel0001020304050607,sel0809101112131415, sel;
wire msk0001,msk0203,msk0405,msk0607,msk0809,msk1011,msk1213,msk1415,msk00010203,msk04050607;
wire msk08091011, msk12131415, msk0001020304050607,msk0809101112131415; //, msk;
reg sel0001_r,sel0203_r,sel0405_r,sel0607_r,sel0809_r,sel1011_r,sel1213_r,sel1415_r; reg sel0001_r,sel0203_r,sel0405_r,sel0607_r,sel0809_r,sel1011_r,sel1213_r,sel1415_r;
reg [1:0] sel00010203_r,sel04050607_r,sel08091011_r, sel12131415_r; reg [1:0] sel00010203_r,sel04050607_r,sel08091011_r, sel12131415_r;
reg [2:0] sel0001020304050607_r,sel0809101112131415_r; reg [2:0] sel0001020304050607_r,sel0809101112131415_r;
reg [3:0] valid_dly; reg [3:0] valid_dly;
reg [3:0] need_dly; reg [3:0] need_dly;
reg [15:0] mask_prev; // previous value of mask (invalidate if mask changes)
wire mask_changed;
// assign mask_changed= mask!=mask_prev;
assign mask_changed= |(~mask &mask_prev); // only invalidate if any bit goes off (granted)
// 1-st layer // 1-st layer
masked_max_reg #(width) i_masked_max_reg0001( masked_max_reg #(width) i_masked_max_reg0001(
...@@ -49,7 +57,8 @@ module index_max_16 #( ...@@ -49,7 +57,8 @@ module index_max_16 #(
.b(values[width*1 +: width]), .b(values[width*1 +: width]),
.mask_b(mask[1]), .mask_b(mask[1]),
.max(max0001), .max(max0001),
.s(sel0001)); .s(sel0001),
.valid(msk0001));
masked_max_reg #(width) i_masked_max_reg0203( masked_max_reg #(width) i_masked_max_reg0203(
.clk(clk), .clk(clk),
.a(values[width*2 +: width]), .a(values[width*2 +: width]),
...@@ -57,7 +66,8 @@ module index_max_16 #( ...@@ -57,7 +66,8 @@ module index_max_16 #(
.b(values[width*3 +: width]), .b(values[width*3 +: width]),
.mask_b(mask[3]), .mask_b(mask[3]),
.max(max0203), .max(max0203),
.s(sel0203)); .s(sel0203),
.valid(msk0203));
masked_max_reg #(width) i_masked_max_reg0405( masked_max_reg #(width) i_masked_max_reg0405(
.clk(clk), .clk(clk),
.a(values[width*4 +: width]), .a(values[width*4 +: width]),
...@@ -65,7 +75,8 @@ module index_max_16 #( ...@@ -65,7 +75,8 @@ module index_max_16 #(
.b(values[width*5 +: width]), .b(values[width*5 +: width]),
.mask_b(mask[5]), .mask_b(mask[5]),
.max(max0405), .max(max0405),
.s(sel0405)); .s(sel0405),
.valid(msk0405));
masked_max_reg #(width) i_masked_max_reg0607( masked_max_reg #(width) i_masked_max_reg0607(
.clk(clk), .clk(clk),
.a(values[width*6 +: width]), .a(values[width*6 +: width]),
...@@ -73,7 +84,8 @@ module index_max_16 #( ...@@ -73,7 +84,8 @@ module index_max_16 #(
.b(values[width*7 +: width]), .b(values[width*7 +: width]),
.mask_b(mask[7]), .mask_b(mask[7]),
.max(max0607), .max(max0607),
.s(sel0607)); .s(sel0607),
.valid(msk0607));
masked_max_reg #(width) i_masked_max_reg0809( masked_max_reg #(width) i_masked_max_reg0809(
.clk(clk), .clk(clk),
.a(values[width*8 +: width]), .a(values[width*8 +: width]),
...@@ -81,7 +93,8 @@ module index_max_16 #( ...@@ -81,7 +93,8 @@ module index_max_16 #(
.b(values[width*9 +: width]), .b(values[width*9 +: width]),
.mask_b(mask[9]), .mask_b(mask[9]),
.max(max0809), .max(max0809),
.s(sel0809)); .s(sel0809),
.valid(msk0809));
masked_max_reg #(width) i_masked_max_reg1011( masked_max_reg #(width) i_masked_max_reg1011(
.clk(clk), .clk(clk),
.a(values[width*10 +: width]), .a(values[width*10 +: width]),
...@@ -89,7 +102,8 @@ module index_max_16 #( ...@@ -89,7 +102,8 @@ module index_max_16 #(
.b(values[width*11 +: width]), .b(values[width*11 +: width]),
.mask_b(mask[11]), .mask_b(mask[11]),
.max(max1011), .max(max1011),
.s(sel1011)); .s(sel1011),
.valid(msk1011));
masked_max_reg #(width) i_masked_max_reg1213( masked_max_reg #(width) i_masked_max_reg1213(
.clk(clk), .clk(clk),
.a(values[width*12 +: width]), .a(values[width*12 +: width]),
...@@ -97,7 +111,8 @@ module index_max_16 #( ...@@ -97,7 +111,8 @@ module index_max_16 #(
.b(values[width*13 +: width]), .b(values[width*13 +: width]),
.mask_b(mask[13]), .mask_b(mask[13]),
.max(max1213), .max(max1213),
.s(sel1213)); .s(sel1213),
.valid(msk1213));
masked_max_reg #(width) i_masked_max_reg1415( masked_max_reg #(width) i_masked_max_reg1415(
.clk(clk), .clk(clk),
.a(values[width*14 +: width]), .a(values[width*14 +: width]),
...@@ -105,67 +120,75 @@ module index_max_16 #( ...@@ -105,67 +120,75 @@ module index_max_16 #(
.b(values[width*15 +: width]), .b(values[width*15 +: width]),
.mask_b(mask[15]), .mask_b(mask[15]),
.max(max1415), .max(max1415),
.s(sel1415)); .s(sel1415),
.valid(msk1415));
// 2-nd layer // 2-nd layer
masked_max_reg #(width) i_masked_max_reg00010203( masked_max_reg #(width) i_masked_max_reg00010203(
.clk(clk), .clk(clk),
.a(max0001), .a(max0001),
.mask_a(&mask[1:0]), .mask_a(msk0001),
.b(max0203), .b(max0203),
.mask_b(&mask[3:2]), .mask_b(msk0203),
.max(max00010203), .max(max00010203),
.s(sel00010203)); .s(sel00010203),
.valid(msk00010203));
masked_max_reg #(width) i_masked_max_reg04050607( masked_max_reg #(width) i_masked_max_reg04050607(
.clk(clk), .clk(clk),
.a(max0405), .a(max0405),
.mask_a(&mask[5:4]), .mask_a(msk0405),
.b(max0607), .b(max0607),
.mask_b(&mask[7:6]), .mask_b(msk0607),
.max(max04050607), .max(max04050607),
.s(sel04050607)); .s(sel04050607),
.valid(msk04050607));
masked_max_reg #(width) i_masked_max_reg08091011( masked_max_reg #(width) i_masked_max_reg08091011(
.clk(clk), .clk(clk),
.a(max0809), .a(max0809),
.mask_a(&mask[9:8]), .mask_a(msk0809),
.b(max1011), .b(max1011),
.mask_b(&mask[11:10]), .mask_b(msk1011),
.max(max08091011), .max(max08091011),
.s(sel08091011)); .s(sel08091011),
.valid(msk08091011));
masked_max_reg #(width) i_masked_max_reg12131415( masked_max_reg #(width) i_masked_max_reg12131415(
.clk(clk), .clk(clk),
.a(max1213), .a(max1213),
.mask_a(&mask[13:12]), .mask_a(msk1213),
.b(max1415), .b(max1415),
.mask_b(&mask[15:14]), .mask_b(msk1415),
.max(max12131415), .max(max12131415),
.s(sel12131415)); .s(sel12131415),
.valid(msk12131415));
// 3-nd layer // 3-nd layer
masked_max_reg #(width) i_masked_max_reg0001020304050607( masked_max_reg #(width) i_masked_max_reg0001020304050607(
.clk(clk), .clk(clk),
.a(max00010203), .a(max00010203),
.mask_a(&mask[3:0]), .mask_a(msk00010203),
.b(max04050607), .b(max04050607),
.mask_b(&mask[7:4]), .mask_b(msk04050607),
.max(max0001020304050607), .max(max0001020304050607),
.s(sel0001020304050607)); .s(sel0001020304050607),
.valid(msk0001020304050607));
masked_max_reg #(width) i_masked_max_reg0809101112131415( masked_max_reg #(width) i_masked_max_reg0809101112131415(
.clk(clk), .clk(clk),
.a(max08091011), .a(max08091011),
.mask_a(&mask[11:8]), .mask_a(msk08091011),
.b(max12131415), .b(max12131415),
.mask_b(&mask[15:12]), .mask_b(msk12131415),
.max(max0809101112131415), .max(max0809101112131415),
.s(sel0809101112131415)); .s(sel0809101112131415),
.valid(msk0809101112131415));
// 4-th layer // 4-th layer
masked_max_reg #(width) i_masked_max_reg( masked_max_reg #(width) i_masked_max_reg(
.clk(clk), .clk(clk),
.a(max0001020304050607), .a(max0001020304050607),
.mask_a(&mask[7:0]), .mask_a(msk0001020304050607),
.b(max0809101112131415), .b(max0809101112131415),
.mask_b(&mask[15:8]), .mask_b(msk0809101112131415),
.max(), .max(),
.s(sel)); .s(sel),
.valid()); //msk));
always @ (posedge clk) begin always @ (posedge clk) begin
sel0001_r<=sel0001; sel0001_r<=sel0001;
sel0203_r<=sel0203; sel0203_r<=sel0203;
...@@ -181,14 +204,16 @@ module index_max_16 #( ...@@ -181,14 +204,16 @@ module index_max_16 #(
sel12131415_r[1:0]<={sel12131415,sel12131415?sel1415_r:sel1213_r}; sel12131415_r[1:0]<={sel12131415,sel12131415?sel1415_r:sel1213_r};
sel0001020304050607_r[2:0]<={sel0001020304050607,sel0001020304050607?sel04050607_r[1:0]:sel00010203_r[1:0]}; sel0001020304050607_r[2:0]<={sel0001020304050607,sel0001020304050607?sel04050607_r[1:0]:sel00010203_r[1:0]};
sel0809101112131415_r[2:0]<={sel0809101112131415,sel0809101112131415?sel12131415_r[1:0]:sel08091011_r[1:0]}; sel0809101112131415_r[2:0]<={sel0809101112131415,sel0809101112131415?sel12131415_r[1:0]:sel08091011_r[1:0]};
valid_dly[3:0] <= {valid_dly[2:0],|mask[15:0]}; valid_dly[3:0] <= {valid_dly[2:0],|mask[15:0] & ~mask_changed}; // invalidate when mask changed (or only if new is zero?
need_dly[3:0] <= {need_dly[2:0],need_in}; need_dly[3:0] <= {need_dly[2:0],need_in};
mask_prev <= mask;
end end
assign index[3:0]={ assign index[3:0]={
sel, sel,
sel?sel0809101112131415_r[2:0]:sel0001020304050607_r[2:0]}; sel?sel0809101112131415_r[2:0]:sel0001020304050607_r[2:0]};
assign valid=valid_dly[3]; //assign valid=valid_dly[3];
assign valid=&valid_dly; // need && |mask ?
assign need_out=need_dly[3]; assign need_out=need_dly[3];
endmodule endmodule
...@@ -29,16 +29,21 @@ module masked_max_reg#( ...@@ -29,16 +29,21 @@ module masked_max_reg#(
input [width-1:0] b, input [width-1:0] b,
input mask_b, input mask_b,
output [width-1:0] max, output [width-1:0] max,
output s output s,
output valid // at least one of the inputs was valid (matches outputs)
); );
reg [width-1:0] max_r; reg [width-1:0] max_r;
reg s_r; reg s_r;
reg valid_r;
assign s=s_r; assign s=s_r;
assign max=max_r; assign max=max_r;
wire s_w= mask_b && ((mask_a && (b>a)) || !mask_a); assign valid=valid_r;
// wire s_w= mask_b && ((mask_a && (b>a)) || !mask_a);
wire s_w= mask_b && (!mask_a || (b>a));
always @ (posedge clk) begin always @ (posedge clk) begin
s_r <= s_w; s_r <= s_w;
max_r <= (mask_a || mask_b)? (s_w?b:a): 0; max_r <= (mask_a || mask_b)? (s_w?b:a): {width{1'b0}};
valid_r <= mask_a || mask_b;
end end
endmodule endmodule
...@@ -26,6 +26,7 @@ module mcont_common_chnbuf_reg #( ...@@ -26,6 +26,7 @@ module mcont_common_chnbuf_reg #(
input rst, input rst,
input clk, input clk,
input [3:0] ext_buf_rchn, // ==run_chn_d valid 1 cycle ahead opf ext_buf_rd!, maybe not needed - will be generated externally input [3:0] ext_buf_rchn, // ==run_chn_d valid 1 cycle ahead opf ext_buf_rd!, maybe not needed - will be generated externally
input ext_buf_rrefresh,
input ext_buf_rpage_nxt, input ext_buf_rpage_nxt,
input seq_done, // sequence done input seq_done, // sequence done
output reg buf_done, // sequence done for the specified channel output reg buf_done, // sequence done for the specified channel
...@@ -34,12 +35,12 @@ module mcont_common_chnbuf_reg #( ...@@ -34,12 +35,12 @@ module mcont_common_chnbuf_reg #(
reg buf_chn_sel; reg buf_chn_sel;
always @ (posedge rst or posedge clk) begin always @ (posedge rst or posedge clk) begin
if (rst) buf_chn_sel <= 0; if (rst) buf_chn_sel <= 0;
else buf_chn_sel <= (ext_buf_rchn==CHN_NUMBER); else buf_chn_sel <= (ext_buf_rchn==CHN_NUMBER) && !ext_buf_rrefresh;
if (rst) buf_done <= 0; if (rst) buf_done <= 0;
else buf_done <= buf_chn_sel && seq_done; else buf_done <= buf_chn_sel && seq_done;
end end
always @ (posedge clk) rpage_nxt <= ext_buf_rpage_nxt && (ext_buf_rchn==CHN_NUMBER); always @ (posedge clk) rpage_nxt <= ext_buf_rpage_nxt && (ext_buf_rchn==CHN_NUMBER) && !ext_buf_rrefresh;
endmodule endmodule
...@@ -29,6 +29,7 @@ module mcont_from_chnbuf_reg #( ...@@ -29,6 +29,7 @@ module mcont_from_chnbuf_reg #(
input ext_buf_rd, input ext_buf_rd,
// input ext_buf_raddr_rst, // input ext_buf_raddr_rst,
input [3:0] ext_buf_rchn, // ==run_chn_d valid 1 cycle ahead opf ext_buf_rd!, maybe not needed - will be generated externally input [3:0] ext_buf_rchn, // ==run_chn_d valid 1 cycle ahead opf ext_buf_rd!, maybe not needed - will be generated externally
input ext_buf_rrefresh,
// input seq_done, // sequence done // input seq_done, // sequence done
// output reg buf_done, // sequence done for the specified channel // output reg buf_done, // sequence done for the specified channel
output reg [63:0] ext_buf_rdata, // Latency of ram_1kx32w_512x64r plus 2 output reg [63:0] ext_buf_rdata, // Latency of ram_1kx32w_512x64r plus 2
...@@ -40,7 +41,7 @@ module mcont_from_chnbuf_reg #( ...@@ -40,7 +41,7 @@ module mcont_from_chnbuf_reg #(
reg [CHN_LATENCY:0] latency_reg=0; reg [CHN_LATENCY:0] latency_reg=0;
always @ (posedge rst or posedge clk) begin always @ (posedge rst or posedge clk) begin
if (rst) buf_chn_sel <= 0; if (rst) buf_chn_sel <= 0;
else buf_chn_sel <= (ext_buf_rchn==CHN_NUMBER); else buf_chn_sel <= (ext_buf_rchn==CHN_NUMBER) && !ext_buf_rrefresh;
if (rst) buf_rd_chn <= 0; if (rst) buf_rd_chn <= 0;
else buf_rd_chn <= buf_chn_sel && ext_buf_rd; else buf_rd_chn <= buf_chn_sel && ext_buf_rd;
......
...@@ -27,7 +27,8 @@ parameter CHN_NUMBER=0 ...@@ -27,7 +27,8 @@ parameter CHN_NUMBER=0
input clk, input clk,
input ext_buf_wr, input ext_buf_wr,
input ext_buf_wpage_nxt, input ext_buf_wpage_nxt,
input [3:0] ext_buf_wchn, // ==run_chn_d valid 1 cycle ahead opf ext_buf_wr!, maybe not needed - will be generated externally input [3:0] ext_buf_wchn, //
input ext_buf_wrefresh,
input [63:0] ext_buf_wdata, // valid with ext_buf_wr input [63:0] ext_buf_wdata, // valid with ext_buf_wr
// input seq_done, // sequence done // input seq_done, // sequence done
// output reg buf_done, // @ posedge mclk sequence done for the specified channel // output reg buf_done, // @ posedge mclk sequence done for the specified channel
...@@ -38,7 +39,7 @@ parameter CHN_NUMBER=0 ...@@ -38,7 +39,7 @@ parameter CHN_NUMBER=0
reg buf_chn_sel; reg buf_chn_sel;
always @ (posedge rst or negedge clk) begin always @ (posedge rst or negedge clk) begin
if (rst) buf_chn_sel <= 0; if (rst) buf_chn_sel <= 0;
else buf_chn_sel <= (ext_buf_wchn==CHN_NUMBER); else buf_chn_sel <= (ext_buf_wchn==CHN_NUMBER) && !ext_buf_wrefresh;
if (rst) buf_wr_chn <= 0; if (rst) buf_wr_chn <= 0;
else buf_wr_chn <= buf_chn_sel && ext_buf_wr; else buf_wr_chn <= buf_chn_sel && ext_buf_wr;
...@@ -50,7 +51,7 @@ parameter CHN_NUMBER=0 ...@@ -50,7 +51,7 @@ parameter CHN_NUMBER=0
// end // end
always @ (negedge clk) begin always @ (negedge clk) begin
buf_wpage_nxt_chn <= ext_buf_wpage_nxt && (ext_buf_wchn==CHN_NUMBER); buf_wpage_nxt_chn <= ext_buf_wpage_nxt && (ext_buf_wchn==CHN_NUMBER) && !ext_buf_wrefresh;
end end
always @ (negedge clk) if (buf_chn_sel && ext_buf_wr) begin always @ (negedge clk) if (buf_chn_sel && ext_buf_wr) begin
......
This diff is collapsed.
...@@ -202,7 +202,8 @@ always #(CLKIN_PERIOD/2) CLK <= ~CLK; ...@@ -202,7 +202,8 @@ always #(CLKIN_PERIOD/2) CLK <= ~CLK;
axi_set_b_lag(0); //(1); axi_set_b_lag(0); //(1);
axi_set_rd_lag(0); axi_set_rd_lag(0);
program_status_all(3,'h2a); // mode auto with sequence number increment program_status_all(3,'h2a); // mode auto with sequence number increment
//...
enable_memcntrl(1); // enable memory controller
set_up; set_up;
wait_phase_shifter_ready; wait_phase_shifter_ready;
...@@ -217,6 +218,23 @@ always #(CLKIN_PERIOD/2) CLK <= ~CLK; ...@@ -217,6 +218,23 @@ always #(CLKIN_PERIOD/2) CLK <= ~CLK;
repeat (16) @(posedge CLK) ; repeat (16) @(posedge CLK) ;
enable_cke(1); enable_cke(1);
repeat (16) @(posedge CLK) ; repeat (16) @(posedge CLK) ;
// enable_memcntrl(1); // enable memory controller
enable_memcntrl_channels(16'h0003); // only channel 0 and 1 are enabled
configure_channel_priority(0,0); // lowest priority channel 0
configure_channel_priority(1,0); // lowest priority channel 1
enable_reset_ps_pio(1,0); // enable, no reset
schedule_ps_pio ( // shedule software-control memory operation (may need to check FIFO status first)
INITIALIZE_OFFSET, // input [9:0] seq_addr; // sequence start address
0, // input [1:0] page; // buffer page number
0, // input urgent; // high priority request (only for competion wityh other channels, wiil not pass in this FIFO)
0); // input chn; // channel buffer to use: 0 - memory read, 1 - memory write
repeat (32) @(posedge CLK) ; // what delay is needed to be sure? Add to PS_PIO?
enable_refresh(1);
/* /*
run_mrs; run_mrs;
...@@ -231,7 +249,7 @@ always #(CLKIN_PERIOD/2) CLK <= ~CLK; ...@@ -231,7 +249,7 @@ always #(CLKIN_PERIOD/2) CLK <= ~CLK;
#2000; #20000;
$finish; $finish;
end end
// protect from never end // protect from never end
...@@ -866,10 +884,49 @@ endtask ...@@ -866,10 +884,49 @@ endtask
task enable_refresh; task enable_refresh;
input en; input en;
begin begin
write_contol_register(MCONTR_PHY_0BIT_ADDR + MCONTR_TOP_0BIT_REFRESH_EN + en, 0); write_contol_register(MCONTR_TOP_0BIT_ADDR + MCONTR_TOP_0BIT_REFRESH_EN + en, 0);
end
endtask
task enable_memcntrl;
input en;
begin
write_contol_register(MCONTR_TOP_0BIT_ADDR + MCONTR_TOP_0BIT_MCONTR_EN + en, 0);
end
endtask
task enable_memcntrl_channels;
input [15:0] chnen; // bit-per-channel, 1 - enable;
begin
write_contol_register(MCONTR_TOP_16BIT_ADDR + MCONTR_TOP_16BIT_CHN_EN, {16'b0,chnen});
end
endtask
task configure_channel_priority;
input [ 3:0] chn;
input [15:0] priority; // (higher is more important)
begin
write_contol_register(MCONTR_ARBIT_ADDR + chn, {16'b0,priority});
end
endtask
task enable_reset_ps_pio; // control reset and enable of the PS PIO channel;
input en;
input rst;
begin
write_contol_register(MCNTRL_PS_ADDR + MCNTRL_PS_EN_RST, {30'b0,en,~rst});
end end
endtask endtask
task schedule_ps_pio; // shedule software-control memory operation (may need to check FIFO status first)
input [9:0] seq_addr; // sequence start address
input [1:0] page; // buffer page number
input urgent; // high priority request (only for competion wityh other channels, wiil not pass in this FIFO)
input chn; // channel buffer to use: 0 - memory read, 1 - memory write
begin
write_contol_register(MCNTRL_PS_ADDR + MCNTRL_PS_CMD, {18'b0,chn,urgent,page,seq_addr});
end
endtask
task write_block_buf; task write_block_buf;
integer i, j; integer i, j;
...@@ -1219,8 +1276,8 @@ task set_refresh; ...@@ -1219,8 +1276,8 @@ task set_refresh;
data <= func_encode_skip( 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); data <= func_encode_skip( 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
@(posedge CLK) axi_write_single_w(cmd_addr, data); cmd_addr <= cmd_addr + 1; @(posedge CLK) axi_write_single_w(cmd_addr, data); cmd_addr <= cmd_addr + 1;
// write_contol_register(DLY_SET,0); // write_contol_register(DLY_SET,0);
write_contol_register(MCONTR_PHY_16BIT_ADDR + MCONTR_TOP_16BIT_REFRESH_ADDRESS, REFRESH_OFFSET); write_contol_register(MCONTR_TOP_16BIT_ADDR + MCONTR_TOP_16BIT_REFRESH_ADDRESS, REFRESH_OFFSET);
write_contol_register(MCONTR_PHY_16BIT_ADDR + MCONTR_TOP_16BIT_REFRESH_PERIOD, {24'h0,t_refi}); write_contol_register(MCONTR_TOP_16BIT_ADDR + MCONTR_TOP_16BIT_REFRESH_PERIOD, {24'h0,t_refi});
// enable refresh - should it be done here? // enable refresh - should it be done here?
// write_contol_register(MCONTR_PHY_0BIT_ADDR + MCONTR_TOP_0BIT_REFRESH_EN + 1, 0); // write_contol_register(MCONTR_PHY_0BIT_ADDR + MCONTR_TOP_0BIT_REFRESH_EN + 1, 0);
end end
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment