Commit ccbfbf84 authored by Andrey Filippov's avatar Andrey Filippov

Fixed some errors in old memory controller modules

parent acf82200
......@@ -62,42 +62,42 @@
<link>
<name>vivado_logs/VivadoBitstream.log</name>
<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>
<name>vivado_logs/VivadoOpt.log</name>
<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>
<name>vivado_logs/VivadoOptPhys.log</name>
<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>
<name>vivado_logs/VivadoOptPower.log</name>
<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>
<name>vivado_logs/VivadoPlace.log</name>
<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>
<name>vivado_logs/VivadoRoute.log</name>
<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>
<name>vivado_logs/VivadoSynthesis.log</name>
<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>
<name>vivado_logs/VivadoTimimgSummaryReportImplemented.log</name>
<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>
<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
iverilog_100_TopModulesOther=glbl<-@\#\#@->
iverilog_101_TopModulesOther=glbl<-@\#\#@->
......@@ -12,8 +12,9 @@ iverilog_105_IncludeDir=${verilog_project_loc}/includes<-@\#\#@->${verilog_proje
iverilog_109_ShowNoProblem=true
iverilog_110_ShowNoProblem=true
iverilog_110_ShowWarnings=false
iverilog_113_SaveLogsPreprocessor=true
iverilog_113_SaveLogsPreprocessor=false
iverilog_113_SaveLogsSimulator=true
iverilog_114_SaveLogsSimulator=true
iverilog_121_GrepFindErrWarn=error|warning|sorry
iverilog_77_Param_Exe=/usr/local/bin/iverilog
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),
// 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 [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*
......@@ -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;
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_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),
//pend_last
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;
/*
counts_corr2[8]
......@@ -456,9 +468,9 @@ items_left
// 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 (pre_busy_w) chunk_inc <= (|counts_corr2[7:2])?
3'h4 :
({1'b0,left_to_eof[winner2 * 8 +: 2]} + 3'h1);
// if (pre_busy_w) 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);
if (awvalid[0]) afi_awid_r <={1'b0,wleft[3:2],last_burst_in_frame,cur_chn};
......@@ -517,13 +529,15 @@ items_left
.pre_busy_w (pre_busy_w), // input
.winner_channel (winner2), // input[1:0]
.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
.busy (busy), // input[3:0]
.ptr_resetting (ptr_resetting), // output
.chunk_addr (chunk_addr), // output[26:0] reg
.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];
cmprs_afi_mux_ptr_wresp cmprs_afi_mux_ptr_wresp_i (
......
......@@ -33,14 +33,17 @@ module cmprs_afi_mux_ptr(
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 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 [ 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 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]}
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_pri; // one-hot reset rq
......@@ -53,21 +56,45 @@ module cmprs_afi_mux_ptr(
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] 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
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 sa_len_ra= {busy[1],ptr_wa[1:0]};
assign reset_rq_enc = {reset_rq_pri[3] | reset_rq_pri[2],
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 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
en_d <= en;
// ===== calculate and rollover channel addresses ====
......@@ -103,11 +130,25 @@ module cmprs_afi_mux_ptr(
chunk_addr <= ptr_ram[ptr_wa] + sa_len_ram[sa_len_ra];
chunk_ptr_inc <= ptr_ram[ptr_wa] + chunk_inc;
end
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
end
// 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
// end
// write to ptr_ram (1 or 2 locations - if eof)
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
endmodule
......
......@@ -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] chunk_ptr_inc; // incremented by 1..4 chunk pointer
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 [ 5:0] id_r; // registered ID data
/// reg [ 3:0] busy; // one-hot busy stages (usually end with [3]
reg [ 4:0] busy; // one-hot busy stages (usually end with [4]
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 last_burst_in_frame; // this response is for eof
reg [2:0] chunk_inc;
......@@ -71,14 +72,19 @@ module cmprs_afi_mux_ptr_wresp(
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_wa = {eof,chn};
assign ptr_wa = {eof,chn}; // valid @busy[2]
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
busy[2] || // always update chunk pointer
(busy[3] && last_burst_in_frame); // optionally update frame chunk pointer (same value)
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);
busy[3] || // always update chunk pointer
(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 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];
......@@ -89,10 +95,11 @@ module cmprs_afi_mux_ptr_wresp(
afi_bvalid_r <= afi_bvalid;
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]),
reset_rq[2] & ~(|reset_rq[1:0]),
......@@ -106,9 +113,11 @@ module cmprs_afi_mux_ptr_wresp(
else resetting <= {resetting[0], start_resetting_w | (resetting[0] & ~resetting[1])};
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];
chunk_inc <= {1'b0,id_r[3 +:2]} + 1;
end
......@@ -118,10 +127,11 @@ module cmprs_afi_mux_ptr_wresp(
if ((resetting == 2'b01) || busy[0]) eof <= 0;
else if (ptr_we) eof <= 1; // always second write cycle
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
// @@@ delay by 1 clk
/// 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_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)
if (ptr_we) ptr_ram[ptr_wa] <= ptr_ram_di;
......
......@@ -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[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 (stb_mclk) status_data[chunk_chn_hclk * CMPRS_AFIMUX_WIDTH +: CMPRS_AFIMUX_WIDTH] <= chunk_ptr_hclk;
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;
else {index,cntr} <= {index,cntr} + 1;
......
......@@ -30,11 +30,14 @@ module membridge#(
parameter MEMBRIDGE_START64= 'h4, // start address relative to lo_addr
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_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 FRAME_HEIGHT_BITS= 16, // Maximal frame height bits
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)
`ifdef DEBUG_RING
,parameter DEBUG_CMD_LATENCY = 2
`endif
)(
// input rst,
......@@ -120,6 +123,11 @@ module membridge#(
input [ 7:0] afi_rcount,
input [ 2:0] afi_racount,
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;
......@@ -262,7 +270,7 @@ module membridge#(
reg next_page_wr;
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;
......@@ -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());
// 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
localparam DELAY_ADVANCE_ADDR=3;
......@@ -523,7 +544,8 @@ module membridge#(
wire is_last_in_page;
wire next_page_rd_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_page = is_last_in_line || (&buf_in_line64[6:0]);
`ifdef MEMBRIDGE_DEBUG_READ
......@@ -577,7 +599,8 @@ module membridge#(
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 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);
......@@ -631,12 +654,24 @@ module membridge#(
else if (!page_ready_wr && next_page_wr_w) write_pages_ready <= write_pages_ready +1; //-1;
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;
always @ (posedge hclk) begin
write_page_r <= write_page;
buf_in_line64_r <= buf_in_line64[6:0];
// 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
`endif
end
cmd_deser #(
......@@ -680,6 +715,19 @@ module membridge#(
);
// 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 #(
.LOG2WIDTH_RD(6) // 64 bit external interface
) chn1rd_buf_i (
......@@ -687,7 +735,7 @@ module membridge#(
.ext_raddr ({read_page,buf_in_line64[6:0]}), // input[8:0]
.ext_rd (bufrd_rd[0]), // 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
.wpage_in (2'b0), // input[1:0]
.wpage_set (xfer_reset_page_rd), // input TODO: Generate @ negedge mclk on frame start
......@@ -714,5 +762,28 @@ module membridge#(
.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
......@@ -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);
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;
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;
\ No newline at end of file
parameter FPGA_VERSION = 32'h03930029;
\ No newline at end of file
......@@ -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] size64; // size of the system memory range in 64-bit words
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;
......@@ -135,7 +138,7 @@ task test_afi_rw; // SuppressThisWarning VEditor - may be unused
reg reset_frame;
reg disable_need;
begin
disable_need = 1'b0;
// disable_need = 1'b0;
repetitive = 1'b1;
single = 1'b0;
reset_frame = 1'b0;
......@@ -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,
start64,
lo_addr64,
size64);
size64,
cache_mode);
membridge_start (continue);
`ifdef MEMBRIDGE_DEBUG_READ
// debugging
......
......@@ -25,13 +25,14 @@
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] size64; // size of the system memory range in 64-bit words
input [4:0] mode;
begin
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_START64, {3'b0,start64});
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_MODE, {27'b0,mode});
end
endtask
......
......@@ -98,7 +98,9 @@ module cmd_encod_linear_rd #(
if (mrst) 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
//counting loops?
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):
code <<= 1
si += 1
return hcodes
def jpegheader_create (self,
y_quality = 80,
c_quality = None,
......@@ -561,7 +563,44 @@ class X393Jpeg(object):
print("\nNumber of bytes that differ = %d"%(diffs))
return {"header":buf,
"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):
return bytearray((
0xfe, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01,
......@@ -606,4 +645,5 @@ class X393Jpeg(object):
"""
ff d9
"""
\ No newline at end of file
"""
......@@ -165,7 +165,7 @@ class X393McntrlMembridge(object):
port_num,
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 quiet - reduce output (>=1 - silent)
'''
......
......@@ -377,16 +377,20 @@ class X393McntrlTests(object):
window_width, # input [15:0] window_width;
window_height, # input [15:0] window_height;
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)
@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 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_height 16 bit window height
@param window_left, 13-bit window left margin in 8-bursts (16 bytes)
@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
"""
if show_data==2:
......@@ -449,8 +453,8 @@ class X393McntrlTests(object):
# 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_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_FRAME_FULL_WIDTH, vrlg.FRAME_FULL_WIDTH);
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, 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_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));
......
......@@ -1084,7 +1084,7 @@ class X393PIOSequences(object):
quiet=1):
"""
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
@param num8 number of 8-bursts (default=64, should be >2)
@param ca 10-bit memory column address
......
......@@ -41,11 +41,13 @@ import x393_cmprs
import x393_frame_sequencer
import x393_sensor
import x393_rtc
import x393_mcntrl_membridge
import x393_utils
import time
import vrlg
import x393_mcntrl
from verilog_utils import hx
......@@ -73,6 +75,7 @@ class X393SensCmprs(object):
x393FrameSequencer = None
x393Sensor = None
x393Rtc = None
x393Membridge = None
def __init__(self, debug_mode=1,dry_mode=True, saveFileName=None):
global BUFFER_ADDRESS, BUFFER_LEN
......@@ -89,7 +92,7 @@ class X393SensCmprs(object):
self.x393FrameSequencer = x393_frame_sequencer.X393FrameSequencer(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.x393Membridge = x393_mcntrl_membridge.X393McntrlMembridge(debug_mode,dry_mode)
try:
self.verbose=vrlg.VERBOSE
except:
......@@ -445,6 +448,7 @@ class X393SensCmprs(object):
trig = False)
return True
def setup_all_sensors (self,
setup_membridge = False,
exit_step = None,
sensor_mask = 0x1, # channel 0 only
gamma_load = False,
......@@ -514,6 +518,8 @@ class X393SensCmprs(object):
for i in range(16):
circbuf_starts.append(circbuf_start + i*circbuf_chn_size)
circbuf_end = circbuf_start + 4*circbuf_chn_size
membridge_start = circbuf_end
membridge_end = mem_end
#TODO: calculate addersses/lengths
"""
......@@ -531,15 +537,28 @@ class X393SensCmprs(object):
print ("circbuf start 2 = 0x%x"%(circbuf_starts[2]))
print ("circbuf start 3 = 0x%x"%(circbuf_starts[3]))
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))
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 :
print ("===================== Sensor power setup: sensor ports 0 and 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 :
print ("===================== Sensor power setup: sensor ports 2 and 3 =========================")
self.setSensorPower(sub_pair=1, power_on=1)
......@@ -757,43 +776,108 @@ class X393SensCmprs(object):
print ("\n%2x: "%(i), end="")
print("%s "%(hx(d,8)), end = "")
print()
"""
tasks related to debug ring
task debug_read_ring;
input integer num32;
reg [5:0] seq_num;
integer i;
begin
// load all shift registers from sources
write_control_register(DEBUG_ADDR + DEBUG_LOAD, 0);
for (i = 0; i < num32; i = i+1 ) begin
read_status(DEBUG_STATUS_REG_ADDR);
seq_num = (registered_rdata[STATUS_SEQ_SHFT+:6] ^ 6'h20) &'h3f; // &'h30;
write_control_register(DEBUG_ADDR + DEBUG_SHIFT_DATA, 0);
while (((registered_rdata[STATUS_SEQ_SHFT+:6] ^ 6'h20) &'h3f) == seq_num) begin
read_status(DEBUG_STATUS_REG_ADDR);
end
read_status(DEBUG_READ_REG_ADDR);
DEBUG_ADDRESS = i;
DEBUG_DATA = registered_rdata;
def setup_membridge_sensor(self,
write_mem = False,
cache_mode = 0x3, # 0x13 for debug mode
window_width = 2592,
window_height = 1944,
window_left = 0,
window_top = 0,
membridge_start = 0x2ba00000,
membridge_end = 0x2dd00000,
verbose = 1):
"""
Configure membridge to read/write to the sensor 0 area in the video memory
@param write_mem - Write to video memory (Flase - read from)
@param cache_mode - lower 4 bits, axi cache mode (default 3), bit [4] - debug mode (replace data)
@param window_width - window width in pixels (bytes) (TODO: add 16-bit mode)
@param window_height - window height in lines
@param window_left - window left margin
@param window_top - window top margin
@param membridge_start system memory low address (bytes) 0x2ba00000,
@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
end
endtask
`ifdef DEBUG_RING
task program_status_debug;
input [1:0] mode;
input [5:0] seq_num;
begin
program_status (DEBUG_ADDR,
DEBUG_SET_STATUS,
mode,
seq_num);
end
endtask
"""
\ No newline at end of file
# 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
if (window_width & 0xf):
width_in_bursts += 1
num_burst_in_line = (window_left >> 4) + width_in_bursts
num_pages_in_line = num_burst_in_line // align_to_bursts;
if num_burst_in_line % align_to_bursts:
num_pages_in_line += 1
frame_full_width = num_pages_in_line * align_to_bursts
num8rows= (window_top + window_height) // 8
if (window_top + window_height) % 8:
num8rows += 1
frame_start_addr = 0 # for sensor 0
# frame_start_address_inc = num8rows * frame_full_width
# len64 = num_burst_in_line * 2 * window_height
"""
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 @@
`define SYSTEM_DEFINES
`define PRELOAD_BRAMS
`define DEBUG_RING 1
`define MEMBRIDGE_DEBUG_WRITE 1
// Enviroment-dependent options
`ifdef IVERILOG
`define SIMULATION
......
......@@ -316,7 +316,7 @@ module x393 #(
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)
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_sl; // debug shift/load: 0 - idle, (1,0) - shift, (1,1) - load
......@@ -1272,6 +1272,9 @@ assign axi_grst = axi_rst_pre;
.MEMBRIDGE_STATUS_REG (MEMBRIDGE_STATUS_REG),
.FRAME_HEIGHT_BITS (FRAME_HEIGHT_BITS),
.FRAME_WIDTH_BITS (FRAME_WIDTH_BITS)
`ifdef DEBUG_RING
,.DEBUG_CMD_LATENCY (DEBUG_CMD_LATENCY)
`endif
) membridge_i (
.mrst (mrst), // input
.hrst (hrst), // input
......@@ -1341,6 +1344,11 @@ assign axi_grst = axi_rst_pre;
.afi_rcount (afi0_rcount), // input[7:0]
.afi_racount (afi0_racount), // input[2:0]
.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)
......@@ -2205,7 +2213,7 @@ assign axi_grst = axi_rst_pre;
.status_ad (status_debug_ad), // output[7:0]
.status_rq (status_debug_rq), // output
.status_start (status_debug_start), // input
.debug_do (debug_ring[2]), // output
.debug_do (debug_ring[3]), // output
.debug_sl (debug_sl), // output
.debug_di (debug_ring[0]) // DEBUG_RING_LENGTH-1]) // input
);
......
......@@ -43,8 +43,8 @@
//`define TEST_TILED_WRITE32 1
//`define TEST_TILED_READ32 1
//`define TEST_AFI_WRITE 1
//`define TEST_AFI_READ 1
`define TEST_AFI_WRITE 1
`define TEST_AFI_READ 1
`define TEST_SENSOR 0
......@@ -856,16 +856,20 @@ assign #10 gpio_pins[9] = gpio_pins[8];
test_afi_rw (
1, // write_ddr3;
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
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)
WINDOW_X0, // input [15:0] window_left;
WINDOW_Y0, // input [15:0] window_top;
'h81, //'h8b,// WINDOW_WIDTH, // input [15:0] window_width; // 13 bit - in 8*16=128 bit bursts
'h2, // WINDOW_HEIGHT, // input [15:0] window_height; // 16 bit (only 14 are used here)
'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)
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
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
......@@ -875,30 +879,37 @@ assign #10 gpio_pins[9] = gpio_pins[8];
test_afi_rw (
0, // write_ddr3;
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
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)
WINDOW_X0, // input [15:0] window_left;
WINDOW_Y0, // input [15:0] window_top;
// Try a single-burst write
'h81, // 'h8b, // WINDOW_WIDTH, // input [15:0] window_width; // 13 bit - in 8*16=128 bit bursts
'h2, // WINDOW_HEIGHT, // input [15:0] window_height; // 16 bit (only 14 are used here)
'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)
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
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);
test_afi_rw (
0, // write_ddr3;
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
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)
WINDOW_X0, // input [15:0] window_left;
WINDOW_Y0, // input [15:0] window_top;
// Try a single-burst read
'h81, // 'h8b, // WINDOW_WIDTH, // input [15:0] window_width; // 13 bit - in 8*16=128 bit bursts
'h2, // WINDOW_HEIGHT, // input [15:0] window_height; // 16 bit (only 14 are used here)
'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)
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
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
......@@ -1045,7 +1056,26 @@ assign #10 gpio_pins[9] = gpio_pins[8];
TEST_TITLE = "READBACK";
$display("===================== TEST_%s =========================",TEST_TITLE);
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
TEST_TITLE = "READING DEBUG DATA";
$display("===================== TEST_%s =========================",TEST_TITLE);
......@@ -2339,41 +2369,8 @@ task setup_sensor_channel;
1, // input [31:0] extra_pages; // 1
1); // disable "need" (yield to sensor channels)
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
// compressor_run (num_sensor, 3); // run repetitive mode
set_camsync_period (camsync_period); // set period (start generating) - in 353 was after everything else was set
*/
TEST_TITLE = "DELAYS_SETUP";
$display("===================== TEST_%s =========================",TEST_TITLE);
......@@ -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'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]
/*
// 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";
$display("===================== TEST_%s =========================",TEST_TITLE);
......@@ -2481,29 +2459,6 @@ task setup_sensor_channel;
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
/*
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?
TEST_TITLE = "SENSOR_SETUP";
$display("===================== TEST_%s =========================",TEST_TITLE);
......@@ -2520,58 +2475,6 @@ task write_cmd_frame_sequencer;
$display("===================== TEST_%s =========================",TEST_TITLE);
// just temporarily - enable channel immediately
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";
$display("===================== TEST_%s =========================",TEST_TITLE);
......@@ -2584,8 +2487,47 @@ task write_cmd_frame_sequencer;
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)
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
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