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];
end
if (stb_mclk) status_data[chunk_chn_hclk * CMPRS_AFIMUX_WIDTH +: CMPRS_AFIMUX_WIDTH] <= chunk_ptr_hclk;
end
// 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 diff is collapsed.
......@@ -345,6 +345,8 @@ class X393Jpeg(object):
code <<= 1
si += 1
return hcodes
def jpegheader_create (self,
y_quality = 80,
c_quality = None,
......@@ -562,6 +564,43 @@ class X393Jpeg(object):
return {"header":buf,
"quantization":qtables["fpga"],
"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,
......@@ -607,3 +646,4 @@ class X393Jpeg(object):
"""
ff d9
"""
......@@ -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,7 +377,9 @@ 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
......@@ -387,6 +389,8 @@ class X393McntrlTests(object):
@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
......
This diff is collapsed.
......@@ -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
);
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment