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; single = 1'b0;
reset_frame = 1'b0; reset_frame = 1'b0;
...@@ -169,7 +172,8 @@ task test_afi_rw; // SuppressThisWarning VEditor - may be unused ...@@ -169,7 +172,8 @@ task test_afi_rw; // SuppressThisWarning VEditor - may be unused
(window_width[12:0]==0)? 29'h4000 : {15'b0,window_width[12:0],1'b0}, // width64, (window_width[12:0]==0)? 29'h4000 : {15'b0,window_width[12:0],1'b0}, // width64,
start64, start64,
lo_addr64, lo_addr64,
size64); size64,
cache_mode);
membridge_start (continue); membridge_start (continue);
`ifdef MEMBRIDGE_DEBUG_READ `ifdef MEMBRIDGE_DEBUG_READ
// debugging // debugging
......
...@@ -25,13 +25,14 @@ ...@@ -25,13 +25,14 @@
input [28:0] start64; // relative start address of the transfer (set to 0 when writing lo_addr64) input [28:0] start64; // relative start address of the transfer (set to 0 when writing lo_addr64)
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 [4:0] mode;
begin begin
write_contol_register(MEMBRIDGE_ADDR + MEMBRIDGE_LO_ADDR64, {3'b0,lo_addr64}); write_contol_register(MEMBRIDGE_ADDR + MEMBRIDGE_LO_ADDR64, {3'b0,lo_addr64});
write_contol_register(MEMBRIDGE_ADDR + MEMBRIDGE_SIZE64, {3'b0,size64}); write_contol_register(MEMBRIDGE_ADDR + MEMBRIDGE_SIZE64, {3'b0,size64});
write_contol_register(MEMBRIDGE_ADDR + MEMBRIDGE_START64, {3'b0,start64}); write_contol_register(MEMBRIDGE_ADDR + MEMBRIDGE_START64, {3'b0,start64});
write_contol_register(MEMBRIDGE_ADDR + MEMBRIDGE_LEN64, {3'b0,len64}); write_contol_register(MEMBRIDGE_ADDR + MEMBRIDGE_LEN64, {3'b0,len64});
write_contol_register(MEMBRIDGE_ADDR + MEMBRIDGE_WIDTH64, {3'b0,width64}); write_contol_register(MEMBRIDGE_ADDR + MEMBRIDGE_WIDTH64, {3'b0,width64});
write_contol_register(MEMBRIDGE_ADDR + MEMBRIDGE_MODE, {27'b0,mode});
end end
endtask endtask
......
...@@ -98,7 +98,9 @@ module cmd_encod_linear_rd #( ...@@ -98,7 +98,9 @@ module cmd_encod_linear_rd #(
if (mrst) gen_addr <= 0; if (mrst) gen_addr <= 0;
else if (!start && !gen_run) gen_addr <= 0; else if (!start && !gen_run) gen_addr <= 0;
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-1)) && (num128[NUM_XFER_BITS-1:1]==0)) gen_addr <= REPEAT_ADDR+1; // skip loop alltogeter
// AF 2015/09/12 : num128[NUM_XFER_BITS-1:0] == 0 for the full 64-bursts!
else if ((gen_addr==(REPEAT_ADDR-1)) && (num128[NUM_XFER_BITS-1:0] == 1)) 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 else if ((gen_addr !=REPEAT_ADDR) || (num128[NUM_XFER_BITS-1:1]==0)) gen_addr <= gen_addr+1; // not in a loop
//counting loops? //counting loops?
if (mrst) num128 <= 0; if (mrst) num128 <= 0;
......
This diff is collapsed.
...@@ -345,6 +345,8 @@ class X393Jpeg(object): ...@@ -345,6 +345,8 @@ class X393Jpeg(object):
code <<= 1 code <<= 1
si += 1 si += 1
return hcodes return hcodes
def jpegheader_create (self, def jpegheader_create (self,
y_quality = 80, y_quality = 80,
c_quality = None, c_quality = None,
...@@ -561,7 +563,44 @@ class X393Jpeg(object): ...@@ -561,7 +563,44 @@ class X393Jpeg(object):
print("\nNumber of bytes that differ = %d"%(diffs)) print("\nNumber of bytes that differ = %d"%(diffs))
return {"header":buf, return {"header":buf,
"quantization":qtables["fpga"], "quantization":qtables["fpga"],
"huffman": self.huff_tables[FPGA_HUFFMAN_TABLE]} "huffman": self.huff_tables[FPGA_HUFFMAN_TABLE]}
def jpegheader_write (self,
file_path = "jpeg",
y_quality = 80,
c_quality = None,
portrait = False,
height = 1944,
width = 2592,
color_mode = 0,
byrshift = 0,
verbose = 1):
"""
Create JPEG file header and trailer
@param file_path - file system path (will create two files *.head and *.tail
@param y_quality - 1..100 - quantization quality for Y component
@param c_quality - 1..100 - quantization quality for color components (None - use y_quality)
@param portrait - False - use normal order, True - transpose for portrait mode images
@param height - image height, pixels
@param width - image width, pixels
@param color_mode - one of the image formats (jpeg, jp4,)
@param byrshift - Bayer shift
@param verbose - verbose level
"""
jpeg_data = self.jpegheader_create (
y_quality = y_quality,
c_quality = c_quality,
portrait = portrait,
height = height,
width = width,
color_mode = color_mode,
byrshift = byrshift,
verbose = verbose - 1)
with open(file_path+".head", "w+b") as sf:
sf.write(jpeg_data["header"])
with open(file_path+".tail", "w+b") as sf:
sf.write(bytearray((0xff,0xd9)))
def jpeg_header_353 (self): def jpeg_header_353 (self):
return bytearray(( return bytearray((
0xfe, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0xfe, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01,
...@@ -606,4 +645,5 @@ class X393Jpeg(object): ...@@ -606,4 +645,5 @@ class X393Jpeg(object):
""" """
ff d9 ff d9
""" """
\ No newline at end of file
...@@ -165,7 +165,7 @@ class X393McntrlMembridge(object): ...@@ -165,7 +165,7 @@ class X393McntrlMembridge(object):
port_num, port_num,
quiet=1): quiet=1):
''' '''
Write defualt parameters to AFI port registers Write default parameters to AFI port registers
@param port_num - AXI_HP port number (0..3) @param port_num - AXI_HP port number (0..3)
@param quiet - reduce output (>=1 - silent) @param quiet - reduce output (>=1 - silent)
''' '''
......
...@@ -377,16 +377,20 @@ class X393McntrlTests(object): ...@@ -377,16 +377,20 @@ class X393McntrlTests(object):
window_width, # input [15:0] window_width; window_width, # input [15:0] window_width;
window_height, # input [15:0] window_height; window_height, # input [15:0] window_height;
window_left, # input [15:0] window_left; window_left, # input [15:0] window_left;
window_top): # input [15:0] window_top; window_top, # input [15:0] window_top;
frame_start_addr = 0x0, # 1000,
frame_full_width = 0xc0):
""" """
Test scanline read (frame size/row increment is set in parameters) Test scanline read (frame size/row increment is set in parameters)
@param channel channel number to use. Valid values: 1, 3 @param channel channel number to use. Valid values: 1, 3
@param extra_pages 2-bit number of extra pages that need to stay (not to be overwritten) in the buffer @param extra_pages 2-bit number of extra pages that need to stay (not to be overwritten) in the buffer
@param show_data print read data @param show_data print read data
@param window_width 13-bit window width in 8-bursts (16 bytes) @param window_width 13-bit window width in 8-bursts (16 bytes)
@param window_height 16 bit window height @param window_height 16 bit window height
@param window_left, 13-bit window left margin in 8-bursts (16 bytes) @param window_left, 13-bit window left margin in 8-bursts (16 bytes)
@param window_top 16-bit window top margin @param window_top 16-bit window top margin
@param frame_start_addr - frame start address (was 0x1000)
@param frame_full_width - frame full width in bursts (16 bytes) - was 0xc0
@return read data as list @return read data as list
""" """
if show_data==2: if show_data==2:
...@@ -449,8 +453,8 @@ class X393McntrlTests(object): ...@@ -449,8 +453,8 @@ class X393McntrlTests(object):
# program to the # program to the
self.x393_axi_tasks.write_control_register(start_addr + vrlg.MCNTRL_SCANLINE_MODE, 0); # reset channel, including page address self.x393_axi_tasks.write_control_register(start_addr + vrlg.MCNTRL_SCANLINE_MODE, 0); # reset channel, including page address
self.x393_axi_tasks.write_control_register(start_addr + vrlg.MCNTRL_SCANLINE_STARTADDR, vrlg.FRAME_START_ADDRESS); # RA=80, CA=0, BA=0 22-bit frame start address (3 CA LSBs==0. BA==0) self.x393_axi_tasks.write_control_register(start_addr + vrlg.MCNTRL_SCANLINE_STARTADDR, frame_start_addr); # RA=80, CA=0, BA=0 22-bit frame start address (3 CA LSBs==0. BA==0)
self.x393_axi_tasks.write_control_register(start_addr + vrlg.MCNTRL_SCANLINE_FRAME_FULL_WIDTH, vrlg.FRAME_FULL_WIDTH); self.x393_axi_tasks.write_control_register(start_addr + vrlg.MCNTRL_SCANLINE_FRAME_FULL_WIDTH, frame_full_width);
self.x393_axi_tasks.write_control_register(start_addr + vrlg.MCNTRL_SCANLINE_WINDOW_WH, (window_height << 16) | window_width); #WINDOW_WIDTH + (WINDOW_HEIGHT<<16)); self.x393_axi_tasks.write_control_register(start_addr + vrlg.MCNTRL_SCANLINE_WINDOW_WH, (window_height << 16) | window_width); #WINDOW_WIDTH + (WINDOW_HEIGHT<<16));
self.x393_axi_tasks.write_control_register(start_addr + vrlg.MCNTRL_SCANLINE_WINDOW_X0Y0, (window_top << 16) | window_left); #WINDOW_X0+ (WINDOW_Y0<<16)); self.x393_axi_tasks.write_control_register(start_addr + vrlg.MCNTRL_SCANLINE_WINDOW_X0Y0, (window_top << 16) | window_left); #WINDOW_X0+ (WINDOW_Y0<<16));
self.x393_axi_tasks.write_control_register(start_addr + vrlg.MCNTRL_SCANLINE_WINDOW_STARTXY, vrlg.SCANLINE_STARTX+(vrlg.SCANLINE_STARTY<<16)); self.x393_axi_tasks.write_control_register(start_addr + vrlg.MCNTRL_SCANLINE_WINDOW_STARTXY, vrlg.SCANLINE_STARTX+(vrlg.SCANLINE_STARTY<<16));
......
...@@ -1084,7 +1084,7 @@ class X393PIOSequences(object): ...@@ -1084,7 +1084,7 @@ class X393PIOSequences(object):
quiet=1): quiet=1):
""" """
Program sequencer, read block from memory,optionally print it Program sequencer, read block from memory,optionally print it
Epecting incremental 16-bit data block, calculate number of leading and trailing Expecting incremental 16-bit data block, calculate number of leading and trailing
non-consecutive words and return them as a tuple non-consecutive words and return them as a tuple
@param num8 number of 8-bursts (default=64, should be >2) @param num8 number of 8-bursts (default=64, should be >2)
@param ca 10-bit memory column address @param ca 10-bit memory column address
......
This diff is collapsed.
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
`define SYSTEM_DEFINES `define SYSTEM_DEFINES
`define PRELOAD_BRAMS `define PRELOAD_BRAMS
`define DEBUG_RING 1 `define DEBUG_RING 1
`define MEMBRIDGE_DEBUG_WRITE 1
// Enviroment-dependent options // Enviroment-dependent options
`ifdef IVERILOG `ifdef IVERILOG
`define SIMULATION `define SIMULATION
......
...@@ -316,7 +316,7 @@ module x393 #( ...@@ -316,7 +316,7 @@ module x393 #(
wire status_debug_rq; // Other status request wire status_debug_rq; // Other status request
wire status_debug_start; // S uppressThisWarning VEditor ****** Other status packet transfer start (currently with 0 latency from status_root_rq) wire status_debug_start; // S uppressThisWarning VEditor ****** Other status packet transfer start (currently with 0 latency from status_root_rq)
localparam DEBUG_RING_LENGTH = 2; // increase here, insert new after master localparam DEBUG_RING_LENGTH = 3; // increase here, insert new after master
wire [DEBUG_RING_LENGTH:0] debug_ring; // TODO: adjust number of bits wire [DEBUG_RING_LENGTH:0] debug_ring; // TODO: adjust number of bits
wire debug_sl; // debug shift/load: 0 - idle, (1,0) - shift, (1,1) - load wire debug_sl; // debug shift/load: 0 - idle, (1,0) - shift, (1,1) - load
...@@ -1272,6 +1272,9 @@ assign axi_grst = axi_rst_pre; ...@@ -1272,6 +1272,9 @@ assign axi_grst = axi_rst_pre;
.MEMBRIDGE_STATUS_REG (MEMBRIDGE_STATUS_REG), .MEMBRIDGE_STATUS_REG (MEMBRIDGE_STATUS_REG),
.FRAME_HEIGHT_BITS (FRAME_HEIGHT_BITS), .FRAME_HEIGHT_BITS (FRAME_HEIGHT_BITS),
.FRAME_WIDTH_BITS (FRAME_WIDTH_BITS) .FRAME_WIDTH_BITS (FRAME_WIDTH_BITS)
`ifdef DEBUG_RING
,.DEBUG_CMD_LATENCY (DEBUG_CMD_LATENCY)
`endif
) membridge_i ( ) membridge_i (
.mrst (mrst), // input .mrst (mrst), // input
.hrst (hrst), // input .hrst (hrst), // input
...@@ -1341,6 +1344,11 @@ assign axi_grst = axi_rst_pre; ...@@ -1341,6 +1344,11 @@ assign axi_grst = axi_rst_pre;
.afi_rcount (afi0_rcount), // input[7:0] .afi_rcount (afi0_rcount), // input[7:0]
.afi_racount (afi0_racount), // input[2:0] .afi_racount (afi0_racount), // input[2:0]
.afi_rdissuecap1en (afi0_rdissuecap1en) // output .afi_rdissuecap1en (afi0_rdissuecap1en) // output
`ifdef DEBUG_RING
,.debug_do (debug_ring[2]), // output
.debug_sl (debug_sl), // input
.debug_di (debug_ring[3]) // input
`endif
); );
// SAXIGP0 signals (read unused) (for the histograms) // SAXIGP0 signals (read unused) (for the histograms)
...@@ -2205,7 +2213,7 @@ assign axi_grst = axi_rst_pre; ...@@ -2205,7 +2213,7 @@ assign axi_grst = axi_rst_pre;
.status_ad (status_debug_ad), // output[7:0] .status_ad (status_debug_ad), // output[7:0]
.status_rq (status_debug_rq), // output .status_rq (status_debug_rq), // output
.status_start (status_debug_start), // input .status_start (status_debug_start), // input
.debug_do (debug_ring[2]), // output .debug_do (debug_ring[3]), // output
.debug_sl (debug_sl), // output .debug_sl (debug_sl), // output
.debug_di (debug_ring[0]) // DEBUG_RING_LENGTH-1]) // input .debug_di (debug_ring[0]) // DEBUG_RING_LENGTH-1]) // input
); );
......
This diff is collapsed.
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