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 source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -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
......
...@@ -41,11 +41,13 @@ import x393_cmprs ...@@ -41,11 +41,13 @@ import x393_cmprs
import x393_frame_sequencer import x393_frame_sequencer
import x393_sensor import x393_sensor
import x393_rtc import x393_rtc
import x393_mcntrl_membridge
import x393_utils import x393_utils
import time import time
import vrlg import vrlg
import x393_mcntrl
from verilog_utils import hx from verilog_utils import hx
...@@ -73,6 +75,7 @@ class X393SensCmprs(object): ...@@ -73,6 +75,7 @@ class X393SensCmprs(object):
x393FrameSequencer = None x393FrameSequencer = None
x393Sensor = None x393Sensor = None
x393Rtc = None x393Rtc = None
x393Membridge = None
def __init__(self, debug_mode=1,dry_mode=True, saveFileName=None): def __init__(self, debug_mode=1,dry_mode=True, saveFileName=None):
global BUFFER_ADDRESS, BUFFER_LEN global BUFFER_ADDRESS, BUFFER_LEN
...@@ -89,7 +92,7 @@ class X393SensCmprs(object): ...@@ -89,7 +92,7 @@ class X393SensCmprs(object):
self.x393FrameSequencer = x393_frame_sequencer.X393FrameSequencer(debug_mode,dry_mode, saveFileName) self.x393FrameSequencer = x393_frame_sequencer.X393FrameSequencer(debug_mode,dry_mode, saveFileName)
self.x393Sensor = x393_sensor.X393Sensor(debug_mode,dry_mode, saveFileName) self.x393Sensor = x393_sensor.X393Sensor(debug_mode,dry_mode, saveFileName)
self.x393Rtc = x393_rtc.X393Rtc(debug_mode,dry_mode, saveFileName) self.x393Rtc = x393_rtc.X393Rtc(debug_mode,dry_mode, saveFileName)
self.x393Membridge = x393_mcntrl_membridge.X393McntrlMembridge(debug_mode,dry_mode)
try: try:
self.verbose=vrlg.VERBOSE self.verbose=vrlg.VERBOSE
except: except:
...@@ -445,6 +448,7 @@ class X393SensCmprs(object): ...@@ -445,6 +448,7 @@ class X393SensCmprs(object):
trig = False) trig = False)
return True return True
def setup_all_sensors (self, def setup_all_sensors (self,
setup_membridge = False,
exit_step = None, exit_step = None,
sensor_mask = 0x1, # channel 0 only sensor_mask = 0x1, # channel 0 only
gamma_load = False, gamma_load = False,
...@@ -514,6 +518,8 @@ class X393SensCmprs(object): ...@@ -514,6 +518,8 @@ class X393SensCmprs(object):
for i in range(16): for i in range(16):
circbuf_starts.append(circbuf_start + i*circbuf_chn_size) circbuf_starts.append(circbuf_start + i*circbuf_chn_size)
circbuf_end = circbuf_start + 4*circbuf_chn_size circbuf_end = circbuf_start + 4*circbuf_chn_size
membridge_start = circbuf_end
membridge_end = mem_end
#TODO: calculate addersses/lengths #TODO: calculate addersses/lengths
""" """
...@@ -531,15 +537,28 @@ class X393SensCmprs(object): ...@@ -531,15 +537,28 @@ class X393SensCmprs(object):
print ("circbuf start 2 = 0x%x"%(circbuf_starts[2])) print ("circbuf start 2 = 0x%x"%(circbuf_starts[2]))
print ("circbuf start 3 = 0x%x"%(circbuf_starts[3])) print ("circbuf start 3 = 0x%x"%(circbuf_starts[3]))
print ("circbuf end = 0x%x"%(circbuf_end)) print ("circbuf end = 0x%x"%(circbuf_end))
print ("membridge start = 0x%x"%(membridge_start))
print ("membridge end = 0x%x"%(membridge_end))
print ("membridge size = %d bytes"%(membridge_end - membridge_start))
print ("memory buffer end = 0x%x"%(mem_end)) print ("memory buffer end = 0x%x"%(mem_end))
self.program_status_debug (3,0) self.program_status_debug (3,0)
if setup_membridge:
self.setup_membridge_sensor(
write_mem = False,
window_width = window_width,
window_height = window_height,
window_left = window_left,
window_top = window_top,
membridge_start = membridge_start,
membridge_end = membridge_end,
verbose = verbose)
if sensor_mask & 3: # Need mower for sesns1 and sens 2 if sensor_mask & 3: # Need power for sens1 and sens 2
if verbose >0 : if verbose >0 :
print ("===================== Sensor power setup: sensor ports 0 and 1 =========================") print ("===================== Sensor power setup: sensor ports 0 and 1 =========================")
self.setSensorPower(sub_pair=0, power_on=1) self.setSensorPower(sub_pair=0, power_on=1)
if sensor_mask & 0xc: # Need mower for sesns1 and sens 2 if sensor_mask & 0xc: # Need power for sens1 and sens 2
if verbose >0 : if verbose >0 :
print ("===================== Sensor power setup: sensor ports 2 and 3 =========================") print ("===================== Sensor power setup: sensor ports 2 and 3 =========================")
self.setSensorPower(sub_pair=1, power_on=1) self.setSensorPower(sub_pair=1, power_on=1)
...@@ -757,43 +776,108 @@ class X393SensCmprs(object): ...@@ -757,43 +776,108 @@ class X393SensCmprs(object):
print ("\n%2x: "%(i), end="") print ("\n%2x: "%(i), end="")
print("%s "%(hx(d,8)), end = "") print("%s "%(hx(d,8)), end = "")
print() print()
""" def setup_membridge_sensor(self,
tasks related to debug ring write_mem = False,
task debug_read_ring; cache_mode = 0x3, # 0x13 for debug mode
input integer num32; window_width = 2592,
window_height = 1944,
reg [5:0] seq_num; window_left = 0,
integer i; window_top = 0,
begin membridge_start = 0x2ba00000,
// load all shift registers from sources membridge_end = 0x2dd00000,
write_control_register(DEBUG_ADDR + DEBUG_LOAD, 0); verbose = 1):
for (i = 0; i < num32; i = i+1 ) begin """
read_status(DEBUG_STATUS_REG_ADDR); Configure membridge to read/write to the sensor 0 area in the video memory
seq_num = (registered_rdata[STATUS_SEQ_SHFT+:6] ^ 6'h20) &'h3f; // &'h30; @param write_mem - Write to video memory (Flase - read from)
write_control_register(DEBUG_ADDR + DEBUG_SHIFT_DATA, 0); @param cache_mode - lower 4 bits, axi cache mode (default 3), bit [4] - debug mode (replace data)
while (((registered_rdata[STATUS_SEQ_SHFT+:6] ^ 6'h20) &'h3f) == seq_num) begin @param window_width - window width in pixels (bytes) (TODO: add 16-bit mode)
read_status(DEBUG_STATUS_REG_ADDR); @param window_height - window height in lines
end @param window_left - window left margin
read_status(DEBUG_READ_REG_ADDR); @param window_top - window top margin
DEBUG_ADDRESS = i; @param membridge_start system memory low address (bytes) 0x2ba00000,
DEBUG_DATA = registered_rdata; @param membridge_end system memory buffer length (bytes)= 0x2dd00000,
@param verbose verbose level):
"""
if verbose >0 :
print ("===================== Setting membridge for sensor 0 =========================")
print ("Write to video buffer = %s"%(("False","True")[write_mem]))
print ("Window width = %d(0x%x)"%(window_width,window_width))
print ("Window height = %d(0x%x)"%(window_height,window_height))
print ("Window left = %d(0x%x)"%(window_left,window_left))
print ("Window top = %d(0x%x)"%(window_top,window_top))
print ("membridge start = 0x%x"%(membridge_start))
print ("membridge end = 0x%x"%(membridge_end))
print ("membridge size = %d bytes"%(membridge_end - membridge_start))
print ("cache/debug mode = 0x%x bytes"%(cache_mode))
end # Copied from setup_sensor
align_to_bursts = 64 # align full width to multiple of align_to_bursts. 64 is the size of memory access
width_in_bursts = window_width >> 4
end if (window_width & 0xf):
endtask width_in_bursts += 1
`ifdef DEBUG_RING num_burst_in_line = (window_left >> 4) + width_in_bursts
task program_status_debug; num_pages_in_line = num_burst_in_line // align_to_bursts;
input [1:0] mode; if num_burst_in_line % align_to_bursts:
input [5:0] seq_num; num_pages_in_line += 1
begin frame_full_width = num_pages_in_line * align_to_bursts
program_status (DEBUG_ADDR, num8rows= (window_top + window_height) // 8
DEBUG_SET_STATUS, if (window_top + window_height) % 8:
mode, num8rows += 1
seq_num); frame_start_addr = 0 # for sensor 0
end # frame_start_address_inc = num8rows * frame_full_width
endtask # len64 = num_burst_in_line * 2 * window_height
"""
\ No newline at end of file """
Setup video memory
"""
mode= x393_mcntrl.func_encode_mode_scan_tiled(
disable_need = False,
repetitive= True,
single = False,
reset_frame = False,
extra_pages = 0,
write_mem = write_mem,
enable = True,
chn_reset = False)
self.x393_axi_tasks.write_control_register(vrlg.MCNTRL_SCANLINE_CHN1_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(vrlg.MCNTRL_SCANLINE_CHN1_ADDR + vrlg.MCNTRL_SCANLINE_FRAME_FULL_WIDTH, frame_full_width)
self.x393_axi_tasks.write_control_register(vrlg.MCNTRL_SCANLINE_CHN1_ADDR + vrlg.MCNTRL_SCANLINE_WINDOW_WH, (window_height << 16) | (window_width >> 4)) # WINDOW_WIDTH + (WINDOW_HEIGHT<<16));
self.x393_axi_tasks.write_control_register(vrlg.MCNTRL_SCANLINE_CHN1_ADDR + vrlg.MCNTRL_SCANLINE_WINDOW_X0Y0, (window_top << 16) | (window_left >> 4)) # WINDOW_X0+ (WINDOW_Y0<<16));
self.x393_axi_tasks.write_control_register(vrlg.MCNTRL_SCANLINE_CHN1_ADDR + vrlg.MCNTRL_SCANLINE_WINDOW_STARTXY, 0)
self.x393_axi_tasks.write_control_register(vrlg.MCNTRL_SCANLINE_CHN1_ADDR + vrlg.MCNTRL_SCANLINE_MODE, mode)
self.x393_axi_tasks.configure_channel_priority(1,0); # lowest priority channel 1
self.x393_axi_tasks.enable_memcntrl_en_dis(1,1);
self.x393Membridge.afi_setup(0)
"""
self.afi_write_reg(port_num, 0x0, 0) # AFI_RDCHAN_CTRL
self.afi_write_reg(port_num, 0x04, 0x7) # AFI_RDCHAN_ISSUINGCAP
self.afi_write_reg(port_num, 0x08, 0) # AFI_RDQOS
#self.afi_write_reg(port_num,0x0c, 0) # AFI_RDDATAFIFO_LEVEL
#self.afi_write_reg(port_num,0x10, 0) # AFI_RDDEBUG
self.afi_write_reg(port_num, 0x14, 0xf00) # AFI_WRCHAN_CTRL
self.afi_write_reg(port_num, 0x18, 0x7) # AFI_WRCHAN_ISSUINGCAP
self.afi_write_reg(port_num, 0x1c, 0) # AFI_WRQOS
#self.afi_write_reg(port_num,0x20, 0) # AFI_WRDATAFIFO_LEVEL
#self.afi_write_reg(port_num,0x24, 0) # AFI_WRDEBUG
"""
self.x393Membridge.membridge_setup(
len64 = num_burst_in_line * 2 * window_height,
width64 = num_burst_in_line * 2, # 0,
start64 = 0,
lo_addr64 = membridge_start // 8,
size64 = (membridge_end - membridge_start) // 8,
cache = cache_mode,
quiet = 1 - verbose)
self.x393Membridge.membridge_en( # enable membridge
en = True,
quiet = 1 - verbose)
if verbose >0 :
print ("Run 'membridge_start' to initiate data transfer")
print ("Use 'mem_dump 0x%x <length>' to view data"%(membridge_start))
print ("Use 'mem_save \"/usr/local/verilog/memdumpXX\" 0x%x 0x%x' to save data"%(membridge_start,(membridge_end - membridge_start)))
...@@ -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
); );
......
...@@ -43,8 +43,8 @@ ...@@ -43,8 +43,8 @@
//`define TEST_TILED_WRITE32 1 //`define TEST_TILED_WRITE32 1
//`define TEST_TILED_READ32 1 //`define TEST_TILED_READ32 1
//`define TEST_AFI_WRITE 1 `define TEST_AFI_WRITE 1
//`define TEST_AFI_READ 1 `define TEST_AFI_READ 1
`define TEST_SENSOR 0 `define TEST_SENSOR 0
...@@ -856,16 +856,20 @@ assign #10 gpio_pins[9] = gpio_pins[8]; ...@@ -856,16 +856,20 @@ assign #10 gpio_pins[9] = gpio_pins[8];
test_afi_rw ( test_afi_rw (
1, // write_ddr3; 1, // write_ddr3;
SCANLINE_EXTRA_PAGES,// extra_pages; SCANLINE_EXTRA_PAGES,// extra_pages;
FRAME_START_ADDRESS, // input [21:0] frame_start_addr; 0, //FRAME_START_ADDRESS, // input [21:0] frame_start_addr;
FRAME_FULL_WIDTH, // input [15:0] window_full_width; // 13 bit - in 8*16=128 bit bursts FRAME_FULL_WIDTH, // input [15:0] window_full_width; // 13 bit - in 8*16=128 bit bursts
WINDOW_WIDTH, // input [15:0] window_width; // 13 bit - in 8*16=128 bit bursts 'h81, //'h8b,// WINDOW_WIDTH, // input [15:0] window_width; // 13 bit - in 8*16=128 bit bursts
WINDOW_HEIGHT, // input [15:0] window_height; // 16 bit (only 14 are used here) 'h2, // WINDOW_HEIGHT, // input [15:0] window_height; // 16 bit (only 14 are used here)
WINDOW_X0, // input [15:0] window_left; 'h1, //'h0, // WINDOW_X0, // input [15:0] window_left;
WINDOW_Y0, // input [15:0] window_top; 'h0, // WINDOW_Y0, // input [15:0] window_top;
0, // input [28:0] start64; // relative start address of the transfer (set to 0 when writing lo_addr64) 0, // input [28:0] start64; // relative start address of the transfer (set to 0 when writing lo_addr64)
AFI_LO_ADDR64, // input [28:0] lo_addr64; // low address of the system memory range, in 64-bit words AFI_LO_ADDR64, // input [28:0] lo_addr64; // low address of the system memory range, in 64-bit words
AFI_SIZE64, // input [28:0] size64; // size of the system memory range in 64-bit words AFI_SIZE64, // input [28:0] size64; // size of the system memory range in 64-bit words
0); // input continue; // 0 start from start64, 1 - continue from where it was 0, // input continue; // 0 start from start64, 1 - continue from where it was
0, // disable_need
'h13); //'h3); // cache_mode; // 'h3 - normal, 'h13 - debug
`endif `endif
...@@ -875,30 +879,37 @@ assign #10 gpio_pins[9] = gpio_pins[8]; ...@@ -875,30 +879,37 @@ assign #10 gpio_pins[9] = gpio_pins[8];
test_afi_rw ( test_afi_rw (
0, // write_ddr3; 0, // write_ddr3;
SCANLINE_EXTRA_PAGES,// extra_pages; SCANLINE_EXTRA_PAGES,// extra_pages;
FRAME_START_ADDRESS, // input [21:0] frame_start_addr; 0, //FRAME_START_ADDRESS, // input [21:0] frame_start_addr;
FRAME_FULL_WIDTH, // input [15:0] window_full_width; // 13 bit - in 8*16=128 bit bursts FRAME_FULL_WIDTH, // input [15:0] window_full_width; // 13 bit - in 8*16=128 bit bursts
WINDOW_WIDTH, // input [15:0] window_width; // 13 bit - in 8*16=128 bit bursts // Try a single-burst write
WINDOW_HEIGHT, // input [15:0] window_height; // 16 bit (only 14 are used here) 'h81, // 'h8b, // WINDOW_WIDTH, // input [15:0] window_width; // 13 bit - in 8*16=128 bit bursts
WINDOW_X0, // input [15:0] window_left; 'h2, // WINDOW_HEIGHT, // input [15:0] window_height; // 16 bit (only 14 are used here)
WINDOW_Y0, // input [15:0] window_top; 'h1, // 'h0, // WINDOW_X0, // input [15:0] window_left;
'h0, // WINDOW_Y0, // input [15:0] window_top;
0, // input [28:0] start64; // relative start address of the transfer (set to 0 when writing lo_addr64) 0, // input [28:0] start64; // relative start address of the transfer (set to 0 when writing lo_addr64)
AFI_LO_ADDR64, // input [28:0] lo_addr64; // low address of the system memory range, in 64-bit words AFI_LO_ADDR64, // input [28:0] lo_addr64; // low address of the system memory range, in 64-bit words
AFI_SIZE64, // input [28:0] size64; // size of the system memory range in 64-bit words AFI_SIZE64, // input [28:0] size64; // size of the system memory range in 64-bit words
0); // input continue; // 0 start from start64, 1 - continue from where it was 0, // input continue; // 0 start from start64, 1 - continue from where it was
0, // disable_need
'h13); //'h3); // cache_mode; // 'h3 - normal, 'h13 - debug
$display("===================== #2 TEST_%s =========================",TEST_TITLE); $display("===================== #2 TEST_%s =========================",TEST_TITLE);
test_afi_rw ( test_afi_rw (
0, // write_ddr3; 0, // write_ddr3;
SCANLINE_EXTRA_PAGES,// extra_pages; SCANLINE_EXTRA_PAGES,// extra_pages;
FRAME_START_ADDRESS, // input [21:0] frame_start_addr; 0, //FRAME_START_ADDRESS, // input [21:0] frame_start_addr;
FRAME_FULL_WIDTH, // input [15:0] window_full_width; // 13 bit - in 8*16=128 bit bursts FRAME_FULL_WIDTH, // input [15:0] window_full_width; // 13 bit - in 8*16=128 bit bursts
WINDOW_WIDTH, // input [15:0] window_width; // 13 bit - in 8*16=128 bit bursts // Try a single-burst read
WINDOW_HEIGHT, // input [15:0] window_height; // 16 bit (only 14 are used here) 'h81, // 'h8b, // WINDOW_WIDTH, // input [15:0] window_width; // 13 bit - in 8*16=128 bit bursts
WINDOW_X0, // input [15:0] window_left; 'h2, // WINDOW_HEIGHT, // input [15:0] window_height; // 16 bit (only 14 are used here)
WINDOW_Y0, // input [15:0] window_top; 'h1, // 'h0, // WINDOW_X0, // input [15:0] window_left;
'h0, // WINDOW_Y0, // input [15:0] window_top;
0, // input [28:0] start64; // relative start address of the transfer (set to 0 when writing lo_addr64) 0, // input [28:0] start64; // relative start address of the transfer (set to 0 when writing lo_addr64)
AFI_LO_ADDR64, // input [28:0] lo_addr64; // low address of the system memory range, in 64-bit words AFI_LO_ADDR64, // input [28:0] lo_addr64; // low address of the system memory range, in 64-bit words
AFI_SIZE64, // input [28:0] size64; // size of the system memory range in 64-bit words AFI_SIZE64, // input [28:0] size64; // size of the system memory range in 64-bit words
0); // input continue; // 0 start from start64, 1 - continue from where it was 0, // input continue; // 0 start from start64, 1 - continue from where it was
0, // disable_need
'h13); //'h3); // cache_mode; // 'h3 - normal, 'h13 - debug
`endif `endif
...@@ -1045,7 +1056,26 @@ assign #10 gpio_pins[9] = gpio_pins[8]; ...@@ -1045,7 +1056,26 @@ assign #10 gpio_pins[9] = gpio_pins[8];
TEST_TITLE = "READBACK"; TEST_TITLE = "READBACK";
$display("===================== TEST_%s =========================",TEST_TITLE); $display("===================== TEST_%s =========================",TEST_TITLE);
axi_get_delays; axi_get_delays;
`endif `endif
compressor_run (0, 2); // run single
compressor_run (1, 2); // run single
compressor_run (2, 2); // run single
compressor_run (3, 2); // run single
TEST_TITLE = "MEMBRIDGE_READ # 1";
$display("===================== TEST_%s =========================",TEST_TITLE);
TEST_TITLE = "MEMBRIDGE READ #1";
$display("===================== TEST_%s =========================",TEST_TITLE);
setup_sensor_membridge (0, // for sensor 0
1) ; // disable_need
TEST_TITLE = "MEMBRIDGE READ #2";
$display("===================== TEST_%s =========================",TEST_TITLE);
setup_sensor_membridge (0, // for sensor 0
1) ; // disable_need
`ifdef DEBUG_RING `ifdef DEBUG_RING
TEST_TITLE = "READING DEBUG DATA"; TEST_TITLE = "READING DEBUG DATA";
$display("===================== TEST_%s =========================",TEST_TITLE); $display("===================== TEST_%s =========================",TEST_TITLE);
...@@ -2339,41 +2369,8 @@ task setup_sensor_channel; ...@@ -2339,41 +2369,8 @@ task setup_sensor_channel;
1, // input [31:0] extra_pages; // 1 1, // input [31:0] extra_pages; // 1
1); // disable "need" (yield to sensor channels) 1); // disable "need" (yield to sensor channels)
compressor_run (num_sensor, 3); // run repetitive mode // compressor_run (num_sensor, 3); // run repetitive mode
/*
TEST_TITLE = "CAMSYNC_SETUP";
$display("===================== TEST_%s =========================",TEST_TITLE);
// setup camsync module
set_camsync_period (0); // reset circuitry
set_gpio_ports (
0, // input [1:0] port_soft; // <2 - unchanged, 2 - disable, 3 - enable
3, // input [1:0] port_a; // camsync
0, // input [1:0] port_b; // motors on 353
0); //input [1:0] port_c; // logger
set_camsync_mode (
1'b1, // input en; // 1 - enable module, 0 - reset
{1'b1,1'b1}, // input [1:0] en_snd; // <2 - NOP, 2 - disable, 3 - enable sending timestamp with sync pulse
{1'b1,external_timestamp}, // input [1:0] en_ts_external; // <2 - NOP, 2 - local timestamp in the frame header, 3 - use external timestamp
{1'b1,trigger_mode}, // input [1:0] triggered_mode; // <2 - NOP, 2 - async sensor mode, 3 - triggered sensor mode
{1'b1, 2'h0}, // input [2:0] master_chn; // <4 - NOP, 4..7 - set master channel
{1'b1, sensor_mask}); // input [4:0] chn_en; // <16 - NOP, [3:0] - bit mask of enabled sensor channels
// setting I/Os after camsync is enabled
reset_camsync_inout (0); // reset input selection
if (ext_trigger_mode)
set_camsync_inout (0, 7, 1 ); // set input selection - ext[7], active high
reset_camsync_inout (1); // reset output selection
set_camsync_inout (1, 6, 1 ); // reset output selection - ext[6], active high
set_camsync_period (SYNC_BIT_LENGTH); ///set (bit_length -1) (should be 2..255)
set_camsync_delay (
0, // input [1:0] sub_chn;
camsync_delay); // input [31:0] dly; // 0 - input selection, 1 - output selection
set_camsync_period (camsync_period); // set period (start generating) - in 353 was after everything else was set
*/
TEST_TITLE = "DELAYS_SETUP"; TEST_TITLE = "DELAYS_SETUP";
$display("===================== TEST_%s =========================",TEST_TITLE); $display("===================== TEST_%s =========================",TEST_TITLE);
...@@ -2399,25 +2396,6 @@ task setup_sensor_channel; ...@@ -2399,25 +2396,6 @@ task setup_sensor_channel;
// 6'h24); // data-0, hact - 1, vact - 2 input [SENS_CTRL_QUADRANTS_WIDTH-1:0] quadrants; // 90-degree shifts for data [1:0], hact [3:2] and vact [5:4] // 6'h24); // data-0, hact - 1, vact - 2 input [SENS_CTRL_QUADRANTS_WIDTH-1:0] quadrants; // 90-degree shifts for data [1:0], hact [3:2] and vact [5:4]
// 6'h01); // data-1, hact - 0, vact - 0 input [SENS_CTRL_QUADRANTS_WIDTH-1:0] quadrants; // 90-degree shifts for data [1:0], hact [3:2] and vact [5:4] // 6'h01); // data-1, hact - 0, vact - 0 input [SENS_CTRL_QUADRANTS_WIDTH-1:0] quadrants; // 90-degree shifts for data [1:0], hact [3:2] and vact [5:4]
QUADRANTS_PXD_HACT_VACT); // data-0, hact - 1, vact - 2 input [SENS_CTRL_QUADRANTS_WIDTH-1:0] quadrants; // 90-degree shifts for data [1:0], hact [3:2] and vact [5:4] QUADRANTS_PXD_HACT_VACT); // data-0, hact - 1, vact - 2 input [SENS_CTRL_QUADRANTS_WIDTH-1:0] quadrants; // 90-degree shifts for data [1:0], hact [3:2] and vact [5:4]
/*
// setup camsync module
reset_camsync_inout (0); // reset input selection
if (ext_trigger_mode)
set_camsync_inout (0, 7, 1 ); // set input selection - ext[7], active high
reset_camsync_inout (1); // reset output selection
set_camsync_inout (1, 6, 1 ); // reset output selection - ext[6], active high
set_camsync_period (camsync_period); // set period
set_camsync_delay (
0, // input [1:0] sub_chn;
camsync_delay); // input [31:0] dly; // 0 - input selection, 1 - output selection
set_camsync_mode (
{1'b1,1'b1}, // input [1:0] en_snd; // <2 - NOP, 2 - disable, 3 - enable sending timestamp with sync pulse
{1'b1,external_timestamp}, // input [1:0] en_ts_external; // <2 - NOP, 2 - local timestamp in the frame header, 3 - use external timestamp
{1'b1,trigger_mode}, // input [1:0] triggered_mode; // <2 - NOP, 2 - async sensor mode, 3 - triggered sensor mode
{1'b1, 2'h0}, // input [2:0] master_chn; // <4 - NOP, 4..7 - set master channel
{1'b1, sensor_mask}); // input [4:0] chn_en; // <16 - NOP, [3:0] - bit mask of enabled sensor channels
*/
TEST_TITLE = "I2C_TEST"; TEST_TITLE = "I2C_TEST";
$display("===================== TEST_%s =========================",TEST_TITLE); $display("===================== TEST_%s =========================",TEST_TITLE);
...@@ -2481,29 +2459,6 @@ task setup_sensor_channel; ...@@ -2481,29 +2459,6 @@ task setup_sensor_channel;
1'b1, // input confirm_write; // wait for the write confirmed before switching channels 1'b1, // input confirm_write; // wait for the write confirmed before switching channels
4'h3); // input [3:0] cache_mode; // default should be 4'h3 4'h3); // input [3:0] cache_mode; // default should be 4'h3
/*
task set_sensor_io_jtag;
input [1:0] num_sensor;
input [1:0] pgmen; // <2: keep PGMEN, 2 - PGMEN low (inactive), 3 - high (active) enable JTAG control
input [1:0] prog; // <2: keep prog, 2 - prog low (active), 3 - high (inactive) ("program" pin control)
input [1:0] tck; // <2: keep TCK, 2 - set TCK low, 3 - set TCK high
input [1:0] tms; // <2: keep TMS, 2 - set TMS low, 3 - set TMS high
input [1:0] tdi; // <2: keep TDI, 2 - set TDI low, 3 - set TDI high
task ctrl_cmd_frame_sequencer;
input [1:0] num_sensor; // sensor channel number
input reset; // reset sequencer (also stops)
input start; // start sequencer
input stop; // stop sequencer
task write_cmd_frame_sequencer;
input [1:0] num_sensor; // sensor channel number
input relative; // 0 - absolute (address = 0..f), 1 - relative (address= 0..e)
input [3:0] frame_addr; // frame address (relative ort absolute)
input [AXI_WR_ADDR_BITS-1:0] addr; // command address (register to which command should be applied)
input [31:0] data; // command data
*/
// Run after histogram channel is set up? // Run after histogram channel is set up?
TEST_TITLE = "SENSOR_SETUP"; TEST_TITLE = "SENSOR_SETUP";
$display("===================== TEST_%s =========================",TEST_TITLE); $display("===================== TEST_%s =========================",TEST_TITLE);
...@@ -2520,58 +2475,6 @@ task write_cmd_frame_sequencer; ...@@ -2520,58 +2475,6 @@ task write_cmd_frame_sequencer;
$display("===================== TEST_%s =========================",TEST_TITLE); $display("===================== TEST_%s =========================",TEST_TITLE);
// just temporarily - enable channel immediately // just temporarily - enable channel immediately
enable_memcntrl_en_dis(4'hc + {2'b0,num_sensor}, 1); enable_memcntrl_en_dis(4'hc + {2'b0,num_sensor}, 1);
/*
TEST_TITLE = "PROGRAM AFI_MUX";
$display("===================== TEST_%s =========================",TEST_TITLE);
afi_mux_program_status (
0, // input [0:0] port_afi; // number of AFI port (0 - afi 1, 1 - afi2) // configuration controlled by the code. currently
// both AFI are used: ch0 - cmprs_afi_mux_1.0, ch1 - cmprs_afi_mux_1.1,
// ch2 - cmprs_afi_mux_2.0, ch3 - cmprs_afi_mux_2
// May be changed to ch0 - cmprs_afi_mux_1.0, ch1 -cmprs_afi_mux_1.1,
// ch2 - cmprs_afi_mux_1.2, ch3 - cmprs_afi_mux_1.3
num_sensor, // input [1:0] chn_afi;
3, // input [1:0] mode;
0); // input [5:0] seq_num;
// reset all channels
afi_mux_reset(
0, // input [0:0] port_afi;
4'hf); // input [3:0] rst_chn;
// release resets
afi_mux_reset(
0, // input [0:0] port_afi;
0); // input [3:0] rst_chn;
// set report mode (pointer type) - per status
afi_mux_mode_chn (
0, //input [0:0] port_afi; // number of AFI port.3
num_sensor, // input [1:0] chn; // channel number to set mode for
//mode == 0 - show EOF pointer, internal
//mode == 1 - show EOF pointer, confirmed
//mode == 2 - show current pointer, internal
//mode == 3 - show current pointer, confirmed
//each group of 4 bits per channel : bits [1:0] - select, bit[2] - sset (0 - nop), bit[3] - not used
0); // input [1:0] mode;
afi_mux_chn_start_length (
0, // input [0:0] port_afi; // number of AFI port
num_sensor, // input [ 1:0] chn; // channel number to set mode for
afi_cmprs0_sa, // input [26:0] sa; // start address in 32-byte chunks
afi_cmprs0_len); // input [26:0] length; // channel buffer length in 32-byte chunks
// enable channel 0 and the whole afi_mux module
afi_mux_enable_chn (
0, // input [0:0] port_afi; // number of AFI port
num_sensor, // input [1:0] en_chn; // channel number to enable/disable;
1); // input en;
afi_mux_enable (
0, // input [0:0] port_afi; // number of AFI port
1); // input en;
*/
TEST_TITLE = "GAMMA_CTL"; TEST_TITLE = "GAMMA_CTL";
$display("===================== TEST_%s =========================",TEST_TITLE); $display("===================== TEST_%s =========================",TEST_TITLE);
...@@ -2584,8 +2487,47 @@ task write_cmd_frame_sequencer; ...@@ -2584,8 +2487,47 @@ task write_cmd_frame_sequencer;
1'b0); // input trig; // pass next frame 1'b0); // input trig; // pass next frame
// temporarily putting in the very end as it takes about 30 usec to program curves (TODO: see how to make it faster for simulation) // temporarily putting in the very end as it takes about 30 usec to program curves (TODO: see how to make it faster for simulation)
end end
endtask endtask // setup_sensor_channel
task setup_sensor_membridge;
input [1:0] num_sensor;
input disable_need;
reg [31:0] frame_full_width; // 13-bit Padded line length (8-row increment), in 8-bursts (16 bytes)
reg [31:0] window_width; // 13 bit - in 8*16=128 bit bursts
reg [31:0] window_height; // 16 bit
reg [31:0] window_left;
reg [31:0] window_top;
reg [31:0] frame_start_address;
// reg [31:0] frame_start_address_inc;
begin
window_height = FULL_HEIGHT;
window_left = 0;
window_top = 0;
window_width = SENSOR_MEMORY_WIDTH_BURSTS;
frame_full_width = SENSOR_MEMORY_FULL_WIDTH_BURSTS;
frame_start_address = FRAME_START_ADDRESS + num_sensor * FRAME_START_ADDRESS_INC * (LAST_BUF_FRAME + 1);
// frame_start_address_inc = FRAME_START_ADDRESS_INC;
test_afi_rw (
0, // write_ddr3;
SCANLINE_EXTRA_PAGES, // extra_pages;
frame_start_address[21:0], // input [21:0] frame_start_addr;
frame_full_width[15:0], // input [15:0] window_full_width; // 13 bit - in 8*16=128 bit bursts
window_width[15:0], // input [15:0] window_width; // 13 bit - in 8*16=128 bit bursts
window_height[15:0], // input [15:0] window_height; // 16 bit (only 14 are used here)
window_left[15:0], // input [15:0] window_left;
window_top[15:0], // input [15:0] window_top;
0, // input [28:0] start64; // relative start address of the transfer (set to 0 when writing lo_addr64)
AFI_LO_ADDR64, // input [28:0] lo_addr64; // low address of the system memory range, in 64-bit words
AFI_SIZE64, // input [28:0] size64; // size of the system memory range in 64-bit words
0, // input continue; // 0 start from start64, 1 - continue from where it was
disable_need,
'h13); // cache_mode; // 'h3 - normal, 'h13 - debug
end
endtask
//x393_camsync.py //x393_camsync.py
task camsync_setup; task camsync_setup;
......
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