Commit 4152a851 authored by Andrey Filippov's avatar Andrey Filippov

cleaning up handling exceptions in compressor, adding output FIFO

parent db90602d
......@@ -132,7 +132,9 @@ module cmprs_cmd_decode#(
parameter CMPRS_CSAT_CB_BITS = 10, // number of bits in blue scale field in color saturation word
parameter CMPRS_CSAT_CR = 12, // bit # of number of red scale field in color saturation word
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_CORING_BITS = 3, // number of bits in coring mode
parameter CMPRS_STUFFER_NEG = 1 // stuffer runs @ negedge xclk2x
)(
......@@ -160,7 +162,8 @@ module cmprs_cmd_decode#(
// cmprs_run should be off
output reg sigle_frame_buf, // memory controller uses a single frame buffer (frame_number_* == 0), use other sync
// outputs sync @ posedge xclk:
output reg cmprs_en_xclk, // enable compressor, extends control fields for graceful shutdown
output reg cmprs_en_xclk, // enable compressor, turne off immedaitely
output reg cmprs_en_late_xclk, // enable stuffer, extends control fields for graceful shutdown
// cmprs_start, // single cycle when single or constant compression is turned on
// cmprs_repeat,// high in repetitive mode
// outputs @posedge xclk, frozen when the new frame is requested
......@@ -291,7 +294,8 @@ module cmprs_cmd_decode#(
// re-clock to compressor clock
always @ (posedge xclk) if (ctrl_we_xclk) begin
cmprs_en_xclk <= cmprs_en_mclk_r || cmprs_en_extend;
cmprs_en_xclk <= cmprs_en_mclk_r;
cmprs_en_late_xclk <= cmprs_en_mclk_r || cmprs_en_extend;
cmprs_qpage_xclk <= cmprs_qpage_mclk;
cmprs_dcsub_xclk <= cmprs_dcsub_mclk;
cmprs_mode_xclk <= cmprs_mode_mclk;
......
......@@ -22,7 +22,9 @@
module cmprs_frame_sync#(
parameter FRAME_HEIGHT_BITS= 16, // Maximal frame height
parameter LAST_FRAME_BITS= 16 // number of bits in frame counter (before rolls over)
parameter LAST_FRAME_BITS= 16, // number of bits in frame counter (before rolls over)
parameter CMPRS_TIMEOUT_BITS= 12,
parameter CMPRS_TIMEOUT= 1000 // mclk cycles
)(
input rst,
......@@ -54,8 +56,17 @@ module cmprs_frame_sync#(
input [LAST_FRAME_BITS-1:0] frame_number, // current frame number (for multi-frame ranges) in this (compressor channel
input frame_done, // input - single-cycle pulse when the full frame (window) was transferred to/from DDR3 memory
output reg suspend, // suspend reading data for this channel - waiting for the source data
output reg broken_frame // next frame start came before previous frame was read to compressor
input stuffer_running, // @xclk2x stuffer is running/flushing
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
);
/*
Abort frame (force flush) if:
a) "broken frame" - attempted to start a new frame before previous one was completely read from the memory
b) turned off enable while frame was being compressed
Abort frame lasts until flush end or timeout expire
*/
wire vsync_late_mclk; // single mclk cycle, reclocked from vsync_late
wire frame_started_mclk;
reg bonded_mode;
......@@ -65,9 +76,39 @@ module cmprs_frame_sync#(
reg line_numbers_sync; // src unfinished line number is > this unfinished line number
reg reading_frame; // compressor is reading frame data (make sure input is done before starting next frame, otherwise make it a broken frame
reg broken_frame;
reg aborted_frame;
reg stuffer_running_mclk;
reg [CMPRS_TIMEOUT_BITS-1:0] timeout;
reg cmprs_en_extend_r=0;
reg cmprs_en_d;
assign frame_start_dst = frame_start_dst_r;
assign cmprs_en_extend = cmprs_en_extend_r;
always @ (posedge rst or posedge mclk) begin
if (rst) cmprs_en_extend_r <= 0;
else if (cmprs_en) cmprs_en_extend_r <= 1;
else if ((timeout == 0) || !stuffer_running_mclk) cmprs_en_extend_r <= 0;
end
always @ (posedge mclk) begin
stuffer_running_mclk <= stuffer_running; // re-clock from negedge xclk2x
if (cmprs_en) timeout <= CMPRS_TIMEOUT;
else if (!cmprs_en_extend_r) timeout <= 0;
else timeout <= timeout - 1;
cmprs_en_d <= cmprs_en;
broken_frame <= cmprs_en && cmprs_run && vsync_late_mclk && reading_frame; // single xclk pulse
aborted_frame <= cmprs_en_d && !cmprs_en && stuffer_running_mclk;
if (!stuffer_running_mclk ||!cmprs_en_extend_r) force_flush_long <= 0;
else if (broken_frame || aborted_frame) force_flush_long <= 1;
if (!cmprs_en || frame_done || (cmprs_run && vsync_late_mclk)) reading_frame <= 0;
else if (frame_started_mclk) reading_frame <= 1;
frame_start_dst_r <= cmprs_en && (cmprs_run ? (vsync_late_mclk && !reading_frame) : cmprs_standalone);
if (!cmprs_en) bonded_mode <= 0;
else if (cmprs_run) bonded_mode <= 1;
......@@ -82,10 +123,6 @@ module cmprs_frame_sync#(
suspend <= !bonded_mode && ((sigle_frame_buf ? frames_differ : frames_numbers_differ) || line_numbers_sync);
if (!cmprs_en || frame_done || (cmprs_run && vsync_late_mclk)) reading_frame <= 0;
else if (frame_started_mclk) reading_frame <= 1;
broken_frame <= cmprs_en && cmprs_run && vsync_late_mclk && reading_frame; // single xclk pulse
end
......
/*******************************************************************************
* Module: cmprs_out_fifo
* Date:2015-06-25
* Author: andrey
* Description: Compressor output FIFO
*
* Copyright (c) 2015 <set up in Preferences-Verilog/VHDL Editor-Templates> .
* cmprs_out_fifo.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.
*
* cmprs_out_fifo.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 cmprs_out_fifo(
input rst, // mostly for simulation
// wclk domain
input wclk, // source clock (2x pixel clock, inverted)
input we,
input [15:0] wdata,
input wa_rst, // reset low address bits when stuffer is disabled (to make sure it is multiple of 32 bytes
input wlast, // written last 32 bytes of a frame (flush FIFO) - stuffer_done (has to be later than we)
output eof_written_wclk, // eof_written - reclocked to wclk
// rclk domain
input rclk,
input rst_fifo, // reset FIFO (set read adderss to write, reset count)
input ren,
output [63:0] rdata,
output eof, // single rclk pulse signalling EOF
input eof_written, // confirm frame written ofer AFI to the system memory (single rclk pulse)
output flush_fifo, // EOF, need to output all what is in FIFO (Stays active until enough data chunks are read)
output [7:0] fifo_count // number of 32-byte chunks in FIFO
);
reg regen;
reg [ 8:0] raddr;
reg [ 7:0] count32;
reg [ 7:0] lcount32; // counting chunks left in the same frame
reg [10:0] waddr;
wire written32b; // written 32 bytes, re-clocked to read clock domain (single-cycle)
wire wlast_rclk;
reg flush_fifo_r;
assign flush_fifo = flush_fifo_r;
assign fifo_count = count32;
assign eof = wlast_rclk;
always @ (posedge rst or posedge wclk) begin
if (rst) waddr <= 0;
else if (wa_rst) waddr <= waddr & 11'h7f0; // reset 4 LSBs only
else if (we) waddr <= waddr + 1;
end
always @ (posedge rclk) begin
regen <= ren;
if (rst_fifo) raddr <= {waddr[10:4],2'b0};
else if (ren) raddr <= raddr + 1;
if (rst_fifo) count32 <= 0;
else if ( written32b && !(ren && (&raddr[1:0]))) count32 <= count32 + 1;
else if (!written32b && (ren && (&raddr[1:0]))) count32 <= count32 - 1;
if (rst_fifo) lcount32 <= 0;
else if (wlast_rclk) lcount32 <= count32;
else if ((lcount32 !=0) && ren && (&raddr[1:0])) lcount32 <= lcount32 - 1;
if (rst_fifo) flush_fifo_r <= 0;
else if (wlast_rclk) flush_fifo_r <= 1;
else if ((count32[7:1] == 0) && ( !count32[0] || ren)) flush_fifo_r <= 0;
end
// wclk -> rclk
pulse_cross_clock written32b_i (.rst(rst), .src_clk(wclk), .dst_clk(rclk), .in_pulse(we && (&waddr[3:0])), .out_pulse(written32b),.busy());
pulse_cross_clock wlast_rclk_i (.rst(rst), .src_clk(wclk), .dst_clk(rclk), .in_pulse(wlast), .out_pulse(wlast_rclk),.busy());
// rclk -> wclk
pulse_cross_clock eof_written_wclk_i (.rst(rst), .src_clk(rclk), .dst_clk(wclk), .in_pulse(eof_written), .out_pulse(eof_written_wclk),.busy());
ram_var_w_var_r #(
.REGISTERS(1),
.LOG2WIDTH_WR(4),
.LOG2WIDTH_RD(6)
) fifo_i (
.rclk (rclk), // input
.raddr (raddr), // input[8:0]
.ren (ren), // input
.regen (regen), // input
.data_out (rdata), // output[63:0]
.wclk (wclk), // input - OK, negedge mclk
.waddr (waddr), // input[10:0]
.we (we), // input
.web (8'hff), // input[7:0]
.data_in (wdata) // input[15:0]
);
endmodule
......@@ -85,7 +85,11 @@ module jp_channel#(
parameter CMPRS_CSAT_CB_BITS = 10, // number of bits in blue scale field in color saturation word
parameter CMPRS_CSAT_CR = 12, // bit # of number of red scale field in color saturation word
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_CORING_BITS = 3, // number of bits in coring mode
parameter CMPRS_TIMEOUT_BITS= 12,
parameter CMPRS_TIMEOUT= 1000 // mclk cycles
)(
input rst,
......@@ -112,6 +116,8 @@ module jp_channel#(
output [15:0] statistics_do,
input [31:0] sec,
input [19:0] usec,
output [23:0] imgptr,
// input [ 1:0] bayer_phase, // shared with sensor channel - remove!
input vsync_late, // delayed start of frame, @xclk. In 353 it was 16 lines after VACT active
// source channel should already start, some delay give time for sequencer commands
......@@ -129,12 +135,25 @@ module jp_channel#(
input [LAST_FRAME_BITS-1:0] frame_number_dst, // current frame number (for multi-frame ranges) in this (compressor 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 suspend, // suspend reading data for this channel - waiting for the source data
// Output interface to the AFI mux
input hclk,
input fifo_rst, // reset FIFO (set read adderss to write, reset count)
input fifo_ren,
output [63:0] fifo_rdata,
output fifo_eof, // single rclk pulse signalling EOF
input eof_written, // confirm frame written ofer AFI to the system memory (single rclk pulse)
output fifo_flush, // EOF, need to output all what is in FIFO (Stays active until enough data chunks are read)
output [7:0] fifo_count // number of 32-byte chunks in FIFO
);
// Control signals to be defined
wire frame_en; // if 0 - will reset logic immediately (but not page number)
wire stuffer_en; // extended enable to allow stuffer to gracefully finish
wire frame_go=frame_en; // start frame: if idle, will start reading data (if available),
// if running - will not restart a new frame if 0.
wire [CMPRS_FRMT_LMARG_BITS-1:0] left_marg; // left margin (for not-yet-implemented) mono JPEG (8 lines tile row) can need 7 bits (mod 32 - tile)
......@@ -142,7 +161,7 @@ module jp_channel#(
wire [CMPRS_FRMT_MBRM1_BITS-1:0] n_block_rows_m1; // number of macroblock rows in a frame minus 1
wire ignore_color; // zero Cb/Cr components (TODO: maybe include into converter_type?)
wire [ 1:0] bayer_phase; // [1:0]) bayer color filter phase 0:(GR/BG), 1:(RG/GB), 2: (BG/GR), 3: (GB/RG)
wire four_blocks; // use only 6 blocks for the output, not 6
// wire four_blocks; // use only 6 blocks for the output, not 6
wire jp4_dc_improved; // in JP4 mode, compare DC coefficients to the same color ones
// wire [ 1:0] tile_margin; // margins around 16x16 tiles (0/1/2)
// wire [ 2:0] tile_shift; // tile shift from top left corner
......@@ -185,7 +204,7 @@ module jp_channel#(
// signals connecting modules: chn_rd_buf_i and ???:
wire [ 7:0] mb_data_out; // Macroblock data out in scanline order
wire mb_pre_first_out; // Macroblock data out strobe - 1 cycle just before data valid
wire mb_data_valid; // Macroblock data out valid
// wire mb_data_valid; // Macroblock data out valid
wire limit_diff = 1'b1; // as in the prototype - just a constant 1
......@@ -207,7 +226,7 @@ module jp_channel#(
wire [ 9:0] yc_nodc; // [9:0] data out (4:2:0) (signed, average=0)
wire [ 8:0] yc_avr; // [8:0] DC (average value) - RAM output, no register. For Y components 9'h080..9'h07f, for C - 9'h100..9'h0ff!
wire yc_nodc_dv; // out data valid (will go high for at least 64 cycles)
// wire yc_nodc_dv; // out data valid (will go high for at least 64 cycles)
wire dct_start; // single-cycle mark of the first_r pixel in a 64 (8x8) - pixel block
wire [ 2:0] color_tn; // [2:0] tile number 0..3 - Y, 4 - Cb, 5 - Cr (valid with start)
wire color_first; // sending first_r MCU (valid @ ds)
......@@ -228,7 +247,8 @@ module jp_channel#(
wire sigle_frame_buf; // input - memory controller uses a single frame buffer (frame_number_* == 0), use other sync
wire stuffer_done_mclk;
wire broken_frame; // @ mclk tried to start frame compression before the previous one was finished
wire force_flush_long;
wire last_block;
wire test_lbw;
......@@ -237,7 +257,7 @@ module jp_channel#(
wire [3:0] huff_dl; // output[3:0] reg
wire huff_dv; // output reg
wire flush; // output reg @ negedge xclk2x
wire force_flush; // @ negedge xclk2x
wire [31:0] cmd_data; // 32-bit data to write to tables and registers(LSB first) - from cmd_deser
......@@ -251,6 +271,21 @@ module jp_channel#(
wire set_coring_w;
wire set_tables_w;
wire stuffer_running; // @negedge xclk2x from registering timestamp until done
wire [12:0] quant_do;
wire quant_ds;
wire [15:0] quant_dc_tdo;// MSB aligned coefficient for the DC component (used in focus module)
wire [ 2:0] cmprs_qpage;
wire [ 2:0] coring_num;
reg dcc_en;
wire dccout;
wire [ 2:0] hfc_sel;
wire [15:0] dccdata; // was not used in late nc353
wire dccvld; // was not used in late nc353
assign set_ctrl_reg_w = cmd_we && (cmd_a== CMPRS_CONTROL_REG);
assign set_status_w = cmd_we && (cmd_a== CMPRS_STATUS_CNTRL);
assign set_format_w = cmd_we && (cmd_a== CMPRS_FORMAT);
......@@ -258,8 +293,6 @@ module jp_channel#(
assign set_coring_w = cmd_we && (cmd_a== CMPRS_CORING_MODE);
assign set_tables_w = cmd_we && ((cmd_a & 6)== CMPRS_TABLES);
// re-clock single-pulse broken_frame@mclk to force_flush@negedge xclk2x
pulse_cross_clock force_flush_i (.rst(rst), .src_clk(mclk), .dst_clk(~xclk2x), .in_pulse(broken_frame), .out_pulse(force_flush),.busy());
// set derived parameters from converter_type
......@@ -395,13 +428,15 @@ module jp_channel#(
.cmprs_run_mclk (cmprs_run_mclk), // output reg
.cmprs_standalone (cmprs_standalone), // output reg
.sigle_frame_buf (sigle_frame_buf), // output reg
.cmprs_en_xclk (frame_en), // output reg
.cmprs_en_xclk (frame_en), // output reg
.cmprs_en_late_xclk (stuffer_en), // output reg - extended enable to allow stuffer to gracefully finish
.cmprs_qpage (cmprs_qpage), // output[2:0] reg
.cmprs_dcsub (subtract_dc), // output reg
.cmprs_fmode (cmprs_fmode), // output[1:0] reg
.bayer_shift (bayer_phase), // output[1:0] reg
.ignore_color (ignore_color), // output reg
.four_blocks (four_blocks), // output reg Not used?
// .four_blocks (four_blocks), // output reg Not used?
.four_blocks (), // output reg Not used?
.jp4_dc_improved (jp4_dc_improved), // output reg
.converter_type (converter_type), // output[2:0] reg
.scale_diff (scale_diff), // output reg
......@@ -411,14 +446,16 @@ module jp_channel#(
.n_block_rows_m1 (n_block_rows_m1), // output[12:0] reg
.color_sat_cb (m_cb), // output[9:0] reg
.color_sat_cr (m_cr), // output[9:0] reg
.coring () // output[2:0] reg
.coring (coring_num) // output[2:0] reg
);
cmprs_frame_sync #(
.FRAME_HEIGHT_BITS (FRAME_HEIGHT_BITS),
.LAST_FRAME_BITS (LAST_FRAME_BITS)
.LAST_FRAME_BITS (LAST_FRAME_BITS),
.CMPRS_TIMEOUT_BITS (CMPRS_TIMEOUT_BITS),
.CMPRS_TIMEOUT (CMPRS_TIMEOUT)
) cmprs_frame_sync_i (
.rst (rst), // input
.xclk (xclk), // input - global clock input, compressor single clock rate
......@@ -445,10 +482,10 @@ module jp_channel#(
.frame_number (frame_number_dst), // input[15:0] - current frame number (for multi-frame ranges) in this (compressor channel
.frame_done (frame_done_dst), // input - single-cycle pulse when the full frame (window) was transferred to/from DDR3 memory
.suspend (suspend), // output reg - suspend reading data for this channel - waiting for the source data
.broken_frame (broken_frame) // output reg - @ mclk tried to start frame compression before the previous one was finished
.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
);
// 353's eot ~= broken_frame || frame_done_dst
cmprs_macroblock_buf_iface cmprs_macroblock_buf_iface_i (
.rst (rst), // input
.xclk (xclk), // input
......@@ -503,7 +540,8 @@ module jp_channel#(
.macroblock_x (macroblock_x), // input[6:0]
.data_out (mb_data_out), // output[7:0] // Macroblock data out in scanline order
.pre_first_out (mb_pre_first_out), // output // Macroblock data out strobe - 1 cycle just before data valid == old pre_first_pixel?
.data_valid (mb_data_valid) // output // Macroblock data out valid
// .data_valid (mb_data_valid) // output // Macroblock data out valid
.data_valid () // output // Macroblock data out valid Unused
);
csconvert #(
......@@ -565,7 +603,8 @@ module jp_channel#(
.signed_c (signed_c), // input[8:0]
.do (yc_nodc), // output[9:0]
.avr (yc_avr), // output[8:0]
.dv (yc_nodc_dv), // output
// .dv (yc_nodc_dv), // output
.dv (), // output unused?
.ds (dct_start), // output
.tn (color_tn), // output[2:0]
.first (color_first), // output reg
......@@ -611,18 +650,6 @@ module jp_channel#(
wire quant_start;
dly_16 #(.WIDTH(1)) i_quant_start (.clk(xclk),.rst(1'b0), .dly(0), .din(dct_pre_first_out), .dout(quant_start)); // dly=0+1
reg [ 2:0] cmprs_qpage;
wire first_block_quant;
wire [12:0] quant_do;
wire quant_ds;
wire [15:0] quant_dc_tdo;// MSB aligned coefficient for the DC component (used in focus module)
wire [ 2:0] coring_num;
reg dcc_en;
wire dccout;
wire [ 2:0] hfc_sel;
wire [15:0] dccdata; // was not used in late nc353
wire dccvld; // was not used in late nc353
always @ (posedge xclk) begin
if (!dccout) dcc_en <=1'b0;
......@@ -774,61 +801,42 @@ module jp_channel#(
.gotLastBlock(test_lbw) // output ??
);
/*
wire last_block, test_lbw;
huffman i_huffman (.pclk(clk), // pixel clock
.clk(clk2x), // twice frequency - uses negedge inside
.en(cmprs_en), // enable (0 resets counter) sync to .pclk(clk)
// .cwr(cwr), // CPU WR global clock
.twe(twhe), // enable write to a table
.ta(ta[8:0]), // [8:0] table address
.tdi(di[15:0]), // [23:0] table data in (8 LSBs - quantization data, [13:9] zigzag address
.di(enc_do[15:0]), // [15:0] specially RLL prepared 16-bit data (to FIFO)
.ds(enc_dv), // di valid strobe
.rdy(stuffer_rdy), // receiver (bit stuffer) is ready to accept data
.do(huff_do), // [15:0] output data
.dl(huff_dl), // [3:0] output width (0==16)
.dv(huff_dv), // output data bvalid
.flush(flush),
.last_block(last_block),
.test_lbw(),
.gotLastBlock(test_lbw)); // last block done - flush the rest bits
*/
wire [15:0] stuffer_do;
wire stuffer_dv;
wire stuffer_done;
reg stuffer_done_persist;
wire stuffer_flushing;
wire [23:0] imgptr;
wire [31:0] sec;
wire [19:0] usec;
// reg stuffer_done_persist;
// wire stuffer_flushing;
always @ (negedge xclk2x) pre_finish_dcc <= stuffer_done;
always @ (posedge xclk2x) finish_dcc <= pre_finish_dcc; //stuffer+done - @negedge clk2x
stuffer393 stuffer393_i (
.clk (xclk2x), // input clock - uses negedge inside
.en (cmprs_en_2x_n), // input
.en_in (stuffer_en), //
.reset_data_counters (reset_data_counters[1]), // input reset data transfer counters (only when DMA and compressor are disabled)
.flush (flush || force_flush), // input - flush output data (fill byte with 0, long word with FFs
.flush (flush), // input - flush output data (fill byte with 0, long word with FFs)
.abort (force_flush_long), // @ any, extracts 0->1 and flushes
.stb (huff_dv), // input
.dl (huff_dl), // input[3:0] number of bits to send (0 - 16) (0-16??)
.d (huff_do), // input[15:0] data to shift (only lower huff_dl bits are valid)
// time stamping - will copy time at the end of color_first (later than the first hact after vact in the current froma, but before the next one
// and before the data is needed for output
.color_first(color_first), // input
.sec(sec[31:0]), // input[31:0]
.usec(usec[19:0]), // input[19:0]
.color_first (color_first), // input valid @xclk - only for sec/usec
.sec (sec[31:0]), // input[31:0] registers to right clock/time inside
.usec (usec[19:0]), // input[19:0]
// outputs valid @negedge xclk2x
.rdy(stuffer_rdy), // output - enable huffman encoder to proceed. Used as CE for many huffman encoder registers
.q(stuffer_do), // output[15:0] reg - output data
.qv(stuffer_dv), // output reg - output data valid
.done(stuffer_done), // output
.imgptr(imgptr[23:0]), // output[23:0] reg - image pointer in 32-byte chunks
.flushing(stuffer_flushing) // output reg
.rdy (stuffer_rdy), // output - enable huffman encoder to proceed. Used as CE for many huffman encoder registers
.q (stuffer_do), // output[15:0] reg - output data
.qv (stuffer_dv), // output reg - output data valid
.done (stuffer_done), // output
.imgptr (imgptr[23:0]), // output[23:0] reg - image pointer in 32-byte chunks
// .flushing (stuffer_flushing), // output reg
.flushing (), // output reg Not used?
.running (stuffer_running) // from registering timestamp until done
`ifdef debug_stuffer
,.etrax_dma_r(tst_stuf_etrax[3:0]) // [3:0] just for testing
,.test_cntr(test_cntr[3:0])
......@@ -837,7 +845,27 @@ module jp_channel#(
);
pulse_cross_clock stuffer_done_mclk_i (.rst(rst), .src_clk(~xclk2x), .dst_clk(mclk), .in_pulse(stuffer_done), .out_pulse(stuffer_done_mclk),.busy());
wire eof_written;
cmprs_out_fifo cmprs_out_fifo_i (
.rst (rst), // input mostly for simulation
// source (stuffer) clock domain
.wclk (~xclk2x), // input source clock (2x pixel clock, inverted) - same as stuffer out
.we (stuffer_dv), // input write data from stuffer
.wdata (stuffer_do), // input[15:0] data from stuffer module;
.wa_rst (!stuffer_en), // input reset low address bits when stuffer is disabled (to make sure it is multiple of 32 bytes
.wlast (stuffer_done), // input - written last 32 bytes of a frame (flush FIFO) - stuffer_done (has to be later than we)
.eof_written_wclk (eof_written), // output - AFI had transferred frame data to the system memory
.rclk (hclk), // input - AFI clock
// AFI clock domain
.rst_fifo (fifo_rst), // input - reset FIFO (set read adderss to write, reset count)
.ren (fifo_ren), // input - fifo read from AFI channel mux
.rdata (fifo_rdata), // output[63:0] - data to AFI channel mux (latency == 2 from fifo_ren)
.eof (fifo_eof), // output single hclk pulse signalling EOF
.eof_written (eof_written), // input single hclk pulse confirming frame data is written to the system memory
.flush_fifo (fifo_flush), // output level signalling that FIFO has data from the current frame (use short AXI burst if needed)
.fifo_count (fifo_count) // output[7:0] - number of 32-byte chunks available in FIFO
);
endmodule
......@@ -43,15 +43,16 @@
module stuffer393 (
input clk, // 2x pixel clock
input en, // enable, 0- reset
input en_in, // enable, 0- reset (other clock domain, needs re-sync)
input reset_data_counters, // reset data transfer counters (only when DMA and compressor are disabled)
input flush, // flush output data (fill byte with 0, long word with 0
input abort, // @ any, extracts 0->1 and flushes
input stb, // input data strobe
input [3:0] dl, // [3:0] number of bits to send (0 - 16) ??
input [15:0] d, // [15:0] input data to shift (only lower bits are valid)
// time stamping - will copy time at the end of color_first (later than the first hact after vact in the current froma, but before the next one
// and before the data is needed for output
input color_first, //
input color_first, // (different clock) only used for timestamp
input [31:0] sec, // [31:0] number of seconds
input [19:0] usec, // [19:0] number of microseconds
output rdy, // enable huffman encoder to proceed. Used as CE for many huffman encoder registers
......@@ -60,7 +61,8 @@ module stuffer393 (
output reg qv, // output data valid
output done, // reset by !en, goes high after some delay after flushing
output reg [23:0] imgptr, // [23:0]image pointer in 32-byte chunks
output reg flushing
output reg flushing,
output reg running // from registering timestamp until done
`ifdef debug_stuffer
, output reg [3:0] etrax_dma_r, // [3:0] just for testing
output reg [3:0] test_cntr,
......@@ -71,7 +73,12 @@ module stuffer393 (
`ifdef debug_stuffer
reg en_d;
`endif
reg en; // re-clock en_in to match this clock
reg [2:0] abort_r;
reg force_flush;
reg [23:1] stage1; // stage 1 register (after right-shifting input data by 0..7 - actually left by 7..0)
wire [2:0] shift1; // shift amount for stage 1
reg [4:0] stage1_bits; // number of topmost invalid bits in stage1 register - 2 MSBs, use lower 3 stage2_bits
......@@ -127,8 +134,24 @@ module stuffer393 (
// stb_time[2] - single-cycle pulse after color_first goes low
reg [19:0] imgsz32; // current image size in multiples of 32-bytes
reg inc_imgsz32;
// re-clock enable to this clock
always @ (negedge clk) begin
en <= en_in;
// re-clock abort, extract leading edge
abort_r <= {abort_r[0] & ~abort_r[1], abort_r[0], abort};
if (!en) force_flush <= 0;
else if (abort_r) force_flush <= 1;
else if (flush_end) force_flush <= 0;
if (!en) running <= 0;
else if (stb_time[2]) running <= 1;
else if (flush_end) running <= 0;
end
always @ (negedge clk) flushing <= en && !flush_end && ((flush && rdy) || flushing);
always @ (negedge clk) begin
flushing <= en && !flush_end && (((flush || force_flush) && rdy) || flushing);
end
wire [4:0] pre_stage1_bits;
assign pre_stage1_bits[4:0]={2'b00,stage1_bits[2:0]} + {(dl[3:0]==4'b0),dl[3:0]};
......
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