Commit 82e11ec7 authored by Andrey Filippov's avatar Andrey Filippov

multiple changes, synchronizing simulation with hardware

parent 7c1a8880
......@@ -2,6 +2,9 @@ unisims
vivado_*
syntax_*
simulation/*
simulation_data/*
www/*
constraints/*
ise_*
attic/*
hardware_tests/*
......@@ -31,3 +34,9 @@ x393_testbench01_debug_membridge.sav
x393_testbench02-0.sav
py393/generated
*.pickle
py393/i2c.py
py393/x393_i2c.py.test
py393/x393_init_usb_hub.py
py393/x393_mcntrl_adjust.py.dbg
x393_testbench03_01.sav
......@@ -62,52 +62,52 @@
<link>
<name>vivado_logs/VivadoBitstream.log</name>
<type>1</type>
<location>/home/andrey/git/x393/vivado_logs/VivadoBitstream-20160417175241357.log</location>
<location>/home/andrey/git/x393/vivado_logs/VivadoBitstream-20160502180852175.log</location>
</link>
<link>
<name>vivado_logs/VivadoOpt.log</name>
<type>1</type>
<location>/home/andrey/git/x393/vivado_logs/VivadoOpt-20160417175241357.log</location>
<location>/home/andrey/git/x393/vivado_logs/VivadoOpt-20160502180852175.log</location>
</link>
<link>
<name>vivado_logs/VivadoOptPhys.log</name>
<type>1</type>
<location>/home/andrey/git/x393/vivado_logs/VivadoOptPhys-20160417175241357.log</location>
<location>/home/andrey/git/x393/vivado_logs/VivadoOptPhys-20160502180852175.log</location>
</link>
<link>
<name>vivado_logs/VivadoOptPower.log</name>
<type>1</type>
<location>/home/andrey/git/x393/vivado_logs/VivadoOptPower-20160417175241357.log</location>
<location>/home/andrey/git/x393/vivado_logs/VivadoOptPower-20160502180852175.log</location>
</link>
<link>
<name>vivado_logs/VivadoPlace.log</name>
<type>1</type>
<location>/home/andrey/git/x393/vivado_logs/VivadoPlace-20160417175241357.log</location>
<location>/home/andrey/git/x393/vivado_logs/VivadoPlace-20160502180852175.log</location>
</link>
<link>
<name>vivado_logs/VivadoRoute.log</name>
<type>1</type>
<location>/home/andrey/git/x393/vivado_logs/VivadoRoute-20160417175241357.log</location>
<location>/home/andrey/git/x393/vivado_logs/VivadoRoute-20160502180852175.log</location>
</link>
<link>
<name>vivado_logs/VivadoSynthesis.log</name>
<type>1</type>
<location>/home/andrey/git/x393/vivado_logs/VivadoSynthesis-20160417173535326.log</location>
<location>/home/andrey/git/x393/vivado_logs/VivadoSynthesis-20160502180258922.log</location>
</link>
<link>
<name>vivado_logs/VivadoTimimgSummaryReportImplemented.log</name>
<type>1</type>
<location>/home/andrey/git/x393/vivado_logs/VivadoTimimgSummaryReportImplemented-20160417175241357.log</location>
<location>/home/andrey/git/x393/vivado_logs/VivadoTimimgSummaryReportImplemented-20160502180852175.log</location>
</link>
<link>
<name>vivado_logs/VivadoTimimgSummaryReportSynthesis.log</name>
<type>1</type>
<location>/home/andrey/git/x393/vivado_logs/VivadoTimimgSummaryReportSynthesis-20160417173535326.log</location>
<location>/home/andrey/git/x393/vivado_logs/VivadoTimimgSummaryReportSynthesis-20160502180258922.log</location>
</link>
<link>
<name>vivado_logs/VivadoTimingReportSynthesis.log</name>
<type>1</type>
<location>/home/andrey/git/x393/vivado_logs/VivadoTimingReportSynthesis-20160417173535326.log</location>
<location>/home/andrey/git/x393/vivado_logs/VivadoTimingReportSynthesis-20160502180258922.log</location>
</link>
<link>
<name>vivado_state/x393-opt-phys.dcp</name>
......@@ -127,7 +127,7 @@
<link>
<name>vivado_state/x393-synth.dcp</name>
<type>1</type>
<location>/home/andrey/git/x393/vivado_state/x393-synth-20160417173535326.dcp</location>
<location>/home/andrey/git/x393/vivado_state/x393-synth-20160502180258922.dcp</location>
</link>
</linkedResources>
</projectDescription>
......@@ -290,6 +290,8 @@ module membridge#(
// incrementing IDs for read (MSB==0) and write (MSB==1)
reg [4:0] rd_id;
reg [4:0] wr_id;
reg read_no_more; // after frame_done - no more requests for new pages to read
assign afi_arid={1'b1,rd_id};
assign afi_awid={1'b1,wr_id};
......@@ -324,7 +326,7 @@ module membridge#(
if (hrst) wr_start <= 0;
else wr_start <= rdwr_start[2] && wr_mode;
page_ready_rd <= page_ready && !wr_mode;
// page_ready_rd <= page_ready && !wr_mode && !read_no_more;
if (hrst) rd_id <= 0;
else if (rd_start) rd_id <= rd_id +1;
......@@ -429,7 +431,7 @@ module membridge#(
afi_len <= (|left64[28:4])?4'hf : (left64[3:0]-1);
afi_len_plus1 <= (|left64[28:4]) ? 5'h10 : {1'b0,left64[3:0]};
page_ready_rd <= page_ready && !wr_mode;
page_ready_rd <= page_ready && !wr_mode && !read_no_more;
page_ready_wr <= page_ready && wr_mode;
if (!rw_in_progress) buf_left64 <= len64;
......@@ -450,12 +452,13 @@ module membridge#(
//rdwr_en
reg [7:0] axi_arw_requested; // 64-bit words to be read/written over axi queued to AR/AW channels
reg [7:0] axi_bursts_requested; // number of bursts requested
reg [7:0] wresp_conf; // number of 64-bit words confirmed through axi b channel
wire [7:0] axi_wr_pending; // Number of words qued to AW but not yet confirmed through B-channel;
reg [7:0] wresp_conf; // number of 64-bit words confirmed through axi b channel (wrong confirmed only bursts)!
wire [7:0] axi_wr_pending; // Number of bursts queued to AW but not yet confirmed through B-channel;
reg [7:0] axi_wr_left; // Number of bursts queued through AW but not sent over W;
wire [7:0] axi_rd_pending;
reg [7:0] axi_rd_received;
assign axi_rd_pending= axi_arw_requested - axi_rd_received;
assign axi_rd_pending= axi_arw_requested - axi_rd_received; // WRONG! - use bursts, not words!
// assign axi_wr_pending= axi_arw_requested - wresp_conf;
assign axi_wr_pending= axi_bursts_requested - wresp_conf;
......@@ -520,12 +523,12 @@ module membridge#(
if (hrst) read_page <= 0;
else if (reset_page_rd) read_page <= 0;
else if (next_page_rd_w) read_page <= read_page + 1;
else if (done_page_rd_w) read_page <= read_page + 1;
if (hrst) read_pages_ready <= 0;
else if (!read_busy) read_pages_ready <= 0;
else if ( page_ready_rd && !next_page_rd_w) read_pages_ready <= read_pages_ready +1;
else if (!page_ready_rd && next_page_rd_w) read_pages_ready <= read_pages_ready -1;
else if ( page_ready_rd && !done_page_rd_w) read_pages_ready <= read_pages_ready +1;
else if (!page_ready_rd && done_page_rd_w) read_pages_ready <= read_pages_ready -1;
if (hrst) afi_wd_safe_not_full <= 0;
else afi_wd_safe_not_full <= rdwr_en && (!afi_wcount[7] && !(&afi_wcount[6:3]));
......@@ -544,6 +547,12 @@ module membridge#(
else if (pre_done) done <= 1;
else if (rdwr_start) done <= 0;
if (hrst ) read_no_more <= 0;
else if (!read_busy) read_no_more <= 0;
else if (frame_done) read_no_more <= 1;
end
// handle interaction with the buffer, advance addresses, keep track of partial (last) pages in each line
......@@ -557,17 +566,29 @@ module membridge#(
wire is_last_in_page;
wire next_page_rd_w;
wire next_page_wr_w;
wire done_page_rd_w;
wire safe_some_left_rd_w;
reg left_was_1; // was <=1 (0 does not matter) valid next after buffer address
reg left_many;
// 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 done_page_rd_w = read_started && is_last_in_page && bufrd_rd[0];
assign next_page_rd_w = done_page_rd_w && !read_no_more;
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 safe_some_left_rd_w = (axi_wr_left[7:1]!=0) || (axi_wr_left[0] && !bufrd_rd[0]);
assign safe_some_left_rd_w = left_many || (|buf_left64[1:0] && !(|bufrd_rd)); // Fine tune
`ifdef MEMBRIDGE_DEBUG_READ
assign bufrd_rd_w = afi_wd_safe_not_full && (|read_pages_ready[2:1] || (read_pages_ready[0] && !is_last_in_page)) && debug_w_ready;
assign bufrd_rd_w = safe_some_left_rd_w && !read_over && afi_wd_safe_not_full &&
(|read_pages_ready[2:1] || (read_pages_ready[0] && (!is_last_in_page || read_no_more))) && debug_w_ready;
`else
assign bufrd_rd_w = afi_wd_safe_not_full && (|read_pages_ready[2:1] || (read_pages_ready[0] && !is_last_in_page));
// assign bufrd_rd_w = afi_wd_safe_not_full && (|read_pages_ready[2:1] || (read_pages_ready[0] && !is_last_in_page));
assign bufrd_rd_w = safe_some_left_rd_w && !read_over && afi_wd_safe_not_full &&
(|read_pages_ready[2:1] || (read_pages_ready[0] && (!is_last_in_page || read_no_more)));
`endif
//last_in_line64 - last word number in scan line
reg left_was_1; // was <=1 (0 does not matter) valid next after buffer address
reg [3:0] src_wcntr;
// reg [2:0] wlast_in_burst;
reg wlast; // valid 2 after buffer address, same as wvalid
......@@ -581,6 +602,12 @@ module membridge#(
if (!rw_in_progress) left_was_1 <= 0;
else if (buf_rdwr) left_was_1 <= !(|buf_left64[28:1]);
/* if (!rw_in_progress) left_many <= 0;
else if (buf_rdwr) */
left_many <= |buf_left64[28:2];
if (!read_started) src_wcntr <= 0;
else if (bufrd_rd[0]) src_wcntr <= src_wcntr+1;
......@@ -639,9 +666,14 @@ module membridge#(
else if (!write_busy && !read_started) axi_bursts_requested <= 0;
else if (advance_rel_addr) axi_bursts_requested <= axi_bursts_requested + 1;
if (hrst) axi_rd_received <= 0;
else if (!write_busy) axi_rd_received <= 0;
else if (bufwr_we[0]) axi_rd_received <= axi_rd_received + 1;
if (hrst) axi_rd_received <= 0;
else if (!write_busy) axi_rd_received <= 0;
else if (bufwr_we[0]) axi_rd_received <= axi_rd_received + 1;
if (hrst) axi_wr_left <= 0;
else if (!read_started) axi_wr_left <= 0;
else if ( advance_rel_addr && !(wlast && afi_wvalid)) axi_wr_left <= axi_wr_left + 1;
else if (!advance_rel_addr && (wlast && afi_wvalid)) axi_wr_left <= axi_wr_left - 1;
if (hrst) afi_rd_safe_not_empty <= 0;
......
......@@ -78,7 +78,8 @@ module cmprs_frame_sync#(
output reg force_flush_long, // force flush (abort frame), can be any clock and may last until stuffer_done_mclk
// stuffer will re-clock and extract 0->1 transition
output stuffer_running_mclk,
output reading_frame
output reading_frame,
output frame_started_mclk // use to store frame number
);
/*
Abort frame (force flush) if:
......@@ -87,7 +88,7 @@ module cmprs_frame_sync#(
Abort frame lasts until flush end or timeout expire
*/
// wire vsync_late_mclk; // single mclk cycle, reclocked from vsync_late
wire frame_started_mclk;
// wire frame_started_mclk;
reg bonded_mode;
reg frame_start_dst_r;
reg frames_differ; // src and dest point to different frames (single-frame buffer mode), disregard line_unfinished_*
......
......@@ -33,25 +33,30 @@
*******************************************************************************/
`timescale 1ns/1ps
module cmprs_status(
input mrst,
input mclk, // system clock
input eof_written,
input stuffer_running,
input reading_frame,
input set_interrupts,
input [1:0] data_in,
output [4:0] status,
output irq
module cmprs_status #(
parameter NUM_FRAME_BITS = 4
) (
input mrst,
input mclk, // system clock
input eof_written,
input stuffer_running,
input reading_frame,
input [NUM_FRAME_BITS - 1:0] frame_num_compressed,
input set_interrupts,
input [1:0] data_in,
output [NUM_FRAME_BITS+7:0] status,
output irq
);
reg stuffer_running_r;
reg flushing_fifo;
reg is_r; // interrupt status (not masked)
reg im_r; // interrupt mask
reg stuffer_running_r;
reg flushing_fifo;
reg is_r; // interrupt status (not masked)
reg im_r; // interrupt mask
reg [NUM_FRAME_BITS - 1:0] frame_irq;
assign status = {flushing_fifo,
assign status = {frame_irq,
3'b0,
flushing_fifo,
stuffer_running_r,
reading_frame,
im_r, is_r};
......@@ -64,6 +69,8 @@ module cmprs_status(
if (mrst) is_r <= 0;
else if (eof_written) is_r <= 1;
else if (set_interrupts && (data_in == 1)) is_r <= 0;
if (eof_written) frame_irq <= frame_num_compressed;
stuffer_running_r <= stuffer_running;
......
......@@ -127,7 +127,9 @@ module compressor393 # (
parameter CMPRS_AFIMUX_WIDTH = 26, // maximal for status: currently only works with 26)
parameter CMPRS_AFIMUX_CYCBITS = 3,
parameter AFI_MUX_BUF_LATENCY = 4'd2 // buffers read latency from fifo_ren* to fifo_rdata* valid : 2 if no register layers are used
parameter AFI_MUX_BUF_LATENCY = 4'd2, // buffers read latency from fifo_ren* to fifo_rdata* valid : 2 if no register layers are used
parameter NUM_FRAME_BITS = 4 // number of bits use for frame number
`ifdef DEBUG_RING
,parameter DEBUG_CMD_LATENCY = 2
`endif
......@@ -173,6 +175,7 @@ module compressor393 # (
// use as 'eot_real' in 353
output [3:0]suspend, // suspend reading data for this channel - waiting for the source data
output [4*LAST_FRAME_BITS-1:0] frame_number_finished, // frame numbers compressed
// statistics data was not used in late nc353
// input dccout, //enable output of DC and HF components for brightness/color/focus adjustments
......@@ -187,11 +190,12 @@ module compressor393 # (
// Outputs for interrupts generation
output [3:0] eof_written_mclk,
output [3:0] stuffer_done_mclk,
// frame input synchronization
input [3:0] vsync_late, // delayed start of frame, @mclk. In 353 it was 16 lines after VACT active
// source channel should already start, some delay give time for sequencer commands
// that should arrive before it
// Frame numbers to determine number of compressed frame (for interrupts)
input [4 * NUM_FRAME_BITS-1:0] frame_num_compressed,
// AXI_HP inteface (single/dual). afi indices - relative (0,1) may actually be connected to 1,2 (or only to 1)
input hclk,
......@@ -398,7 +402,8 @@ module compressor393 # (
.CMPRS_CSAT_CR_BITS (CMPRS_CSAT_CR_BITS),
.CMPRS_CORING_BITS (CMPRS_CORING_BITS),
.CMPRS_TIMEOUT_BITS (CMPRS_TIMEOUT_BITS),
.CMPRS_TIMEOUT (CMPRS_TIMEOUT)
.CMPRS_TIMEOUT (CMPRS_TIMEOUT),
.NUM_FRAME_BITS (NUM_FRAME_BITS)
`ifdef DEBUG_RING
,.DEBUG_CMD_LATENCY (DEBUG_CMD_LATENCY)
`endif
......@@ -433,7 +438,7 @@ module compressor393 # (
.frame_number_dst (frame_number_dst[LAST_FRAME_BITS * i +: LAST_FRAME_BITS]), // input[15:0]
.frame_done_dst (frame_done_dst[i]), // input
.suspend (suspend[i]), // output
.frame_number_finished (frame_number_finished[LAST_FRAME_BITS * i +: LAST_FRAME_BITS]), // output reg[15:0]
.dccout (1'b0), // input
.hfc_sel (3'b0), // input[2:0]
.statistics_dv (), // output
......@@ -443,6 +448,7 @@ module compressor393 # (
.eof_written_mclk (eof_written_mclk[i]), // output
.stuffer_done_mclk (stuffer_done_mclk[i]), // output
.vsync_late (vsync_late[i]), // input
.frame_num_compressed (frame_num_compressed[i * NUM_FRAME_BITS +: NUM_FRAME_BITS]), // input[3:0]
.hclk (hclk), // input
.fifo_rst (fifo_rst[i]), // input
......
......@@ -110,8 +110,10 @@ module jp_channel#(
parameter CMPRS_CSAT_CR_BITS = 10, // number of bits in red scale field in color saturation word
parameter CMPRS_CORING_BITS = 3, // number of bits in coring mode
parameter CMPRS_TIMEOUT_BITS= 12,
parameter CMPRS_TIMEOUT= 1000 // mclk cycles
parameter CMPRS_TIMEOUT_BITS= 12,
parameter CMPRS_TIMEOUT= 1000, // mclk cycles
parameter NUM_FRAME_BITS = 4 // number of bits use for frame number
`ifdef DEBUG_RING
,parameter DEBUG_CMD_LATENCY = 2 //SuppressThisWarning VEditor - not used
`endif
......@@ -159,6 +161,8 @@ module jp_channel#(
input frame_done_dst, // single-cycle pulse when the full frame (window) was transferred to/from DDR3 memory
// use as 'eot_real' in 353
output suspend, // suspend reading data for this channel - waiting for the source data
output reg [LAST_FRAME_BITS-1:0] frame_number_finished, // valid after stuffer done
// statistics data was not used in late nc353
input dccout, //enable output of DC and HF components for brightness/color/focus adjustments
......@@ -177,6 +181,7 @@ module jp_channel#(
input vsync_late, // delayed start of frame, @mclk. In 353 it was 16 lines after VACT active
// source channel should already start, some delay give time for sequencer commands
// that should arrive before it
input [NUM_FRAME_BITS-1:0] frame_num_compressed,
// Output interface to the AFI mux
input hclk,
......@@ -312,6 +317,17 @@ module jp_channel#(
//TODO: use next signals for status
wire stuffer_running_mclk;
wire reading_frame;
wire frame_started_mclk;// store frame number ? Wrong, frame number should come from the sensor channel
reg stuffer_running_mclk_d;
reg [LAST_FRAME_BITS-1:0] frame_number_started; // valid when stuffer started
// output reg [LAST_FRAME_BITS-1:0] frame_number_finished, // valid after stuffer done
always @ (posedge mclk) begin
stuffer_running_mclk_d <=stuffer_running_mclk;
if ( stuffer_running_mclk && !stuffer_running_mclk_d) frame_number_started <= frame_number_dst;
if (!stuffer_running_mclk && stuffer_running_mclk_d) frame_number_finished <= frame_number_started;
end
`ifdef USE_XCLK2X
wire [15:0] huff_do; // output[15:0] reg
......@@ -581,22 +597,25 @@ module jp_channel#(
.we (cmd_we) // output
);
wire [4:0] status_data;
cmprs_status cmprs_status_i (
.mrst (mrst), // input
.mclk (mclk), // input
.eof_written (eof_written_mclk), // input
.stuffer_running (stuffer_running_mclk), // input
.reading_frame (reading_frame), // input
.set_interrupts (set_interrupts_w), // input
.data_in (cmd_data[1:0]), // input[1:0]
.status (status_data), // output[2:0]
.irq (irq) // output
wire [11:0] status_data;
cmprs_status #(
.NUM_FRAME_BITS(4)
) cmprs_status_i (
.mrst (mrst), // input
.mclk (mclk), // input
.eof_written (eof_written_mclk), // input
.stuffer_running (stuffer_running_mclk), // input
.reading_frame (reading_frame), // input
.frame_num_compressed (frame_num_compressed), // input[3:0]
.set_interrupts (set_interrupts_w), // input
.data_in (cmd_data[1:0]), // input[1:0]
.status (status_data), // output[9:0]
.irq (irq) // output
);
status_generate #(
.STATUS_REG_ADDR (CMPRS_STATUS_REG_ADDR),
.PAYLOAD_BITS (7),
.PAYLOAD_BITS (14),
.EXTRA_WORDS (1),
.EXTRA_REG_ADDR (CMPRS_HIFREQ_REG_ADDR)
......@@ -779,8 +798,8 @@ module jp_channel#(
.stuffer_running (stuffer_running), // input
.force_flush_long (force_flush_long), // output reg - @ mclk tried to start frame compression before the previous one was finished
.stuffer_running_mclk(stuffer_running_mclk), // output
.reading_frame (reading_frame) // output
.reading_frame (reading_frame), // output
.frame_started_mclk (frame_started_mclk)
);
cmprs_macroblock_buf_iface cmprs_macroblock_buf_iface_i (
......@@ -1239,6 +1258,9 @@ module jp_channel#(
.fifo_count (fifo_count) // output[7:0] - number of 32-byte chunks available in FIFO
);
pulse_cross_clock eof_written_mclk_i (.rst(xrst2xn), .src_clk(~xclk2x), .dst_clk(mclk), .in_pulse(eof_written_xclk2xn), .out_pulse(eof_written_mclk),.busy());
// pulse_cross_clock eof_written_mclk_i (.rst(xrst2xn), .src_clk(~xclk2x), .dst_clk(mclk), .in_pulse(eof_written_xclk2xn), .out_pulse(eof_written_mclk),.busy());
`ifdef DISPLAY_COMPRESSED_DATA
integer dbg_stuffer_word_number;
reg dbg_odd_stuffer_dv;
......
......@@ -32,7 +32,8 @@
* with at least one of the Free Software programs.
*******************************************************************************/
parameter FPGA_VERSION = 32'h03930086; // Adding byte-wide JTAG read to speed-up 10359 load
parameter FPGA_VERSION = 32'h03930087; // Synchronizing i2c sequencer frame number with that of a command sequencer
// parameter FPGA_VERSION = 32'h03930086; // Adding byte-wide JTAG read to speed-up 10359 load
// parameter FPGA_VERSION = 32'h03930085; // Adding software control for i2c pins when sequencer is stopped, timing matched
// parameter FPGA_VERSION = 32'h03930084; // Back to iserdes, inverting xfpgatdo - met
// parameter FPGA_VERSION = 32'h03930083; // Debugging JTAG, using plain IOBUF
......
......@@ -139,6 +139,7 @@ task test_afi_rw; // SuppressThisWarning VEditor - may be unused
input continue; // 0 start from start64, 1 - continue from where it was
input disable_need;
input [4:0] cache_mode; // 'h3 - normal, 'h13 - debug
input rpt;
// -----------------------------------------
......@@ -154,8 +155,8 @@ task test_afi_rw; // SuppressThisWarning VEditor - may be unused
begin
skip_too_late = 1'b0;
disable_need = 1'b0;
repetitive = 1'b1;
single = 1'b0;
repetitive = rpt; //1'b1;
single = !rpt; // 1'b0;
reset_frame = 1'b0;
$display("====== test_afi_rw: write=%d, extra_pages=%d, frame_start= %x, window_full_width=%d, window_width=%d, window_height=%d, window_left=%d, window_top=%d,@%t",
write_ddr3, extra_pages, frame_start_addr, window_full_width, window_width, window_height, window_left, window_top, $time);
......
......@@ -55,15 +55,17 @@
// parameter SENSOR12BITS_NROWA = 1, // number of "blank rows" from last hact to end of vact
// parameter nAV = 24, //240; // clocks from ARO to VACT (actually from en_dclkd)
// parameter SENSOR12BITS_NBPF = 20, //16; // bpf length
parameter SENSOR_IMAGE_TYPE0 = "NORM", // "RUN1",
parameter SENSOR_IMAGE_TYPE0 = "RUN1", //"NORM", // "RUN1",
parameter SENSOR_IMAGE_TYPE1 = "RUN1",
parameter SENSOR_IMAGE_TYPE2 = "NORM", // "RUN1",
parameter SENSOR_IMAGE_TYPE2 = "RUN1", // "NORM", // "RUN1",
parameter SENSOR_IMAGE_TYPE3 = "RUN1",
parameter SIMULATE_CMPRS_CMODE0 = CMPRS_CBIT_CMODE_JPEG18,
parameter SIMULATE_CMPRS_CMODE1 = CMPRS_CBIT_CMODE_JPEG18,
parameter SIMULATE_CMPRS_CMODE2 = CMPRS_CBIT_CMODE_JP4,
parameter SIMULATE_CMPRS_CMODE3 = CMPRS_CBIT_CMODE_JP4,
// parameter SIMULATE_CMPRS_CMODE2 = CMPRS_CBIT_CMODE_JPEG18,
// parameter SIMULATE_CMPRS_CMODE3 = CMPRS_CBIT_CMODE_JPEG18,
// CMPRS_CBIT_CMODE_JPEG18, //input [31:0] cmode; // [13:9] color mode:
// parameter CMPRS_CBIT_CMODE_JPEG18 = 4'h0, // color 4:2:0
// parameter CMPRS_CBIT_CMODE_MONO6 = 4'h1, // mono 4:2:0 (6 blocks)
......
......@@ -311,6 +311,7 @@ module mcntrl393 #(
input [255:0] sens_buf_dout, // (), // output[63:0]
input [3:0] sens_page_written, // single mclk pulse: buffer page (full or partial) is written to the memory buffer
output [3:0] sens_xfer_skipped, // single mclk pulse on each bit indicating one skipped (not written) block.
output reg [3:0] sens_first_wr_in_frame, // single mclk pulse on first write block in each frame
// compressor subsystem interface
// Buffer interfaces, combined for 4 channels
output [3:0] cmprs_xfer_reset_page_rd, // from mcntrl_tiled_rw (
......@@ -319,6 +320,7 @@ module mcntrl393 #(
output [255:0] cmprs_buf_din, // data out
output [3:0] cmprs_page_ready, // single mclk (posedge)
input [3:0] cmprs_next_page, // single mclk (posedge): Done with the page in the buffer, memory controller may read more data
output reg [3:0] cmprs_first_rd_in_frame, // single mclk pulse on first read block in each frame
// master (sensor) with slave (compressor) synchronization I/Os
input [3:0] cmprs_frame_start_dst, // @mclk - trigger receive (tiledc) memory channel (it will take care of single/repetitive
......@@ -734,7 +736,9 @@ module mcntrl393 #(
wire tiled_rw_start_wr16; // start cmd_encod_tiled_32_rw generating command sequence in write mode
wire tiled_rw_start_rd32; // start cmd_encod_tiled_32_rw generating command sequence in read mode
wire tiled_rw_start_wr32; // start cmd_encod_tiled_32_rw generating command sequence in write mode
// for propagating absolute frame number:
reg [3:0] sens_first_wr_pending_r;
reg [3:0] cmprs_first_rd_pending_r;
// Command tree - insert register layer(s) if needed, now just direct assignments
......@@ -755,8 +759,6 @@ module mcntrl393 #(
assign cmd_sens_stb= cmd_stb;
assign cmd_cmprs_ad= cmd_ad;
assign cmd_cmprs_stb= cmd_stb;
// For now - combinatorial, maybe add registers (modify axibram_read)
assign buf_raddr=axird_raddr;
......@@ -787,6 +789,19 @@ module mcntrl393 #(
assign select_buf3wr_w = ((axiwr_pre_awaddr ^ MCONTR_BUF3_WR_ADDR) & MCONTR_WR_MASK)==0;
assign select_buf4rd_w = ((axird_pre_araddr ^ MCONTR_BUF4_RD_ADDR) & MCONTR_RD_MASK)==0;
assign select_buf4wr_w = ((axiwr_pre_awaddr ^ MCONTR_BUF4_WR_ADDR) & MCONTR_WR_MASK)==0;
always @ (posedge mclk) begin
if (mrst) sens_first_wr_pending_r <= 0;
else sens_first_wr_pending_r <= sens_sof | (sens_first_wr_pending_r & ~sens_start_wr);
//cmprs_first_rd_pending_r
sens_first_wr_in_frame <= sens_first_wr_pending_r & sens_start_wr;
if (mrst) cmprs_first_rd_pending_r <= 0;
else cmprs_first_rd_pending_r <= cmprs_frame_start_dst | (cmprs_first_rd_pending_r & ~cmprs_channel_pgm_en);
cmprs_first_rd_in_frame <= cmprs_first_rd_pending_r & cmprs_channel_pgm_en;
end
always @ (posedge axi_clk) begin
if (mrst) select_cmd0 <= 0;
......
......@@ -182,6 +182,7 @@ module mcntrl_linear_rw #(
reg frame_finished_r;
wire last_in_row_w;
wire last_row_w;
wire last_block_w;
reg last_block;
reg [MCNTRL_SCANLINE_PENDING_CNTR_BITS-1:0] pending_xfers; // number of requested,. but not finished block transfers
reg [NUM_RC_BURST_BITS-1:0] row_col_r;
......@@ -340,7 +341,9 @@ module mcntrl_linear_rw #(
// assign pre_want= chn_en && busy_r && !want_r && !xfer_start_r[0] && calc_valid && !last_block && !suspend && !(|frame_start_r);
// accelerating pre_want:
assign pre_want= pre_want_r1 && !want_r && !xfer_start_r[0] && !suspend ;
// assign pre_want= pre_want_r1 && !want_r && !xfer_start_r[0] && !suspend ;
// last_block was too late to inclusde in pre_want_r1, moving it here
assign pre_want= pre_want_r1 && !want_r && !xfer_start_r[0] && !suspend && !last_block;
assign last_in_row_w=(row_left=={{(FRAME_WIDTH_BITS-NUM_XFER_BITS){1'b0}},xfer_num128_r});
assign last_row_w= next_y==window_height;
......@@ -485,8 +488,10 @@ wire start_not_partial= xfer_start_r[0] && !xfer_limited_by_mem_page_r;
// calculate number to read (min of row_left, maximal xfer and what is left in the DDR3 page
always @(posedge mclk) begin
// acceletaring pre_want
pre_want_r1 <= chn_en && !frame_done_r && busy_r && par_mod_r[PAR_MOD_LATENCY-2] && !(|frame_start_r[4:1]) && !last_block;
// pre_want_r1 <= chn_en && !frame_done_r && busy_r && par_mod_r[PAR_MOD_LATENCY-2] && !(|frame_start_r[4:1]) && !last_block;
//last_block is too late for pre_want_r1, moving upsteram
pre_want_r1 <= chn_en && !frame_done_r && busy_r && par_mod_r[PAR_MOD_LATENCY-2] && !(|frame_start_r[4:1]);
if (mrst) par_mod_r<=0;
else if (pgm_param_w ||
xfer_start_r[0] ||
......
......@@ -47,6 +47,7 @@ import time
#import shutil
import socket
import select
import traceback
from import_verilog_parameters import ImportVerilogParameters
#from import_verilog_parameters import VerilogParameters
......@@ -152,6 +153,7 @@ def execTask(commandLine):
sFuncArgs+=' <'+str(a)+'>'
print ("Usage:\n%s %s"%(funcName,sFuncArgs))
print ("exception message:"+str(e))
print (traceback.format_exc())
else:
result = callableTasks[funcName]['func'](callableTasks[funcName]['inst'],*funcArgs)
return result
......@@ -480,7 +482,7 @@ USAGE
print ("args.exception=%d, QUIET=%d"%(args.exceptions,QUIET))
print ("Enter 'R' to toggle show/hide command results, now it is %s"%(("OFF","ON")[showResult]))
print ("Use 'socket_port [PORT]' to (re-)open socket on PORT (0 or no PORT - disable socket)")
# print ("Use 'copy <SRC> <DST> to copy files in file the system")
# print ("Use 'copy <SRC> <DST> to copy files in file the system")
print ("Use 'pydev_predefines' to generate a parameter list to paste to vrlg.py, so Pydev will be happy")
elif lineList[0].upper() == 'R':
if len(lineList)>1:
......
......@@ -106,15 +106,51 @@ class X393CmprsAfi(object):
num_lines_print = 20):
"""
Returns image metadata (start, length,timestamp) or null
@param port_afi - AFI port (0/1), currently only 0
@param port_afi - AFI port (0/1), currently only 0, or file path template for simulated mode
@param channel - AFI input channel (0..3) - with 2 AFIs - 0..1 only
@return - memory segments (1 or two) with image data, timestamp in numeric and string format
"""
if verbose >0:
def read_mem(addr):
if ba_data:
return ba_data[addr + 0] + (ba_data[addr + 1] << 8) + (ba_data[addr + 2] << 16) + (ba_data[addr + 3] << 24)
else:
return self.x393_mem.read_mem(addr)
if isinstance(port_afi, (unicode,str)):
data_file = port_afi%channel # for simulated mode
ba_data=bytearray()
try:
with open(data_file) as f:
for l in f:
line = l.strip()
if line:
dl = []
for item in line.split():
dl.append(int(item,16))
ba_data += bytearray(dl)
if verbose > 0:
print ("Read simulated sensor JPEG data from %s data file"%(data_file))
except:
print("Failed to read data from ", data_file)
return
cirbuf_start = 0
circbuf_len = len(ba_data)
print ("len(ba) = %d"%(len(ba_data)))
if verbose > 1:
for i in range(len(ba_data)):
if not (i%16):
print("\n%04x:"%(i),end="")
print ("%02x "%(ba_data[i]),end="")
else:
ba_data = None
if verbose > 0:
print ("\n------------ channel %d --------------"%(channel))
print ("x393_sens_cmprs.GLBL_WINDOW = ", x393_sens_cmprs.GLBL_WINDOW)
if (self.DRY_MODE):
return None
# if (self.DRY_MODE):
# return None
CCAM_MMAP_META = 12 # extra bytes included at the end of each frame (last aligned to 32 bytes)
CCAM_MMAP_META_LENGTH = 4 # displacement to length frame length data from the end of the 32-byte aligned frame slot
CCAM_MMAP_META_USEC = 8 # // (negative) displacement to USEC data - 20 bits (frame timestamp)
......@@ -122,20 +158,25 @@ class X393CmprsAfi(object):
# offs_len32 = 0x20 - CCAM_MMAP_META_LENGTH # 0x1c #from last image 32-byte chunk to lower of 3-byte image length (MSB == 0xff)
next_image = self.afi_mux_get_image_pointer(port_afi = port_afi,
if ba_data:
next_image = len(ba_data)
else:
next_image = self.afi_mux_get_image_pointer(port_afi = port_afi,
channel = channel)
# Bug - got 0x20 more than start of the new image
last_image_chunk = next_image - 0x40
if last_image_chunk < 0:
last_image_chunk += circbuf_len
len32 = self.x393_mem.read_mem(cirbuf_start + last_image_chunk + (0x20 - CCAM_MMAP_META_LENGTH))
## len32 = self.x393_mem.read_mem(cirbuf_start + last_image_chunk + (0x20 - CCAM_MMAP_META_LENGTH))
len32 = read_mem(cirbuf_start + last_image_chunk + (0x20 - CCAM_MMAP_META_LENGTH))
markerFF = len32 >> 24
if (markerFF != 0xff):
print ("Failed to get 0xff marker at offset 0x%08x - length word = 0x%08x, next_image = 0x%08x)"%
(cirbuf_start + last_image_chunk + (0x20 - CCAM_MMAP_META_LENGTH) + 3,len32,next_image))
if verbose >0:
for a in range ( next_image - (0x10 * num_lines_print), next_image + (0x10 * num_lines_print), 4):
d = self.x393_mem.read_mem(cirbuf_start + a)
## d = self.x393_mem.read_mem(cirbuf_start + a)
d = read_mem(cirbuf_start + a)
if (a % 16) == 0:
print ("\n%08x: "%(a),end ="" )
print("%02x %02x %02x %02x "%(d & 0xff, (d >> 8) & 0xff, (d >> 16) & 0xff, (d >> 24) & 0xff), end = "")
......@@ -146,7 +187,8 @@ class X393CmprsAfi(object):
last_image_chunk = next_image - 0x40
if last_image_chunk < 0:
last_image_chunk += circbuf_len
len32 = self.x393_mem.read_mem(cirbuf_start + last_image_chunk + (0x20 - CCAM_MMAP_META_LENGTH))
## len32 = self.x393_mem.read_mem(cirbuf_start + last_image_chunk + (0x20 - CCAM_MMAP_META_LENGTH))
len32 = read_mem(cirbuf_start + last_image_chunk + (0x20 - CCAM_MMAP_META_LENGTH))
markerFF = len32 >> 24
if (markerFF != 0xff):
print ("**** Failed to get 0xff marker at CORRECTED offset 0x%08x - length word = 0x%08x, next_image = 0x%08x)"%
......@@ -166,7 +208,8 @@ class X393CmprsAfi(object):
img_start += circbuf_len
if verbose >0:
for a in range ( img_start, img_start + (0x10 * num_lines_print), 4):
d = self.x393_mem.read_mem(cirbuf_start + a)
## d = self.x393_mem.read_mem(cirbuf_start + a)
d = read_mem(cirbuf_start + a)
if (a % 16) == 0:
print ("\n%08x: "%(a),end ="" )
print("%02x %02x %02x %02x "%(d & 0xff, (d >> 8) & 0xff, (d >> 16) & 0xff, (d >> 24) & 0xff), end = "")
......@@ -175,14 +218,17 @@ class X393CmprsAfi(object):
a = a0
if (a < 0):
a -=circbuf_len
d = self.x393_mem.read_mem(cirbuf_start + a)
## d = self.x393_mem.read_mem(cirbuf_start + a)
d = read_mem(cirbuf_start + a)
if (a % 16) == 0:
print ("\n%08x: "%(a),end ="" )
print("%02x %02x %02x %02x "%(d & 0xff, (d >> 8) & 0xff, (d >> 16) & 0xff, (d >> 24) & 0xff), end = "")
print()
sec = self.x393_mem.read_mem(cirbuf_start + last_image_chunk + (0x20 - CCAM_MMAP_META_SEC))
usec = self.x393_mem.read_mem(cirbuf_start + last_image_chunk + (0x20 - CCAM_MMAP_META_USEC))
## sec = self.x393_mem.read_mem(cirbuf_start + last_image_chunk + (0x20 - CCAM_MMAP_META_SEC))
sec = read_mem(cirbuf_start + last_image_chunk + (0x20 - CCAM_MMAP_META_SEC))
## usec = self.x393_mem.read_mem(cirbuf_start + last_image_chunk + (0x20 - CCAM_MMAP_META_USEC))
usec = read_mem(cirbuf_start + last_image_chunk + (0x20 - CCAM_MMAP_META_USEC))
fsec=sec + usec/1000000.0
try:
tstr = time.strftime("%b %d %Y %H:%M:%S", time.gmtime(fsec))
......@@ -196,6 +242,8 @@ class X393CmprsAfi(object):
result = {"timestamp": fsec,
"timestring": tstr,
"segments":segments}
if ba_data:
result["bindata"] = ba_data
if verbose >0 :
print ("Inserted bytes after image before meta = 0x%x"%(inserted_bytes))
print ("Image start (relative to cirbuf) = 0x%x, image length = 0x%x"%(img_start, len32 ))
......
......@@ -156,6 +156,7 @@ HUFFVAL = "huffval"
LENGTH = "length"
VALUE = "value"
FPGA_HUFFMAN_TABLE = "fpga_huffman_table"
SIMULATION_JPEG_DATA = "../simulation_data/compressor_out_%d.dat"
class X393Jpeg(object):
DRY_MODE= True # True
......@@ -271,8 +272,8 @@ class X393Jpeg(object):
for i,t in enumerate(STD_QUANT_TBLS[t_name]):
d = max(1,min((t * q + 50) // 100, 255))
tbl[ZIG_ZAG[i]] = d
# fpga_tbl[i] = min(((0x20000 // d) + 1) >> 1, 0xffff)
fpga_tbl[ZIG_ZAG[i]] = min(((0x20000 // d) + 1) >> 1, 0xffff)
fpga_tbl[i] = min(((0x20000 // d) + 1) >> 1, 0xffff)
## fpga_tbl[ZIG_ZAG[i]] = min(((0x20000 // d) + 1) >> 1, 0xffff)
rslt.append(tbl)
fpga.append(fpga_tbl)
if verbose > 0:
......@@ -770,7 +771,7 @@ class X393Jpeg(object):
portrait = False,
# color_mode = None, # vrlg.CMPRS_CBIT_CMODE_JPEG18, # read it from the saved
byrshift = 0,
server_root = "/www/pages/",
server_root = None, # "/www/pages/",
verbose = 1):
"""
Create JPEG image from the latest acquired in the camera
......@@ -783,6 +784,11 @@ class X393Jpeg(object):
@param server_root - files ystem path to the web server root directory
@param verbose - verbose level
"""
if server_root is None:
if (self.DRY_MODE):
server_root = "../www/"
else:
server_root = "/www/pages/"
allFiles = False
if file_path[0] == "/":
server_root = "" # just do not add anything
......@@ -849,6 +855,9 @@ class X393Jpeg(object):
print ("window[width]",window["width"])
print ("window[cmode]",window["cmode"])
print ("window=",window)
jpeg_data = self.jpegheader_create (
y_quality = y_quality,
c_quality = c_quality,
......@@ -858,13 +867,23 @@ class X393Jpeg(object):
color_mode = window["cmode"], #color_mode,
byrshift = byrshift,
verbose = verbose - 1)
meta = self.x393_cmprs_afi.afi_mux_get_image_meta(
port_afi = 0,
channel = channel,
cirbuf_start = x393_sens_cmprs.GLBL_CIRCBUF_STARTS[channel],
circbuf_len = x393_sens_cmprs.GLBL_CIRCBUF_CHN_SIZE,
verbose = verbose)
if verbose > 0 :
if self.DRY_MODE:
meta = self.x393_cmprs_afi.afi_mux_get_image_meta(
port_afi = SIMULATION_JPEG_DATA, # 0,
channel = channel,
cirbuf_start = 0, #x393_sens_cmprs.GLBL_CIRCBUF_STARTS[channel],
circbuf_len = 0, #x393_sens_cmprs.GLBL_CIRCBUF_ENDS[channel] - x393_sens_cmprs.GLBL_CIRCBUF_STARTS[channel],
verbose = verbose)
else:
meta = self.x393_cmprs_afi.afi_mux_get_image_meta(
port_afi = 0,
channel = channel,
cirbuf_start = x393_sens_cmprs.GLBL_CIRCBUF_STARTS[channel],
# circbuf_len = x393_sens_cmprs.GLBL_CIRCBUF_CHN_SIZE,
circbuf_len = x393_sens_cmprs.GLBL_CIRCBUF_ENDS[channel] - x393_sens_cmprs.GLBL_CIRCBUF_STARTS[channel],
verbose = verbose)
if verbose > 2 :
print ("meta = ",meta)
if verbose > 1 :
for s in meta["segments"]:
......@@ -874,9 +893,12 @@ class X393Jpeg(object):
for s in meta["segments"]:
if verbose > 1 :
print ("start_address = 0x%x, length = 0x%x"%(s[0],s[1]))
self.x393_mem._mem_write_to_file (bf = bf,
start_addr = s[0],
length = s[1])
if 'bindata' in meta:
bf.write(meta['bindata'][s[0] : s[0] + s[1]])
else:
self.x393_mem._mem_write_to_file (bf = bf,
start_addr = s[0],
length = s[1])
bf.write(bytearray((0xff,0xd9)))
......@@ -976,6 +998,7 @@ setup_all_sensors True None 0x4
################## Parallel ##################
cd /usr/local/verilog/; test_mcntrl.py @hargs
#fpga_shutdown
setupSensorsPower "PAR12"
measure_all "*DI"
setup_all_sensors True None 0xf
......@@ -997,6 +1020,11 @@ axi_write_single_w 0x686 0x079800a3
axi_write_single_w 0x6a6 0x079800a3
axi_write_single_w 0x6b6 0x079800a3
#Gamma 0.57
program_gamma all 0 0.57 0.04
......
......@@ -206,7 +206,7 @@ class X393McntrlMembridge(object):
size64 = BUFFER_LEN//8 # input [28:0] size64; # size of the system memory range in 64-bit words
if quiet <2:
print("membridge_setup(0x%08x,0x%0xx,0x%08x,0x%0xx,0x%08x,%d)"%(len64, width64, start64, lo_addr64, size64, quiet))
print("membridge_setup(0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,%d)"%(len64, width64, start64, lo_addr64, size64, quiet))
self.x393_axi_tasks.write_control_register(vrlg.MEMBRIDGE_ADDR + vrlg.MEMBRIDGE_LO_ADDR64, lo_addr64);
self.x393_axi_tasks.write_control_register(vrlg.MEMBRIDGE_ADDR + vrlg.MEMBRIDGE_SIZE64, size64);
self.x393_axi_tasks.write_control_register(vrlg.MEMBRIDGE_ADDR + vrlg.MEMBRIDGE_START64, start64);
......
......@@ -85,7 +85,7 @@ class X393Mem(object):
self.USE_NEGATIVE = True
return mmap.mmap(f.fileno(), self.PAGE_SIZE, offset = page_addr - (1<<32))
else:
return mmap.mmap(f.fileno(), self.PAGE_SIZE, offset = page_addr)
return mmap.mmap(f.fileno(), self.PAGE_SIZE, offset = page_addr)
def write_mem (self,addr, data,quiet=1):
......
This diff is collapsed.
......@@ -70,6 +70,8 @@ class X393Sensor(object):
Get sensor interface type by reading status register 0xfe that is set to 0 for parallel and 1 for HiSPi
@return "PAR12" or "HISPI"
"""
if self.DRY_MODE:
return SENSOR_INTERFACE_PARALLEL
return (SENSOR_INTERFACE_PARALLEL, SENSOR_INTERFACE_HISPI)[self.x393_axi_tasks.read_status(address=0xfe)] # "PAR12" , "HISPI"
def program_status_sensor_i2c( self,
......@@ -502,6 +504,18 @@ class X393Sensor(object):
@param bits16) - True - 16 bpp mode, false - 8 bpp mode (bypass gamma). Gamma-processed data
is still used for histograms
"""
try:
if (num_sensor == all) or (num_sensor[0].upper() == "A"): #all is a built-in function
for num_sensor in range(4):
self.set_sensor_mode (num_sensor = num_sensor,
hist_en = hist_en,
hist_nrst = hist_nrst,
chn_en = chn_en,
bits16 = bits16)
return
except:
pass
self.x393_axi_tasks.write_control_register(vrlg.SENSOR_GROUP_ADDR + num_sensor * vrlg.SENSOR_BASE_INC + vrlg.SENSOR_CTRL_RADDR,
self.func_sensor_mode(
hist_en = hist_en,
......
......@@ -432,7 +432,8 @@ module sens_parallel12 #(
status_generate #(
.STATUS_REG_ADDR(SENSIO_STATUS_REG),
// .PAYLOAD_BITS(15+3+STATUS_ALIVE_WIDTH) // STATUS_PAYLOAD_BITS)
.PAYLOAD_BITS(15+3+STATUS_ALIVE_WIDTH+1) // STATUS_PAYLOAD_BITS)
// .PAYLOAD_BITS(15+3+STATUS_ALIVE_WIDTH+1) // STATUS_PAYLOAD_BITS)
.PAYLOAD_BITS(26) // STATUS_PAYLOAD_BITS)
) status_generate_sens_io_i (
.rst (1'b0), // rst), // input
.clk (mclk), // input
......
......@@ -150,12 +150,14 @@ UPDATE: Xilinx docs say that (AR/AW)CACHE is ignored
reg start_write_burst_r; // next after start_write_burst_w
wire write_in_progress_w; // should go inactive last confirmed upstream cycle
reg write_in_progress;
reg [ 7:0] num_full_data = 0; // Number of full data bursts in FIFO
wire [5:0] wresp_num_in_fifo;
reg was_wresp_re=0;
wire wresp_re;
reg [ 7:0] num_full_data = 0; // Number of full data bursts in FIFO
wire inc_num_full_data = wvalid && wready && wlast;
// documentation sais : "When set, allows the priority of a transaction at the head of the WrCmdQ to be promoted if higher
// priority transactions are backed up behind it." Whqt about demotion? Assuming it is not demoted
assign sim_wr_qos = (wrQosHeadOfCmdQEn && (wr_qos_in > wr_qos_out))? wr_qos_in : wr_qos_out;
......@@ -218,8 +220,8 @@ UPDATE: Xilinx docs say that (AR/AW)CACHE is ignored
// Count full data bursts ready in FIFO
always @ (posedge rst or posedge aclk) begin
if (rst) num_full_data <=0;
else if (wvalid && wready && wlast && !start_write_burst_w) num_full_data <= num_full_data + 1;
else if (!(wvalid && wready && wlast) && start_write_burst_w) num_full_data <= num_full_data - 1;
else if ( inc_num_full_data && !start_write_burst_w) num_full_data <= num_full_data + 1;
else if (!inc_num_full_data && start_write_burst_w) num_full_data <= num_full_data - 1;
end
......
/*******************************************************************************
* Module: frame_num_sync
* Date:2016-04-28
* Author: andrey
* Description: Propagating frame number from acquisition to compressor output
*
* Copyright (c) 2016 Elphel, Inc .
* frame_num_sync.v is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* frame_num_sync.v is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/> .
*******************************************************************************/
`timescale 1ns/1ps
module frame_num_sync #(
parameter NUM_FRAME_BITS = 4,
parameter LAST_FRAME_BITS = 16,
parameter FRAME_BITS_KEEP = 4 // number of bits from mcntrl frame number used to index absolute sensor frame number
)(
input mrst,
input mclk, // for command/status
input [NUM_FRAME_BITS*4-1:0] absolute_frames, // per-channel current sensor frame number
input [3:0] first_wr_in_frame, // sensor writes first block in a frame
// input [3:0] first_rd_in_frame, // compressor gets first block in a frame
input [4*LAST_FRAME_BITS-1:0] memory_frames_sensor, // 4 channels of frame numbers as defined for memory allocation
input [4*LAST_FRAME_BITS-1:0] memory_frames_compressor, // 4 channels of frame numbers as defined for memory allocation, valid after compression (before done)
output reg [NUM_FRAME_BITS*4-1:0] compressed_frames // frame numbers valid at compressor done (TODO: keep until IRQ cleared? pointers will change anyway)
);
reg [NUM_FRAME_BITS-1:0] frames_ram0[0: (1<<FRAME_BITS_KEEP) -1];
reg [NUM_FRAME_BITS-1:0] frames_ram1[0: (1<<FRAME_BITS_KEEP) -1];
reg [NUM_FRAME_BITS-1:0] frames_ram2[0: (1<<FRAME_BITS_KEEP) -1];
reg [NUM_FRAME_BITS-1:0] frames_ram3[0: (1<<FRAME_BITS_KEEP) -1];
always @ (posedge mclk) begin
if (first_wr_in_frame[0]) frames_ram0[memory_frames_sensor[0*LAST_FRAME_BITS+:FRAME_BITS_KEEP]] <= absolute_frames[0*NUM_FRAME_BITS +: NUM_FRAME_BITS];
if (first_wr_in_frame[1]) frames_ram1[memory_frames_sensor[1*LAST_FRAME_BITS+:FRAME_BITS_KEEP]] <= absolute_frames[1*NUM_FRAME_BITS +: NUM_FRAME_BITS];
if (first_wr_in_frame[2]) frames_ram2[memory_frames_sensor[2*LAST_FRAME_BITS+:FRAME_BITS_KEEP]] <= absolute_frames[2*NUM_FRAME_BITS +: NUM_FRAME_BITS];
if (first_wr_in_frame[3]) frames_ram3[memory_frames_sensor[3*LAST_FRAME_BITS+:FRAME_BITS_KEEP]] <= absolute_frames[3*NUM_FRAME_BITS +: NUM_FRAME_BITS];
compressed_frames[0*NUM_FRAME_BITS +: NUM_FRAME_BITS] <= frames_ram0[memory_frames_compressor[0*LAST_FRAME_BITS+:FRAME_BITS_KEEP]];
compressed_frames[1*NUM_FRAME_BITS +: NUM_FRAME_BITS] <= frames_ram1[memory_frames_compressor[1*LAST_FRAME_BITS+:FRAME_BITS_KEEP]];
compressed_frames[2*NUM_FRAME_BITS +: NUM_FRAME_BITS] <= frames_ram2[memory_frames_compressor[2*LAST_FRAME_BITS+:FRAME_BITS_KEEP]];
compressed_frames[3*NUM_FRAME_BITS +: NUM_FRAME_BITS] <= frames_ram3[memory_frames_compressor[3*LAST_FRAME_BITS+:FRAME_BITS_KEEP]];
end
endmodule
// wire [4*LAST_FRAME_BITS-1:0] cmprs_frame_number_src;// input[15:0] current frame number (for multi-frame ranges) in the source (sensor) channel
......@@ -481,7 +481,9 @@ module x393 #(
wire [255:0] sens_buf_dout; // (), // output[63:0]
wire [3:0] sens_page_written; // single mclk pulse: buffer page (full or partial) is written to the memory buffer
// TODO: Add counter(s) to count sens_xfer_skipped pulses
wire [3:0] sens_xfer_skipped; // single mclk pulse on every skipped (not written) block to record error statistics
wire [3:0] sens_xfer_skipped; // single mclk pulse on every skipped (not written) block to record error statistics
wire [3:0] sens_first_wr_in_frame; // single mclk pulse on first write block in each frame
wire trigger_mode; // (), // input
wire [3:0] trig_in; // input[3:0]
......@@ -493,8 +495,8 @@ module x393 #(
// handling this pulse (should be so). Make sure parameters are applied in ASAP in single-trigger mode
wire [3:0] sof_late_mclk; // (), // output[3:0]
wire [4 * NUM_FRAME_BITS - 1:0] frame_num; // (), // input[15:0]
wire [4 * NUM_FRAME_BITS - 1:0] frame_num; // (), // input[15:0]
wire [4 * NUM_FRAME_BITS - 1:0] frame_num_compressed; // (), // input[15:0]
// signals for compressor393 (in/outs as seen for the sensor393)
// per-channel memory buffers interface
......@@ -520,6 +522,8 @@ module x393 #(
wire [3:0] cmprs_frame_done_dst; // input single-cycle pulse when the full frame (window) was transferred to/from DDR3 memory
// use as 'eot_real' in 353
wire [3:0] cmprs_suspend; // output suspend reading data for this channel - waiting for the source data
wire [4*LAST_FRAME_BITS-1:0] cmprs_frame_number_finished; // frame numbers compressed
// Timestamp messages (@mclk) - combine to a single ts_data?
wire [3:0] ts_pre_stb; // input[ 3:0] 4 compressor channels
......@@ -929,6 +933,22 @@ assign axi_grst = axi_rst_pre;
end
endgenerate
frame_num_sync #(
.NUM_FRAME_BITS(NUM_FRAME_BITS),
.LAST_FRAME_BITS(LAST_FRAME_BITS),
.FRAME_BITS_KEEP(NUM_FRAME_BITS)
) frame_num_sync_i (
.mrst (mrst), // input
.mclk (mclk), // input
.absolute_frames (frame_num), // input[15:0]
.first_wr_in_frame (sens_first_wr_in_frame), // input[3:0]
// .first_rd_in_frame (), // input[3:0]
.memory_frames_sensor (cmprs_frame_number_src), // input[63:0]
.memory_frames_compressor (cmprs_frame_number_finished), // input[63:0]
.compressed_frames (frame_num_compressed) // output[15:0]
);
cmd_seq_mux #(
.CMDSEQMUX_ADDR (CMDSEQMUX_ADDR),
.CMDSEQMUX_MASK (CMDSEQMUX_MASK),
......@@ -1298,6 +1318,8 @@ assign axi_grst = axi_rst_pre;
.sens_buf_dout (sens_buf_dout), // input[255:0]
.sens_page_written (sens_page_written), // input [3:0] single mclk pulse: buffer page (full or partial) is written to the memory buffer
.sens_xfer_skipped (sens_xfer_skipped), // output reg
.sens_first_wr_in_frame (sens_first_wr_in_frame), // single mclk pulse on first write block in each frame
// compressor interface
.cmprs_xfer_reset_page_rd (cmprs_xfer_reset_page_rd), // output[3:0]
.cmprs_buf_wpage_nxt (cmprs_buf_wpage_nxt), // output[3:0]
......@@ -1996,7 +2018,9 @@ assign axi_grst = axi_rst_pre;
.CMPRS_AFIMUX_SA_LEN (CMPRS_AFIMUX_SA_LEN),
.CMPRS_AFIMUX_WIDTH (CMPRS_AFIMUX_WIDTH),
.CMPRS_AFIMUX_CYCBITS (CMPRS_AFIMUX_CYCBITS),
.AFI_MUX_BUF_LATENCY (AFI_MUX_BUF_LATENCY)
.AFI_MUX_BUF_LATENCY (AFI_MUX_BUF_LATENCY),
.NUM_FRAME_BITS (NUM_FRAME_BITS)
`ifdef DEBUG_RING
,.DEBUG_CMD_LATENCY (DEBUG_CMD_LATENCY)
`endif
......@@ -2034,14 +2058,16 @@ assign axi_grst = axi_rst_pre;
.frame_done_dst (cmprs_frame_done_dst), // input[3:0]
.suspend (cmprs_suspend), // output[3:0]
.frame_number_finished (cmprs_frame_number_finished),// output[63:0] frame numbers compressed
.ts_pre_stb (ts_pre_stb), // input[3:0]
.ts_data (ts_data), // input[31:0]
.eof_written_mclk (eof_written_mclk), // output[3:0]
.stuffer_done_mclk (stuffer_done_mclk), // output[3:0]
.vsync_late (sof_late_mclk), // input[3:0]
.frame_num_compressed (frame_num_compressed[4 * NUM_FRAME_BITS -1 : 0]), // input[3:0]
.hclk (hclk), // input
.afi0_awaddr (afi1_awaddr), // output[31:0]
.afi0_awvalid (afi1_awvalid), // output
......
This diff is collapsed.
This diff is collapsed.
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