Commit ccbfbf84 authored by Andrey Filippov's avatar Andrey Filippov

Fixed some errors in old memory controller modules

parent acf82200
...@@ -62,42 +62,42 @@ ...@@ -62,42 +62,42 @@
<link> <link>
<name>vivado_logs/VivadoBitstream.log</name> <name>vivado_logs/VivadoBitstream.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393/vivado_logs/VivadoBitstream-20150909225646571.log</location> <location>/home/andrey/git/x393/vivado_logs/VivadoBitstream-20150912133316882.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoOpt.log</name> <name>vivado_logs/VivadoOpt.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393/vivado_logs/VivadoOpt-20150909225646571.log</location> <location>/home/andrey/git/x393/vivado_logs/VivadoOpt-20150912133316882.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoOptPhys.log</name> <name>vivado_logs/VivadoOptPhys.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393/vivado_logs/VivadoOptPhys-20150909225646571.log</location> <location>/home/andrey/git/x393/vivado_logs/VivadoOptPhys-20150912133316882.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoOptPower.log</name> <name>vivado_logs/VivadoOptPower.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393/vivado_logs/VivadoOptPower-20150909225646571.log</location> <location>/home/andrey/git/x393/vivado_logs/VivadoOptPower-20150912133316882.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoPlace.log</name> <name>vivado_logs/VivadoPlace.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393/vivado_logs/VivadoPlace-20150909225646571.log</location> <location>/home/andrey/git/x393/vivado_logs/VivadoPlace-20150912133316882.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoRoute.log</name> <name>vivado_logs/VivadoRoute.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393/vivado_logs/VivadoRoute-20150909225646571.log</location> <location>/home/andrey/git/x393/vivado_logs/VivadoRoute-20150912133316882.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoSynthesis.log</name> <name>vivado_logs/VivadoSynthesis.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393/vivado_logs/VivadoSynthesis-20150909224841524.log</location> <location>/home/andrey/git/x393/vivado_logs/VivadoSynthesis-20150912132805424.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoTimimgSummaryReportImplemented.log</name> <name>vivado_logs/VivadoTimimgSummaryReportImplemented.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393/vivado_logs/VivadoTimimgSummaryReportImplemented-20150909225646571.log</location> <location>/home/andrey/git/x393/vivado_logs/VivadoTimimgSummaryReportImplemented-20150912133316882.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoTimimgSummaryReportSynthesis.log</name> <name>vivado_logs/VivadoTimimgSummaryReportSynthesis.log</name>
......
com.elphel.store.context.iverilog=iverilog_81_TopModulesOther<-@\#\#@->iverilog_83_ExtraFiles<-@\#\#@->iverilog_88_ShowNoProblem<-@\#\#@->iverilog_77_Param_Exe<-@\#\#@->iverilog_78_VVP_Exe<-@\#\#@->iverilog_99_GrepFindErrWarn<-@\#\#@->iverilog_84_IncludeDir<-@\#\#@->iverilog_89_ShowNoProblem<-@\#\#@->iverilog_79_GtkWave_Exe<-@\#\#@->iverilog_98_GTKWaveSavFile<-@\#\#@->iverilog_100_TopModulesOther<-@\#\#@->iverilog_102_ExtraFiles<-@\#\#@->iverilog_103_IncludeDir<-@\#\#@->iverilog_101_TopModulesOther<-@\#\#@->iverilog_103_ExtraFiles<-@\#\#@->iverilog_104_IncludeDir<-@\#\#@->iverilog_113_SaveLogsSimulator<-@\#\#@->iverilog_109_ShowNoProblem<-@\#\#@->iverilog_110_ShowWarnings<-@\#\#@->iverilog_102_TopModulesOther<-@\#\#@->iverilog_104_ExtraFiles<-@\#\#@->iverilog_105_IncludeDir<-@\#\#@->iverilog_110_ShowNoProblem<-@\#\#@->iverilog_113_SaveLogsPreprocessor<-@\#\#@->iverilog_121_GrepFindErrWarn<-@\#\#@-> com.elphel.store.context.iverilog=iverilog_81_TopModulesOther<-@\#\#@->iverilog_83_ExtraFiles<-@\#\#@->iverilog_88_ShowNoProblem<-@\#\#@->iverilog_77_Param_Exe<-@\#\#@->iverilog_78_VVP_Exe<-@\#\#@->iverilog_99_GrepFindErrWarn<-@\#\#@->iverilog_84_IncludeDir<-@\#\#@->iverilog_89_ShowNoProblem<-@\#\#@->iverilog_79_GtkWave_Exe<-@\#\#@->iverilog_98_GTKWaveSavFile<-@\#\#@->iverilog_100_TopModulesOther<-@\#\#@->iverilog_102_ExtraFiles<-@\#\#@->iverilog_103_IncludeDir<-@\#\#@->iverilog_101_TopModulesOther<-@\#\#@->iverilog_103_ExtraFiles<-@\#\#@->iverilog_104_IncludeDir<-@\#\#@->iverilog_113_SaveLogsSimulator<-@\#\#@->iverilog_109_ShowNoProblem<-@\#\#@->iverilog_110_ShowWarnings<-@\#\#@->iverilog_102_TopModulesOther<-@\#\#@->iverilog_104_ExtraFiles<-@\#\#@->iverilog_105_IncludeDir<-@\#\#@->iverilog_110_ShowNoProblem<-@\#\#@->iverilog_113_SaveLogsPreprocessor<-@\#\#@->iverilog_121_GrepFindErrWarn<-@\#\#@->iverilog_114_SaveLogsSimulator<-@\#\#@->
eclipse.preferences.version=1 eclipse.preferences.version=1
iverilog_100_TopModulesOther=glbl<-@\#\#@-> iverilog_100_TopModulesOther=glbl<-@\#\#@->
iverilog_101_TopModulesOther=glbl<-@\#\#@-> iverilog_101_TopModulesOther=glbl<-@\#\#@->
...@@ -12,8 +12,9 @@ iverilog_105_IncludeDir=${verilog_project_loc}/includes<-@\#\#@->${verilog_proje ...@@ -12,8 +12,9 @@ iverilog_105_IncludeDir=${verilog_project_loc}/includes<-@\#\#@->${verilog_proje
iverilog_109_ShowNoProblem=true iverilog_109_ShowNoProblem=true
iverilog_110_ShowNoProblem=true iverilog_110_ShowNoProblem=true
iverilog_110_ShowWarnings=false iverilog_110_ShowWarnings=false
iverilog_113_SaveLogsPreprocessor=true iverilog_113_SaveLogsPreprocessor=false
iverilog_113_SaveLogsSimulator=true iverilog_113_SaveLogsSimulator=true
iverilog_114_SaveLogsSimulator=true
iverilog_121_GrepFindErrWarn=error|warning|sorry iverilog_121_GrepFindErrWarn=error|warning|sorry
iverilog_77_Param_Exe=/usr/local/bin/iverilog iverilog_77_Param_Exe=/usr/local/bin/iverilog
iverilog_78_VVP_Exe=/usr/local/bin/vvp iverilog_78_VVP_Exe=/usr/local/bin/vvp
......
...@@ -212,7 +212,16 @@ each group of 4 bits per channel : bits [1:0] - select, bit[2] - sset (0 - nop), ...@@ -212,7 +212,16 @@ each group of 4 bits per channel : bits [1:0] - select, bit[2] - sset (0 - nop),
// reg [1:0] wlen32; // 2 high bits of burst len (LSB are always 2'b11) // reg [1:0] wlen32; // 2 high bits of burst len (LSB are always 2'b11)
reg [3:0] wleft; // number of 64-bit words left to be sent - also used as awlen (valid @ awvalid) reg [3:0] wleft; // number of 64-bit words left to be sent - also used as awlen (valid @ awvalid)
reg [2:0] chunk_inc; // how much to increment chunk pointer (1..4) // reg [2:0] chunk_inc; // how much to increment chunk pointer (1..4)
// wire [2:0] pre_chunk_inc = (|counts_corr2[7:2])? // Would like to increment, if not roll-over
// 3'h4 :
// ({1'b0,left_to_eof[winner2 * 8 +: 2]} + 3'h1);
wire [1:0] pre_chunk_inc_m1 = (|counts_corr2[7:2])? // Would like to increment, if not roll-over
2'h3 :
left_to_eof[winner2 * 8 +: 2];
reg [ 3:0] reset_pointers; // per-channel - after chunk_start_hclk or chunk_len_hclk were written or explicit fifo_rst* reg [ 3:0] reset_pointers; // per-channel - after chunk_start_hclk or chunk_len_hclk were written or explicit fifo_rst*
...@@ -234,7 +243,8 @@ each group of 4 bits per channel : bits [1:0] - select, bit[2] - sset (0 - nop), ...@@ -234,7 +243,8 @@ each group of 4 bits per channel : bits [1:0] - select, bit[2] - sset (0 - nop),
reg [5:0] afi_awid_r; reg [5:0] afi_awid_r;
wire [2:0] max_wlen; // 0,1,2,3,7 (7 - not limited by rollover) - calculated by cmprs_afi_mux_ptr
wire [1:0] want_wleft32 = (|items_left[7:2])? 2'b11 : items_left[1:0]; // want to set wleft[3:2] if not roll-over
assign cmd_we_status_w = cmd_we && ((cmd_a & 'hc) == CMPRS_AFIMUX_STATUS_CNTRL); assign cmd_we_status_w = cmd_we && ((cmd_a & 'hc) == CMPRS_AFIMUX_STATUS_CNTRL);
assign cmd_we_mode_w = cmd_we && (cmd_a == CMPRS_AFIMUX_MODE); assign cmd_we_mode_w = cmd_we && (cmd_a == CMPRS_AFIMUX_MODE);
...@@ -416,7 +426,9 @@ each group of 4 bits per channel : bits [1:0] - select, bit[2] - sset (0 - nop), ...@@ -416,7 +426,9 @@ each group of 4 bits per channel : bits [1:0] - select, bit[2] - sset (0 - nop),
//pend_last //pend_last
if (!en) wleft <= 0; if (!en) wleft <= 0;
else if (pre_busy_w) wleft <= {(|items_left[7:2])? 2'b11 : items_left[1:0], 2'b11}; /// else if (pre_busy_w) wleft <= {(|items_left[7:2])? 2'b11 : items_left[1:0], 2'b11}; // @@@******* different for roll over
/// else if (pre_busy_w) wleft <= {(max_wlen[2] || (max_wlen[1:0] > want_wleft32))? want_wleft32 : max_wlen[1:0], 2'b11};
else if (pre_busy_w) wleft <= {(max_wlen[1:0] > want_wleft32) ? want_wleft32 : max_wlen[1:0], 2'b11};
else if (wleft != 0) wleft <= wleft - 1; else if (wleft != 0) wleft <= wleft - 1;
/* /*
counts_corr2[8] counts_corr2[8]
...@@ -456,9 +468,9 @@ items_left ...@@ -456,9 +468,9 @@ items_left
// wdata register mux // wdata register mux
if (wdata_en) wdata <= wdata_sel[1]?(wdata_sel[0]?fifo_rdata3:fifo_rdata2):(wdata_sel[0]?fifo_rdata1:fifo_rdata0); if (wdata_en) wdata <= wdata_sel[1]?(wdata_sel[0]?fifo_rdata3:fifo_rdata2):(wdata_sel[0]?fifo_rdata1:fifo_rdata0);
if (pre_busy_w) chunk_inc <= (|counts_corr2[7:2])? // if (pre_busy_w) chunk_inc <= (|counts_corr2[7:2])? // Would like to increment, if not roll-over
3'h4 : // 3'h4 :
({1'b0,left_to_eof[winner2 * 8 +: 2]} + 3'h1); // ({1'b0,left_to_eof[winner2 * 8 +: 2]} + 3'h1);
if (awvalid[0]) afi_awid_r <={1'b0,wleft[3:2],last_burst_in_frame,cur_chn}; if (awvalid[0]) afi_awid_r <={1'b0,wleft[3:2],last_burst_in_frame,cur_chn};
...@@ -517,13 +529,15 @@ items_left ...@@ -517,13 +529,15 @@ items_left
.pre_busy_w (pre_busy_w), // input .pre_busy_w (pre_busy_w), // input
.winner_channel (winner2), // input[1:0] .winner_channel (winner2), // input[1:0]
.need_to_bother (need_to_bother), // input .need_to_bother (need_to_bother), // input
.chunk_inc (chunk_inc), // input[2:0] // .chunk_inc (chunk_inc), // input[2:0]
.chunk_inc_want_m1 (pre_chunk_inc_m1), // input[1:0] Want to increment by this (0..3) + 1, if not roll over
.last_burst_in_frame (last_burst_in_frame), // input .last_burst_in_frame (last_burst_in_frame), // input
.busy (busy), // input[3:0] .busy (busy), // input[3:0]
.ptr_resetting (ptr_resetting), // output .ptr_resetting (ptr_resetting), // output
.chunk_addr (chunk_addr), // output[26:0] reg .chunk_addr (chunk_addr), // output[26:0] reg
.chunk_ptr_ra (chunk_ptr_ra[2:0]), // input[2:0] .chunk_ptr_ra (chunk_ptr_ra[2:0]), // input[2:0]
.chunk_ptr_rd (chunk_ptr_rd01[0 * 27 +: 27]) // output[26:0] .chunk_ptr_rd (chunk_ptr_rd01[0 * 27 +: 27]), // output[26:0]
.max_wlen (max_wlen) // output[2:0]: msb - no rollover (>3)
); );
assign chunk_ptr_rd=chunk_ptr_ra[3]?chunk_ptr_rd01[1 * 27 +: 27]:chunk_ptr_rd01[0 * 27 +: 27]; assign chunk_ptr_rd=chunk_ptr_ra[3]?chunk_ptr_rd01[1 * 27 +: 27]:chunk_ptr_rd01[0 * 27 +: 27];
cmprs_afi_mux_ptr_wresp cmprs_afi_mux_ptr_wresp_i ( cmprs_afi_mux_ptr_wresp cmprs_afi_mux_ptr_wresp_i (
......
...@@ -33,14 +33,17 @@ module cmprs_afi_mux_ptr( ...@@ -33,14 +33,17 @@ module cmprs_afi_mux_ptr(
input pre_busy_w, // combinatorial signal - one before busy[0] (depends on ptr_resetting) input pre_busy_w, // combinatorial signal - one before busy[0] (depends on ptr_resetting)
input [ 1:0] winner_channel, // channel that won arbitration for AXI access, valid @ pre_busy_w input [ 1:0] winner_channel, // channel that won arbitration for AXI access, valid @ pre_busy_w
input need_to_bother, // whants to start access if address and data FIFO permit input need_to_bother, // whants to start access if address and data FIFO permit
input [2:0] chunk_inc, // how much to increment chunk pointer (1..4) - valid witrh busy[0] input [1:0] chunk_inc_want_m1, // how much to increment chunk pointer (0..3) +1 - valid with busy[0] (w/o rollover)
input last_burst_in_frame, // valid with busy[0] (last_burst_in_frame<=last_chunk_w[winner2]) input last_burst_in_frame, // valid with busy[0] (last_burst_in_frame<=last_chunk_w[winner2])
input [ 3:0] busy, // one cycle less than sending 1-4 bursts, [1] - delayed by 1, [2] - by 2 input [ 3:0] busy, // one cycle less than sending 1-4 bursts, [1] - delayed by 1, [2] - by 2
output ptr_resetting, // pointers will be reset next cycle (2-cycle-long pulse) output ptr_resetting, // pointers will be reset next cycle (2-cycle-long pulse)
output reg [26:0] chunk_addr, // chunk absolute address, valid with busy[1] output reg [26:0] chunk_addr, // chunk absolute address, valid with busy[1]
input [ 2:0] chunk_ptr_ra, // chunk pointer read address {eof, chn[1:0]} input [ 2:0] chunk_ptr_ra, // chunk pointer read address {eof, chn[1:0]}
output [26:0] chunk_ptr_rd // chunk pointer read data (non-registered output [26:0] chunk_ptr_rd, // chunk pointer read data (non-registered
// output [ 2:0] max_inc // maximal increment to rollover (limited by 4)
output [ 2:0] max_wlen // maximal wlen[3:2], MSB - limited by rollover
); );
reg [3:0] reset_rq; // request to reset pointers when ready reg [3:0] reset_rq; // request to reset pointers when ready
reg [3:0] reset_rq_pri; // one-hot reset rq reg [3:0] reset_rq_pri; // one-hot reset rq
...@@ -53,21 +56,45 @@ module cmprs_afi_mux_ptr( ...@@ -53,21 +56,45 @@ module cmprs_afi_mux_ptr(
wire [26:0] ptr_ram_di; // data to be written to ptr_ram wire [26:0] ptr_ram_di; // data to be written to ptr_ram
reg [26:0] sa_len_ram[0:7]; // start chunk/num cunks in a buffer (write port @mclk) reg [26:0] sa_len_ram[0:7]; // start chunk/num cunks in a buffer (write port @mclk)
reg [26:0] chunk_ptr_inc; // incremented by 1..4 chunk pointer reg [26:0] chunk_ptr_inc; // incremented by 1..4 chunk pointer
reg [27:0] chunk_ptr_rovr; // incremented chunk pointer, decremented by length (MSB - sign) // reg [27:0] rollover_r; // incremented chunk pointer, decremented by length (MSB - sign)
reg en_d; //enable delayed by 1 cycle reg en_d; //enable delayed by 1 cycle
wire [ 2:0] sa_len_ra; // start/len read address (0..3 - start addresses, 4..7 - lengths) wire [ 2:0] sa_len_ra; // start/len read address (0..3 - start addresses, 4..7 - lengths)
reg [ 2:0] max_inc_ram[0:3]; // maximal increment to rollover (limited by 4)
wire [ 1:0] pre_chunk_inc_m1;
reg [ 2:0] chunk_inc;
wire [26:0] chunks_to_rollover;
reg [3:0] chunks_to_rollover_r; // [3] >=8
wire [3:0] chunks_to_rollover_m1;
reg max_inc_ram_we;
reg [1:0] max_inc_ram_wa;
wire rollover_w; // this cycle causes rollover - valid at pre_busy_w
reg rollover_r; // this cycle causes rollover - valid at busy[0] and late
wire ptr_ram_wa = ptr_ram[ptr_wa]; // SuppressThisWarning VEditor debug - just to view
assign ptr_resetting = resetting[0]; assign ptr_resetting = resetting[0];
assign sa_len_ra= {busy[1],ptr_wa[1:0]}; assign sa_len_ra= {busy[1],ptr_wa[1:0]};
assign reset_rq_enc = {reset_rq_pri[3] | reset_rq_pri[2], assign reset_rq_enc = {reset_rq_pri[3] | reset_rq_pri[2],
reset_rq_pri[3] | reset_rq_pri[1]}; reset_rq_pri[3] | reset_rq_pri[1]};
assign ptr_ram_di= resetting[1] ? 27'b0 : (chunk_ptr_rovr[27] ? chunk_ptr_inc : chunk_ptr_rovr[26:0]); // assign ptr_ram_di= resetting[1] ? 27'b0 : (chunk_ptr_rovr[27] ? chunk_ptr_inc : chunk_ptr_rovr[26:0]);
assign ptr_ram_di= (resetting[1] ||rollover_r) ? 27'b0 : chunk_ptr_inc ;
assign chunk_ptr_rd = ptr_ram[chunk_ptr_ra]; assign chunk_ptr_rd = ptr_ram[chunk_ptr_ra];
assign start_resetting_w = en && !busy[0] && !resetting[0] && (|reset_rq) && !need_to_bother; assign start_resetting_w = en && !busy[0] && !resetting[0] && (|reset_rq) && !need_to_bother;
// assign max_inc = max_inc_ram[winner_channel];
assign max_wlen = max_inc_ram[winner_channel]; // valid @pre_busy_w
//chunk_inc_want_m1
assign pre_chunk_inc_m1 = (max_wlen[1:0] >= chunk_inc_want_m1)? chunk_inc_want_m1 : max_wlen[1:0];
assign rollover_w = !max_wlen[2] && (max_wlen[1:0] <= chunk_inc_want_m1);
assign chunks_to_rollover = sa_len_ram[sa_len_ra] - ptr_ram_di;
assign chunks_to_rollover_m1 = chunks_to_rollover_r -1;
always @ (posedge hclk) begin always @ (posedge hclk) begin
en_d <= en; en_d <= en;
// ===== calculate and rollover channel addresses ==== // ===== calculate and rollover channel addresses ====
...@@ -103,11 +130,25 @@ module cmprs_afi_mux_ptr( ...@@ -103,11 +130,25 @@ module cmprs_afi_mux_ptr(
chunk_addr <= ptr_ram[ptr_wa] + sa_len_ram[sa_len_ra]; chunk_addr <= ptr_ram[ptr_wa] + sa_len_ram[sa_len_ra];
chunk_ptr_inc <= ptr_ram[ptr_wa] + chunk_inc; chunk_ptr_inc <= ptr_ram[ptr_wa] + chunk_inc;
end end
if (busy[1] && !busy[2]) begin // first clock of busy // if (busy[1] && !busy[2]) begin // first clock of busy
chunk_ptr_rovr <={1'b0,chunk_ptr_inc} - {1'b0,sa_len_ram[sa_len_ra]}; // sa_len_ra now points at length // chunk_ptr_rovr <={1'b0,chunk_ptr_inc} - {1'b0,sa_len_ram[sa_len_ra]}; // sa_len_ra now points at length
end // end
// write to ptr_ram (1 or 2 locations - if eof) // write to ptr_ram (1 or 2 locations - if eof)
if (ptr_we) ptr_ram[ptr_wa] <= ptr_ram_di; if (ptr_we) ptr_ram[ptr_wa] <= ptr_ram_di;
if (pre_busy_w) chunk_inc <= {1'b0, pre_chunk_inc_m1} + 1;
if (pre_busy_w) rollover_r <= rollover_w;
// wire [26:0] chunks_to_rollover;
// reg [3:0] chunks_to_rollover_r; // [3] >=8
if (ptr_we) chunks_to_rollover_r <= {|chunks_to_rollover[26:3],chunks_to_rollover[2:0]};
max_inc_ram_we <= ptr_we & ~ptr_wa[2];
max_inc_ram_wa <= ptr_wa[1:0];
if (max_inc_ram_we) max_inc_ram[max_inc_ram_wa] <= (|chunks_to_rollover_m1[3:2])?3'h7:{1'b0,chunks_to_rollover_m1[1:0]};
end end
endmodule endmodule
......
...@@ -54,10 +54,11 @@ module cmprs_afi_mux_ptr_wresp( ...@@ -54,10 +54,11 @@ module cmprs_afi_mux_ptr_wresp(
reg [26:0] len_ram[0:3]; // start chunk/num cunks in a buffer (write port @mclk) reg [26:0] len_ram[0:3]; // start chunk/num cunks in a buffer (write port @mclk)
reg [26:0] chunk_ptr_inc; // incremented by 1..4 chunk pointer reg [26:0] chunk_ptr_inc; // incremented by 1..4 chunk pointer
reg [27:0] chunk_ptr_rovr; // incremented chunk pointer, decremented by length (MSB - sign) reg [27:0] chunk_ptr_rovr; // incremented chunk pointer, decremented by length (MSB - sign)
reg [ 3:0] busy; // one-hot busy stages (usually end with [3] /// reg [ 3:0] busy; // one-hot busy stages (usually end with [3]
// reg [ 5:0] id_r; // registered ID data reg [ 4:0] busy; // one-hot busy stages (usually end with [4]
reg [ 4:0] id_r; // registered ID data - MSB is unused reg [ 4:0] id_r; // registered ID data - MSB is unused
reg [1:0] chn; // selected channel reg [1:0] chn; // selected channel valid @busy[2]
reg eof; // eof register being written reg eof; // eof register being written
reg last_burst_in_frame; // this response is for eof reg last_burst_in_frame; // this response is for eof
reg [2:0] chunk_inc; reg [2:0] chunk_inc;
...@@ -71,14 +72,19 @@ module cmprs_afi_mux_ptr_wresp( ...@@ -71,14 +72,19 @@ module cmprs_afi_mux_ptr_wresp(
reset_rq_pri[3] | reset_rq_pri[1]}; reset_rq_pri[3] | reset_rq_pri[1]};
assign ptr_ram_di= resetting[1] ? 27'b0 : (chunk_ptr_rovr[27] ? chunk_ptr_inc : chunk_ptr_rovr[26:0]); assign ptr_ram_di= resetting[1] ? 27'b0 : (chunk_ptr_rovr[27] ? chunk_ptr_inc : chunk_ptr_rovr[26:0]);
assign ptr_wa = {eof,chn}; assign ptr_wa = {eof,chn}; // valid @busy[2]
assign afi_bready = afi_bready_r; assign afi_bready = afi_bready_r;
/// assign pre_we= resetting[0] || // a pair of cycles to reset chunk pointer and frame chunk pointer
/// busy[2] || // always update chunk pointer
/// (busy[3] && last_burst_in_frame); // optionally update frame chunk pointer (same value)
assign pre_we= resetting[0] || // a pair of cycles to reset chunk pointer and frame chunk pointer assign pre_we= resetting[0] || // a pair of cycles to reset chunk pointer and frame chunk pointer
busy[2] || // always update chunk pointer busy[3] || // always update chunk pointer
(busy[3] && last_burst_in_frame); // optionally update frame chunk pointer (same value) (busy[4] && last_burst_in_frame); // optionally update frame chunk pointer (same value)
assign pre_busy= afi_bvalid_r && en && !(|busy[1:0]) && !pre_we; /// assign pre_busy= afi_bvalid_r && en && !(|busy[1:0]) && !pre_we;
assign start_resetting_w = !afi_bvalid_r && en && !(|busy[1:0]) && !pre_we && (|reset_rq); /// assign start_resetting_w = !afi_bvalid_r && en && !(|busy[1:0]) && !pre_we && (|reset_rq);
assign pre_busy= afi_bvalid_r && en && !(|busy[2:0]) && !pre_we;
assign start_resetting_w = !afi_bvalid_r && en && !(|busy[2:0]) && !pre_we && (|reset_rq);
assign chunk_ptr_rd = ptr_ram[chunk_ptr_ra]; assign chunk_ptr_rd = ptr_ram[chunk_ptr_ra];
...@@ -89,10 +95,11 @@ module cmprs_afi_mux_ptr_wresp( ...@@ -89,10 +95,11 @@ module cmprs_afi_mux_ptr_wresp(
afi_bvalid_r <= afi_bvalid; afi_bvalid_r <= afi_bvalid;
afi_bready_r <= !en || pre_busy; // (!busy[0] && !pre_busy && !resetting[0] && !start_resetting_w); afi_bready_r <= !en || pre_busy; // (!busy[0] && !pre_busy && !resetting[0] && !start_resetting_w);
busy <= {busy[2:0], pre_busy}; // adjust bits // busy <= {busy[2:0], pre_busy}; // adjust bits
busy <= {busy[3:0], pre_busy}; // adjust bits
// id_r <= afi_bid; // id_r <= afi_bid[4:0]; // id_r[5] is never used - revoved
id_r <= afi_bid[4:0]; // id_r[5] is never used - revoved if (afi_bready && afi_bvalid) id_r <= afi_bid[4:0]; // id_r[5] is never used - revoved
if (start_resetting_w) reset_rq_pri <= {reset_rq[3] & ~(|reset_rq[2:0]), if (start_resetting_w) reset_rq_pri <= {reset_rq[3] & ~(|reset_rq[2:0]),
reset_rq[2] & ~(|reset_rq[1:0]), reset_rq[2] & ~(|reset_rq[1:0]),
...@@ -106,9 +113,11 @@ module cmprs_afi_mux_ptr_wresp( ...@@ -106,9 +113,11 @@ module cmprs_afi_mux_ptr_wresp(
else resetting <= {resetting[0], start_resetting_w | (resetting[0] & ~resetting[1])}; else resetting <= {resetting[0], start_resetting_w | (resetting[0] & ~resetting[1])};
if (resetting == 2'b01) chn <= reset_rq_enc; if (resetting == 2'b01) chn <= reset_rq_enc;
else if (busy[0]) chn <= id_r[0 +: 2]; /// else if (busy[0]) chn <= id_r[0 +: 2];
else if (busy[1]) chn <= id_r[0 +: 2];
if (busy[0]) begin // first busy cycle /// if (busy[0]) begin // first busy cycle
if (busy[1]) begin // first busy cycle
last_burst_in_frame <= id_r[2]; last_burst_in_frame <= id_r[2];
chunk_inc <= {1'b0,id_r[3 +:2]} + 1; chunk_inc <= {1'b0,id_r[3 +:2]} + 1;
end end
...@@ -118,10 +127,11 @@ module cmprs_afi_mux_ptr_wresp( ...@@ -118,10 +127,11 @@ module cmprs_afi_mux_ptr_wresp(
if ((resetting == 2'b01) || busy[0]) eof <= 0; if ((resetting == 2'b01) || busy[0]) eof <= 0;
else if (ptr_we) eof <= 1; // always second write cycle else if (ptr_we) eof <= 1; // always second write cycle
// @@@ delay by 1 clk
if (busy[1]) chunk_ptr_inc <= ptr_ram[ptr_wa] + chunk_inc; // second clock of busy /// if (busy[1]) chunk_ptr_inc <= ptr_ram[ptr_wa] + chunk_inc; // second clock of busy
/// if (busy[2]) chunk_ptr_rovr <={1'b0,chunk_ptr_inc} - {1'b0,len_ram[chn]}; // third clock of busy
if (busy[2]) chunk_ptr_rovr <={1'b0,chunk_ptr_inc} - {1'b0,len_ram[chn]}; // third clock of busy if (busy[2]) chunk_ptr_inc <= ptr_ram[ptr_wa] + chunk_inc; // second clock of busy
if (busy[3]) chunk_ptr_rovr <={1'b0,chunk_ptr_inc} - {1'b0,len_ram[chn]}; // third clock of busy
// write to ptr_ram (1 or 2 locations - if eof) // write to ptr_ram (1 or 2 locations - if eof)
if (ptr_we) ptr_ram[ptr_wa] <= ptr_ram_di; if (ptr_we) ptr_ram[ptr_wa] <= ptr_ram_di;
......
...@@ -78,9 +78,13 @@ module cmprs_afi_mux_status #( ...@@ -78,9 +78,13 @@ module cmprs_afi_mux_status #(
if (mode_data_mclk[ 6]) mode_hclk[3:2] <= mode_data_mclk[ 5: 4]; if (mode_data_mclk[ 6]) mode_hclk[3:2] <= mode_data_mclk[ 5: 4];
if (mode_data_mclk[10]) mode_hclk[5:4] <= mode_data_mclk[ 9: 8]; if (mode_data_mclk[10]) mode_hclk[5:4] <= mode_data_mclk[ 9: 8];
if (mode_data_mclk[14]) mode_hclk[7:6] <= mode_data_mclk[13:12]; if (mode_data_mclk[14]) mode_hclk[7:6] <= mode_data_mclk[13:12];
if (stb_mclk) status_data[chunk_chn_hclk * CMPRS_AFIMUX_WIDTH +: CMPRS_AFIMUX_WIDTH] <= chunk_ptr_hclk;
end end
if (stb_mclk) status_data[chunk_chn_hclk * CMPRS_AFIMUX_WIDTH +: CMPRS_AFIMUX_WIDTH] <= chunk_ptr_hclk;
// if (stb_mclk && (chunk_chn_hclk == 2'h0)) status_data[0 * CMPRS_AFIMUX_WIDTH +: CMPRS_AFIMUX_WIDTH] <= chunk_ptr_hclk;
// if (stb_mclk && (chunk_chn_hclk == 2'h1)) status_data[1 * CMPRS_AFIMUX_WIDTH +: CMPRS_AFIMUX_WIDTH] <= chunk_ptr_hclk;
// if (stb_mclk && (chunk_chn_hclk == 2'h2)) status_data[2 * CMPRS_AFIMUX_WIDTH +: CMPRS_AFIMUX_WIDTH] <= chunk_ptr_hclk;
// if (stb_mclk && (chunk_chn_hclk == 2'h3)) status_data[3 * CMPRS_AFIMUX_WIDTH +: CMPRS_AFIMUX_WIDTH] <= chunk_ptr_hclk;
if (!en) {index,cntr} <= 0; if (!en) {index,cntr} <= 0;
else {index,cntr} <= {index,cntr} + 1; else {index,cntr} <= {index,cntr} + 1;
......
...@@ -30,11 +30,14 @@ module membridge#( ...@@ -30,11 +30,14 @@ module membridge#(
parameter MEMBRIDGE_START64= 'h4, // start address relative to lo_addr parameter MEMBRIDGE_START64= 'h4, // start address relative to lo_addr
parameter MEMBRIDGE_LEN64= 'h5, // full length of transfer in 64-bit words parameter MEMBRIDGE_LEN64= 'h5, // full length of transfer in 64-bit words
parameter MEMBRIDGE_WIDTH64= 'h6, // frame width in 64-bit words (partial last page in each line) parameter MEMBRIDGE_WIDTH64= 'h6, // frame width in 64-bit words (partial last page in each line)
parameter MEMBRIDGE_MODE= 'h7, // frame width in 64-bit words (partial last page in each line) parameter MEMBRIDGE_MODE= 'h7, // bits [3:0] - *_cache, bit [4] - cache debug
parameter MEMBRIDGE_STATUS_REG= 'h3b, parameter MEMBRIDGE_STATUS_REG= 'h3b,
parameter FRAME_HEIGHT_BITS= 16, // Maximal frame height bits parameter FRAME_HEIGHT_BITS= 16, // Maximal frame height bits
parameter FRAME_WIDTH_BITS= 13 parameter FRAME_WIDTH_BITS= 13
// ,parameter MCNTRL_SCANLINE_FRAME_PAGE_RESET= 1'b0 // reset internal page number to zero at the frame start (false - only when hard/soft reset) // ,parameter MCNTRL_SCANLINE_FRAME_PAGE_RESET= 1'b0 // reset internal page number to zero at the frame start (false - only when hard/soft reset)
`ifdef DEBUG_RING
,parameter DEBUG_CMD_LATENCY = 2
`endif
)( )(
// input rst, // input rst,
...@@ -120,6 +123,11 @@ module membridge#( ...@@ -120,6 +123,11 @@ module membridge#(
input [ 7:0] afi_rcount, input [ 7:0] afi_rcount,
input [ 2:0] afi_racount, input [ 2:0] afi_racount,
output afi_rdissuecap1en output afi_rdissuecap1en
`ifdef DEBUG_RING
,output debug_do, // output to the debug ring
input debug_sl, // 0 - idle, (1,0) - shift, (1,1) - load // SuppressThisWarning VEditor - not used
input debug_di // input from the debug ring
`endif
); );
localparam BUFWR_WE_WIDTH = 4; //2; // 4; localparam BUFWR_WE_WIDTH = 4; //2; // 4;
...@@ -262,7 +270,7 @@ module membridge#( ...@@ -262,7 +270,7 @@ module membridge#(
reg next_page_wr; reg next_page_wr;
wire next_page; // @ posedge hclk - source wire next_page; // @ posedge hclk - source
wire busy_next_page; // do not send next_page -previous is crossing clock boundaries // wire busy_next_page; // do not send next_page -previous is crossing clock boundaries
assign next_page= next_page_wr | next_page_rd; assign next_page= next_page_wr | next_page_rd;
...@@ -332,7 +340,20 @@ module membridge#( ...@@ -332,7 +340,20 @@ module membridge#(
pulse_cross_clock reset_page_rd_i (.rst(mrstn), .src_clk(~mclk),.dst_clk(hclk), .in_pulse(xfer_reset_page_rd), .out_pulse(reset_page_rd),.busy()); pulse_cross_clock reset_page_rd_i (.rst(mrstn), .src_clk(~mclk),.dst_clk(hclk), .in_pulse(xfer_reset_page_rd), .out_pulse(reset_page_rd),.busy());
// hclk -> mclk // hclk -> mclk
pulse_cross_clock next_page_i (.rst(hrst), .src_clk(hclk), .dst_clk(mclk), .in_pulse(next_page), .out_pulse(next_page_chn),.busy(busy_next_page)); // pulse_cross_clock next_page_i (.rst(hrst), .src_clk(hclk), .dst_clk(mclk), .in_pulse(next_page), .out_pulse(next_page_chn),.busy(busy_next_page));
elastic_cross_clock #(
.WIDTH(2),
.EXTRA_DLY(0)
) elastic_cross_clock_i (
.rst (hrst), // input
.src_clk (hclk), // input
.dst_clk (mclk), // input
.in_pulses (next_page), // input
.out_pulse (next_page_chn), // output
.busy () // output
);
// Common to both directions // Common to both directions
localparam DELAY_ADVANCE_ADDR=3; localparam DELAY_ADVANCE_ADDR=3;
...@@ -523,7 +544,8 @@ module membridge#( ...@@ -523,7 +544,8 @@ module membridge#(
wire is_last_in_page; wire is_last_in_page;
wire next_page_rd_w; wire next_page_rd_w;
wire next_page_wr_w; wire next_page_wr_w;
assign next_page_rd_w = read_started && !busy_next_page && is_last_in_page && bufrd_rd[0]; // assign next_page_rd_w = read_started && !busy_next_page && is_last_in_page && bufrd_rd[0];
assign next_page_rd_w = read_started && is_last_in_page && bufrd_rd[0];
assign is_last_in_line = buf_in_line64 == last_in_line64; assign is_last_in_line = buf_in_line64 == last_in_line64;
assign is_last_in_page = is_last_in_line || (&buf_in_line64[6:0]); assign is_last_in_page = is_last_in_line || (&buf_in_line64[6:0]);
`ifdef MEMBRIDGE_DEBUG_READ `ifdef MEMBRIDGE_DEBUG_READ
...@@ -577,7 +599,8 @@ module membridge#( ...@@ -577,7 +599,8 @@ module membridge#(
assign advance_rel_addr_rd = write_busy && afi_ra_safe_not_full && afi_safe_rd_pending && (|left64); assign advance_rel_addr_rd = write_busy && afi_ra_safe_not_full && afi_safe_rd_pending && (|left64);
assign afi_arvalid=advance_rel_addr && write_busy; assign afi_arvalid=advance_rel_addr && write_busy;
assign next_page_wr_w = write_busy && !busy_next_page && is_last_in_page && bufwr_we[0]; // assign next_page_wr_w = write_busy && !busy_next_page && is_last_in_page && bufwr_we[0];
assign next_page_wr_w = write_busy && is_last_in_page && bufwr_we[0];
assign bufwr_we_w= afi_rd_safe_not_empty && !write_pages_ready[2] && (!(&write_pages_ready[1:0]) || !is_last_in_page); assign bufwr_we_w= afi_rd_safe_not_empty && !write_pages_ready[2] && (!(&write_pages_ready[1:0]) || !is_last_in_page);
...@@ -631,12 +654,24 @@ module membridge#( ...@@ -631,12 +654,24 @@ module membridge#(
else if (!page_ready_wr && next_page_wr_w) write_pages_ready <= write_pages_ready +1; //-1; else if (!page_ready_wr && next_page_wr_w) write_pages_ready <= write_pages_ready +1; //-1;
end end
`ifdef MEMBRIDGE_DEBUG_WRITE
reg [30:0] dbg_read_counter;
always @ (posedge hclk) begin
if (!write_busy ) dbg_read_counter <= 0;
else if (bufwr_we[0]) dbg_read_counter <= dbg_read_counter + 1;
end
`endif
reg [63:0] rdata_r; reg [63:0] rdata_r;
always @ (posedge hclk) begin always @ (posedge hclk) begin
write_page_r <= write_page; write_page_r <= write_page;
buf_in_line64_r <= buf_in_line64[6:0]; buf_in_line64_r <= buf_in_line64[6:0];
// rdata_r <= afi_rdata; // rdata_r <= afi_rdata;
`ifdef MEMBRIDGE_DEBUG_WRITE
rdata_r <= cache_debug?{dbg_read_counter,1'h1,dbg_read_counter,1'h0}:afi_rdata[63:0]; // debugging
`else
rdata_r <= cache_debug?{wr_id[3:0],2'b0,write_page_r[1:0],afi_rcount[7:0],afi_rdata[47:0]}:afi_rdata[63:0]; // debugging rdata_r <= cache_debug?{wr_id[3:0],2'b0,write_page_r[1:0],afi_rcount[7:0],afi_rdata[47:0]}:afi_rdata[63:0]; // debugging
`endif
end end
cmd_deser #( cmd_deser #(
...@@ -680,6 +715,19 @@ module membridge#( ...@@ -680,6 +715,19 @@ module membridge#(
); );
// Port 1rd (read DDR to AFI) buffer, linear // Port 1rd (read DDR to AFI) buffer, linear
wire [63:0] afi_wdata0;
`ifdef MEMBRIDGE_DEBUG_WRITE
reg [15:0] dbg_write_counter;
always @ (posedge hclk) begin
if (!read_busy || !cache_debug) dbg_write_counter <= 0;
else if (bufrd_rd[1]) dbg_write_counter <= dbg_write_counter + 1;
end
assign afi_wdata = {afi_wdata0[63:16], dbg_write_counter[0]? dbg_write_counter[15:0]: afi_wdata0[15:0]};
`else
assign afi_wdata = afi_wdata0;
`endif
mcntrl_buf_rd #( mcntrl_buf_rd #(
.LOG2WIDTH_RD(6) // 64 bit external interface .LOG2WIDTH_RD(6) // 64 bit external interface
) chn1rd_buf_i ( ) chn1rd_buf_i (
...@@ -687,7 +735,7 @@ module membridge#( ...@@ -687,7 +735,7 @@ module membridge#(
.ext_raddr ({read_page,buf_in_line64[6:0]}), // input[8:0] .ext_raddr ({read_page,buf_in_line64[6:0]}), // input[8:0]
.ext_rd (bufrd_rd[0]), // input .ext_rd (bufrd_rd[0]), // input
.ext_regen (bufrd_rd[1]), // input .ext_regen (bufrd_rd[1]), // input
.ext_data_out (afi_wdata), // output[63:0] .ext_data_out (afi_wdata0), // output[63:0]
.wclk (!mclk), // input .wclk (!mclk), // input
.wpage_in (2'b0), // input[1:0] .wpage_in (2'b0), // input[1:0]
.wpage_set (xfer_reset_page_rd), // input TODO: Generate @ negedge mclk on frame start .wpage_set (xfer_reset_page_rd), // input TODO: Generate @ negedge mclk on frame start
...@@ -714,5 +762,28 @@ module membridge#( ...@@ -714,5 +762,28 @@ module membridge#(
.data_out (buf_rdata) // output[63:0] .data_out (buf_rdata) // output[63:0]
); );
`ifdef DEBUG_RING
debug_slave #(
.SHIFT_WIDTH (32),
.READ_WIDTH (32),
.WRITE_WIDTH (32),
.DEBUG_CMD_LATENCY (DEBUG_CMD_LATENCY)
) debug_slave_i (
.mclk (mclk), // input
.mrst (mrst), // input
.debug_di (debug_di), // input
.debug_sl (debug_sl), // input
.debug_do (debug_do), // output
.rd_data ({
5'b0, afi_racount[2:0],
afi_rcount[7:0],
2'b0, afi_wacount[5:0],
afi_wcount[7:0]
}), // input[31:0]
.wr_data (), // output[31:0] - not used
.stb () // output - not used
);
`endif
endmodule endmodule
...@@ -261,7 +261,8 @@ module cmprs_cmd_decode#( ...@@ -261,7 +261,8 @@ module cmprs_cmd_decode#(
else if (ctrl_we_r && di_r[CMPRS_CBIT_RUN]) cmprs_run_mclk <= (di_r[CMPRS_CBIT_RUN-1 -:CMPRS_CBIT_RUN_BITS] == CMPRS_CBIT_RUN_ENABLE); else if (ctrl_we_r && di_r[CMPRS_CBIT_RUN]) cmprs_run_mclk <= (di_r[CMPRS_CBIT_RUN-1 -:CMPRS_CBIT_RUN_BITS] == CMPRS_CBIT_RUN_ENABLE);
if (mrst) cmprs_standalone <= 0; if (mrst) cmprs_standalone <= 0;
else if (ctrl_we_r) cmprs_standalone <= ctrl_we_r && di_r[CMPRS_CBIT_RUN] && (di_r[CMPRS_CBIT_RUN-1 -:CMPRS_CBIT_RUN_BITS] == CMPRS_CBIT_RUN_STANDALONE); // else if (ctrl_we_r) cmprs_standalone <= ctrl_we_r && di_r[CMPRS_CBIT_RUN] && (di_r[CMPRS_CBIT_RUN-1 -:CMPRS_CBIT_RUN_BITS] == CMPRS_CBIT_RUN_STANDALONE);
else cmprs_standalone <= ctrl_we_r && di_r[CMPRS_CBIT_RUN] && (di_r[CMPRS_CBIT_RUN-1 -:CMPRS_CBIT_RUN_BITS] == CMPRS_CBIT_RUN_STANDALONE);
if (mrst) sigle_frame_buf <= 0; if (mrst) sigle_frame_buf <= 0;
else if (ctrl_we_r && di_r[CMPRS_CBIT_FRAMES]) sigle_frame_buf <= (di_r[CMPRS_CBIT_FRAMES-1 -:CMPRS_CBIT_FRAMES_BITS] == CMPRS_CBIT_FRAMES_SINGLE); else if (ctrl_we_r && di_r[CMPRS_CBIT_FRAMES]) sigle_frame_buf <= (di_r[CMPRS_CBIT_FRAMES-1 -:CMPRS_CBIT_FRAMES_BITS] == CMPRS_CBIT_FRAMES_SINGLE);
......
parameter FPGA_VERSION = 32'h03930021; parameter FPGA_VERSION = 32'h03930029;
\ No newline at end of file \ No newline at end of file
...@@ -124,6 +124,9 @@ task test_afi_rw; // SuppressThisWarning VEditor - may be unused ...@@ -124,6 +124,9 @@ task test_afi_rw; // SuppressThisWarning VEditor - may be unused
input [28:0] lo_addr64; // low address of the system memory range, in 64-bit words input [28:0] lo_addr64; // low address of the system memory range, in 64-bit words
input [28:0] size64; // size of the system memory range in 64-bit words input [28:0] size64; // size of the system memory range in 64-bit words
input continue; // 0 start from start64, 1 - continue from where it was input continue; // 0 start from start64, 1 - continue from where it was
input disable_need;
input [4:0] cache_mode; // 'h3 - normal, 'h13 - debug
// ----------------------------------------- // -----------------------------------------
integer mode; integer mode;
...@@ -135,7 +138,7 @@ task test_afi_rw; // SuppressThisWarning VEditor - may be unused ...@@ -135,7 +138,7 @@ task test_afi_rw; // SuppressThisWarning VEditor - may be unused
reg reset_frame; reg reset_frame;
reg disable_need; reg disable_need;
begin begin
disable_need = 1'b0; // disable_need = 1'b0;
repetitive = 1'b1; repetitive = 1'b1;
single = 1'b0;