Loading compressor_jp/bit_stuffer_27_32.v +38 −2 Original line number Diff line number Diff line Loading @@ -63,7 +63,7 @@ module bit_stuffer_27_32#( else ds_stage <= {ds_stage[0], ds}; if (rst) flush_stage <= 0; else flush_stage <= {flush_stage[1:0], ds}; else flush_stage <= {flush_stage[1:0], flush_in}; if (rst || flush_in) early_length <= 0; else if (ds) early_length <= early_length[4:0] + dlen; // early_length[5] is not used in calculations, it is just carry out Loading Loading @@ -91,6 +91,7 @@ module bit_stuffer_27_32#( 2'h3: data2 <= { 6'b0,data1 }; endcase if (stage[0]) case (dlen1[4:0]) /* 5'h00: dmask2_rom <= 32'hffffffff; 5'h01: dmask2_rom <= 32'hfffffffe; 5'h02: dmask2_rom <= 32'hfffffffc; Loading Loading @@ -123,6 +124,39 @@ module bit_stuffer_27_32#( 5'h1d: dmask2_rom <= 32'he0000000; 5'h1e: dmask2_rom <= 32'hc0000000; 5'h1f: dmask2_rom <= 32'h80000000; */ 5'h00: dmask2_rom <= 32'hffffffff; 5'h01: dmask2_rom <= 32'h7fffffff; 5'h02: dmask2_rom <= 32'h3fffffff; 5'h03: dmask2_rom <= 32'h1fffffff; 5'h04: dmask2_rom <= 32'h0fffffff; 5'h05: dmask2_rom <= 32'h07ffffff; 5'h06: dmask2_rom <= 32'h03ffffff; 5'h07: dmask2_rom <= 32'h01ffffff; 5'h08: dmask2_rom <= 32'h00ffffff; 5'h09: dmask2_rom <= 32'h007fffff; 5'h0a: dmask2_rom <= 32'h003fffff; 5'h0b: dmask2_rom <= 32'h001fffff; 5'h0c: dmask2_rom <= 32'h000fffff; 5'h0d: dmask2_rom <= 32'h0007ffff; 5'h0e: dmask2_rom <= 32'h0003ffff; 5'h0f: dmask2_rom <= 32'h0001ffff; 5'h10: dmask2_rom <= 32'h0000ffff; 5'h11: dmask2_rom <= 32'h00007fff; 5'h12: dmask2_rom <= 32'h00003fff; 5'h13: dmask2_rom <= 32'h00001fff; 5'h14: dmask2_rom <= 32'h00000fff; 5'h15: dmask2_rom <= 32'h000007ff; 5'h16: dmask2_rom <= 32'h000003ff; 5'h17: dmask2_rom <= 32'h000001ff; 5'h18: dmask2_rom <= 32'h000000ff; 5'h19: dmask2_rom <= 32'h0000007f; 5'h1a: dmask2_rom <= 32'h0000003f; 5'h1b: dmask2_rom <= 32'h0000001f; 5'h1c: dmask2_rom <= 32'h0000000f; 5'h1d: dmask2_rom <= 32'h00000007; 5'h1e: dmask2_rom <= 32'h00000003; 5'h1f: dmask2_rom <= 32'h00000001; endcase // barrel shifter stage 3 (0/1), combined with output/hold register if (ds_stage[1]) begin Loading @@ -131,7 +165,9 @@ module bit_stuffer_27_32#( data3[DATA3_LEN-1-32: 0] <= dlen2[0] ? data2[DATA2_LEN-31-1 : 0] : {data2[DATA2_LEN-32-1 : 0], 1'b0}; end dv <= (ds_stage[1] && dlen2[5]) || (flush_stage[1] && !(|data3[DATA3_LEN-1 -: 32])); // dv <= (ds_stage[1] && dlen2[5]) || (flush_stage[1] && !(|data3[DATA3_LEN-1 -: 32])); // dv <= (ds_stage[1] && dlen1[5]) || (flush_stage[1] && !(|data3[DATA3_LEN-1 -: 32])); dv <= (ds_stage[0] && dlen1[5]) || (flush_stage[1] && !(|data3[DATA3_LEN-1 -: 32])); if (rst || ds_stage[1]) bytes_out <= 0; // if the dv was caused by 32 bits full - output 4 bytes else if (flush_stage[1]) bytes_out <= pre_bits_out_w[4:3]; Loading compressor_jp/bit_stuffer_escape.v +3 −3 Original line number Diff line number Diff line Loading @@ -23,11 +23,11 @@ module bit_stuffer_escape( input xclk, // pixel clock, sync to incoming data input rst, // @xclk // data from external FIFO (35x16 should be OK) input [31:0] din, // input data, MSB aligned input [1:0] bytes_in, // number of bytes, valid @ ds (0 means 4) input flush_in, // end of input data (ignore din/bytes_in) input in_stb, // input data/bytes_in/flush_in strobe input in_stb, // input data/bytes_in strobe input flush_in, // end of input data output reg [31:0] d_out, // output 32-bit data output reg [1:0] bytes_out, // valid @dv(only), 0 means 4 bytes output reg dv, // output data valid Loading compressor_jp/bit_stuffer_metadata.v 0 → 100644 +160 −0 Original line number Diff line number Diff line /******************************************************************************* * Module: bit_stuffer_metadata * Date:2015-10-25 * Author: andrey * Description: * * Copyright (c) 2015 Elphel, Inc . * bit_stuffer_metadata.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. * * bit_stuffer_metadata.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 bit_stuffer_metadata( input mclk, input mrst, // @posedge mclk, sync reset input xclk, input xrst, // @posedge xclk, sync reset input last_block, // use it to copy timestamp from fifo // time stamping - will copy time at the end of color_first (later than the first hact after vact in the current frame, but before the next one // and before the data is needed for output input ts_pre_stb, // @mclk - 1 cycle before receiving 8 bytes of timestamp data input [7:0] ts_data, // timestamp data (s0,s1,s2,s3,us0,us1,us2,us3==0) input color_first, // @fradv_clk only used for timestamp input [31:0] din, // input data, MSB aligned input [1:0] bytes_in, // number of bytes, valid @ ds (0 means 4) input in_stb, // input data/bytes_in strobe input flush, // end of input data input abort, // @ any, extracts 0->1 and flushes // outputs @ negedge clk output reg [31:0] data_out, // [31:0] output data output reg data_out_valid,// output data valid output reg done, // reset by !en, goes high after some delay after flushing output reg running // from registering timestamp until done `ifdef DEBUG_RING , output reg [3:0] dbg_etrax_dma ,output dbg_ts_rstb ,output [7:0] dbg_ts_dout `endif ); reg [7:0] time_ram0[0:3]; // 0 - seconds, 1 - microseconds MSB in the output 32-bit word, byt LSB of the sec/usec reg [7:0] time_ram1[0:3]; reg [7:0] time_ram2[0:3]; reg [7:0] time_ram3[0:3]; reg [3:0] ts_in=8; reg last_block_d; // last_block delayed by one clock reg color_first_r; reg [2:0] abort_r; reg force_flush; // reg color_first_r; // registered with the same clock as color_first to extract leading edge // stb_time[2] - single-cycle pulse after color_first goes low // reg [19:0] imgsz32; // current image size in multiples of 32-bytes reg [21:0] imgsz4; // current image size in multiples of 4-bytes reg last_stb_4; // last stb_in was 4 bytes reg trailer; reg meta_out; reg [1:0] meta_word; reg zeros_out; // output of 32 bytes (8 words) of zeros wire trailer_done = (imgsz4[2:0] == 7) && zeros_out; wire meta_last = (imgsz4[2:0] == 7) && meta_out; // re-clock enable to this clock wire ts_rstb= last_block && !last_block_d; // enough time to have timestamp data; // one cycle before getting timestamp data from FIFO wire [7:0] ts_dout; // timestamp data, byte at a time wire write_size = (in_stb && (bytes_in != 0)) || (flush && last_stb_4); wire stb_start = !color_first && color_first_r; wire stb = in_stb & !trailer && !force_flush; always @ (posedge xclk) begin if (xrst ||trailer_done) imgsz4 <= 0; else if (stb || trailer) imgsz4 <= imgsz4 + 1; if (stb) last_stb_4 <= (bytes_in == 0); last_block_d <= last_block; color_first_r <= color_first; if (xrst) ts_in <= 8; else if (ts_rstb) ts_in <= 0; else if (!ts_in[3]) ts_in <= ts_in + 1; if ((ts_in[3] && (ts_in[1:0] == 0)) || write_size) time_ram0[ts_in[3:2]] <= ts_in[3]? ({imgsz4[5:0],flush?2'b0:bytes_in}):ts_dout; //ts_in[3:2] == 2'b10 when write_size if ((ts_in[3] && (ts_in[1:0] == 1)) || write_size) time_ram1[ts_in[3:2]] <= ts_in[3]? (imgsz4[13:6]):ts_dout; if ((ts_in[3] && (ts_in[1:0] == 2)) || write_size) time_ram2[ts_in[3:2]] <= ts_in[3]? (imgsz4[21:14]):ts_dout; if ((ts_in[3] && (ts_in[1:0] == 3)) || write_size) time_ram3[ts_in[3:2]] <= ts_in[3]? (8'hff):ts_dout; if (xrst) trailer <= 0; else if (flush || force_flush) trailer <= 1; else if (trailer_done) trailer <= 0; if (xrst) meta_out <= 0; else if ((flush || trailer) && (imgsz4[2:0] == 4)) meta_out <= 1; else if (meta_last) meta_out <= 0; if (!meta_out) meta_word <= 0; else meta_word <= meta_word + 1; if (xrst) zeros_out <= 0; else if (meta_last) zeros_out <= 1; else if (trailer_done) zeros_out <= 0; data_out <= ({32{stb}} & din) | ({32{meta_out}} & {time_ram0[meta_word],time_ram1[meta_word],time_ram2[meta_word],time_ram3[meta_word]}); data_out_valid <= stb || trailer; if (xrst) running <= 0; else if (stb_start) running <= 1; else if (trailer) running <= 0; done <= trailer_done; // re-clock abort, extract leading edge abort_r <= {abort_r[0] & ~abort_r[1], abort_r[0], abort & ~trailer}; if (xrst || trailer) force_flush <= 0; else if (abort_r) force_flush <= 1; end // just for testing `ifdef DEBUG_RING assign dbg_ = ts_rstb; assign dbg_ts_dout = ts_dout; always @ (posedge xclk) begin dbg_etrax_dma <= imgsz4[3:0]; end `endif //color_first && color_first_r timestamp_fifo timestamp_fifo_i ( .sclk (mclk), // input .srst (mrst), // input .pre_stb (ts_pre_stb), // input .din (ts_data), // input[7:0] .aclk (xclk), //fradv_clk), // input .arst (xrst), //fradv_clk), // input .advance (stb_start), // triggers at the 0->1 .rclk (xclk), // input .rrst (xrst), //fradv_clk), // input .rstb (ts_rstb), // input .dout (ts_dout) // output[7:0] reg ); endmodule compressor_jp/huffman_snglclk.v +26 −16 Original line number Diff line number Diff line Loading @@ -25,7 +25,6 @@ ** */ `include "system_defines.vh" // 01/22/2004 - extended flush until ready (modified stuffer.v too) module huffman_snglclk ( input xclk, // pixel clock, sync to incoming data input rst, // @xclk Loading @@ -47,15 +46,16 @@ module huffman_snglclk ( output last_block, output reg test_lbw, output gotLastBlock, // last block done - flush the rest bits input clk_flush, // other clock to generate synchronized 1-cycle flush_clk output output flush_clk, // 1-cycle flush output @ clk_flush // input clk_flush, // other clock to generate synchronized 1-cycle flush_clk output // output flush_clk, // 1-cycle flush output @ clk_flush output fifo_or_full // FIFO output register full - just for debuging ); // A small input FIFO, only needed for RLL >16 that require several clock cycles to output reg fifo_re; reg fifo_re_r; wire fifo_rdy; wire fifo_re = fifo_re_r && fifo_rdy; wire [15:0] fifo_out; fifo_same_clock #( .DATA_WIDTH(16), Loading @@ -80,8 +80,8 @@ module huffman_snglclk ( wire gotLastWord= !fifo_out[14] && fifo_out[12] && fifo_re; // (AC or RLL) and last bit set wire gotColor= fifo_out[13]; reg [5:0] rll; // 2 MSBs - counter to send "f0" codes reg [3:0] rll1; // valid at cycle "1" reg [3:0] rll2; // valid at cycle "1" // reg [3:0] rll1; // valid at cycle "1" wire [3:0] rll_late; // match AC's length timing reg [2:0] gotAC_r; reg [2:0] gotDC_r; reg [2:0] gotEOB_r; Loading Loading @@ -109,8 +109,8 @@ module huffman_snglclk ( assign fifo_or_full = fifo_rdy; always @(posedge xclk) begin if (rst) fifo_re <= 0; else fifo_re <= fifo_rdy && !(fifo_re && gotRLL) && !(|rll[5:4]); if (rst) fifo_re_r <= 0; else fifo_re_r <= fifo_rdy && !(fifo_re && gotRLL) && !(|rll[5:4]); if (rst) gotAC_r <= 0; else gotAC_r <= {gotAC_r[1:0], gotAC && fifo_re}; Loading @@ -132,8 +132,8 @@ module huffman_snglclk ( if (rst) rll[3:0] <= 0; else if (fifo_re) rll[3:0] <= gotRLL ? fifo_out[3:0] : 4'b0; rll1 <= rll[3:0]; rll2 <= rll1; // rll1 <= rll[3:0]; // rll_late <= rll1; if (rst) gotF0_r[2:1] <= 0; else gotF0_r[2:1] <= {gotF0_r[1], (|rll[5:4])}; Loading @@ -145,7 +145,7 @@ module huffman_snglclk ( htable_addr[7:0] <= ({8{gotEOB_r[2]}} & 8'h0 ) | // generate 00 code (end of block) ({8{gotF0_r[2]}} & 8'hf0 ) | // generate f0 code (16 zeros) ({8{gotDC_r[2]}} & {val_length[3:0], 4'hf}) | ({8{gotAC_r[2]}} & {rll2[3:0], val_length[3:0]}); ({8{gotAC_r[2]}} & {rll_late[3:0], val_length[3:0]}); if (rst) htable_re <= 0; else htable_re <= {htable_re[1:0], gotEOB_r[2] | gotF0_r[2] | gotDC_r[2] | gotAC_r[2]}; Loading Loading @@ -195,7 +195,7 @@ module huffman_snglclk ( ); ram18_var_w_var_r #( .REGISTERS(0), .REGISTERS(1), .LOG2WIDTH_WR(4), .LOG2WIDTH_RD(5), .DUMMY(0) Loading Loading @@ -235,6 +235,16 @@ module huffman_snglclk ( .dout (val_length_late) // output[0:0] ); dly_16 #( .WIDTH(4) ) dly_16_rll_late_i ( .clk (xclk), // input .rst (rst), // input .dly (4'h2), // input[3:0] .din (rll[3:0]), // input[0:0] .dout (rll_late) // output[0:0] ); huffman_merge_code_literal huffman_merge_code_literal_i ( .clk (xclk), // input .in_valid (htable_re[2]), // input Loading @@ -246,7 +256,7 @@ module huffman_snglclk ( .out_bits (do27), // output[26:0] reg .out_len (dl) // output[4:0] reg ); /* pulse_cross_clock flush_clk_i ( .rst (rst), .src_clk (xclk), Loading @@ -255,6 +265,6 @@ module huffman_snglclk ( .out_pulse (flush_clk), .busy ()); */ endmodule compressor_jp/huffman_stuffer_meta.v 0 → 100644 +151 −0 Original line number Diff line number Diff line /******************************************************************************* * Module: huffman_stuffer_meta * Date:2015-10-26 * Author: andrey * Description: Huffman encoder, bit stuffer, inser meta-data * "New" part of the JPEG/JP4 comressor that used double frequency clock * * Copyright (c) 2015 Elphel, Inc . * huffman_stuffer_meta.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. * * huffman_stuffer_meta.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 huffman_stuffer_meta( input mclk, // system clock to write tables input mrst, input xclk, // pixel clock, sync to incoming data input en_huffman, // @xclk input en_stuffer, // @xclk input abort_stuffer, // @ any // Interface to program Huffman tables input tser_we, // enable write to a table input tser_a_not_d, // address/not data distributed to submodules input [ 7:0] tser_d, // byte-wide serialized tables address/data to submodules // Input data input [15:0] di, // [15:0] specially RLL prepared 16-bit data (to FIFO) (sync to xclk) input ds, // di valid strobe (sync to xclk) // time stamping - will copy time at the end of color_first (later than the first hact after vact in the current frame, but before the next one // and before the data is needed for output input ts_pre_stb, // @mclk - 1 cycle before receiving 8 bytes of timestamp data input [7:0] ts_data, // timestamp data (s0,s1,s2,s3,us0,us1,us2,us3==0) input color_first, // @fradv_clk only used for timestamp // outputs @ negedge clk output [31:0] data_out, // [31:0] output data output data_out_valid,// output data valid output done, // reset by !en, goes high after some delay after flushing output running // from registering timestamp until done `ifdef DEBUG_RING ,output test_lbw, output gotLastBlock, // last block done - flush the rest bits output [3:0] dbg_etrax_dma ,output dbg_ts_rstb ,output [7:0] dbg_ts_dout `endif ); wire [26:0] huffman_do27; wire [4:0] huffman_dl; wire huffman_dv; wire huffman_flush; wire huffman_last_block; wire [31:0] stuffer_do32; wire [1:0] stuffer_bytes; wire stuffer_dv; wire stuffer_flush_out; wire [31:0] escape_do32; wire [1:0] escape_bytes; wire escape_dv; wire escape_flush_out; huffman_snglclk huffman_snglclk_i ( .xclk (xclk), // input .rst (~en_huffman), // input .mclk (mclk), // input .tser_we (tser_we), // input .tser_a_not_d (tser_a_not_d), // input .tser_d (tser_d), // input[7:0] .di (di), // input[15:0] .ds (ds), // input .do27 (huffman_do27), // output[26:0] .dl (huffman_dl), // output[4:0] .dv (huffman_dv), // output .flush (huffman_flush), // output .last_block (huffman_last_block), // output `ifdef DEBUG_RING .test_lbw (test_lbw), .gotLastBlock (gotLastBlock), // last block done - flush the rest bits `else .test_lbw (), .gotLastBlock (), // last block done - flush the rest bits `endif // .clk_flush(), // input // .flush_clk(), // output .fifo_or_full() // output ); bit_stuffer_27_32 #( .DIN_LEN(27) ) bit_stuffer_27_32_i ( .xclk (xclk), // input .rst (~en_huffman), // input .din (huffman_do27), // input[26:0] .dlen (huffman_dl), // input[4:0] .ds (huffman_dv), // input .flush_in (huffman_flush), // input .d_out (stuffer_do32), // output[31:0] .bytes_out (stuffer_bytes), // output[1:0] reg .dv (stuffer_dv), // output reg .flush_out (stuffer_flush_out) // output reg ); bit_stuffer_escape bit_stuffer_escape_i ( .xclk (xclk), // input .rst (~en_huffman), // input .din (stuffer_do32), // input[31:0] .bytes_in (stuffer_bytes), // input[1:0] .in_stb (stuffer_dv), // input .flush_in (stuffer_flush_out), // input .d_out (escape_do32), // output[31:0] reg .bytes_out (escape_bytes), // output[1:0] reg .dv (escape_dv), // output reg .flush_out (escape_flush_out) // output reg ); bit_stuffer_metadata bit_stuffer_metadata_i ( .mclk (mclk), // input .mrst (mrst), // input .xclk (xclk), // input .xrst (~en_stuffer), // input .last_block (huffman_last_block), // input .ts_pre_stb (ts_pre_stb), // input .ts_data (ts_data), // input[7:0] .color_first (color_first), // input .din (escape_do32), // input[31:0] .bytes_in (escape_bytes), // input[1:0] .in_stb (escape_dv), // input .flush (escape_flush_out), // input .abort (abort_stuffer), // input .data_out (data_out), // output[31:0] reg .data_out_valid (data_out_valid), // output reg .done (done), // output reg .running (running) // output reg ); endmodule Loading
compressor_jp/bit_stuffer_27_32.v +38 −2 Original line number Diff line number Diff line Loading @@ -63,7 +63,7 @@ module bit_stuffer_27_32#( else ds_stage <= {ds_stage[0], ds}; if (rst) flush_stage <= 0; else flush_stage <= {flush_stage[1:0], ds}; else flush_stage <= {flush_stage[1:0], flush_in}; if (rst || flush_in) early_length <= 0; else if (ds) early_length <= early_length[4:0] + dlen; // early_length[5] is not used in calculations, it is just carry out Loading Loading @@ -91,6 +91,7 @@ module bit_stuffer_27_32#( 2'h3: data2 <= { 6'b0,data1 }; endcase if (stage[0]) case (dlen1[4:0]) /* 5'h00: dmask2_rom <= 32'hffffffff; 5'h01: dmask2_rom <= 32'hfffffffe; 5'h02: dmask2_rom <= 32'hfffffffc; Loading Loading @@ -123,6 +124,39 @@ module bit_stuffer_27_32#( 5'h1d: dmask2_rom <= 32'he0000000; 5'h1e: dmask2_rom <= 32'hc0000000; 5'h1f: dmask2_rom <= 32'h80000000; */ 5'h00: dmask2_rom <= 32'hffffffff; 5'h01: dmask2_rom <= 32'h7fffffff; 5'h02: dmask2_rom <= 32'h3fffffff; 5'h03: dmask2_rom <= 32'h1fffffff; 5'h04: dmask2_rom <= 32'h0fffffff; 5'h05: dmask2_rom <= 32'h07ffffff; 5'h06: dmask2_rom <= 32'h03ffffff; 5'h07: dmask2_rom <= 32'h01ffffff; 5'h08: dmask2_rom <= 32'h00ffffff; 5'h09: dmask2_rom <= 32'h007fffff; 5'h0a: dmask2_rom <= 32'h003fffff; 5'h0b: dmask2_rom <= 32'h001fffff; 5'h0c: dmask2_rom <= 32'h000fffff; 5'h0d: dmask2_rom <= 32'h0007ffff; 5'h0e: dmask2_rom <= 32'h0003ffff; 5'h0f: dmask2_rom <= 32'h0001ffff; 5'h10: dmask2_rom <= 32'h0000ffff; 5'h11: dmask2_rom <= 32'h00007fff; 5'h12: dmask2_rom <= 32'h00003fff; 5'h13: dmask2_rom <= 32'h00001fff; 5'h14: dmask2_rom <= 32'h00000fff; 5'h15: dmask2_rom <= 32'h000007ff; 5'h16: dmask2_rom <= 32'h000003ff; 5'h17: dmask2_rom <= 32'h000001ff; 5'h18: dmask2_rom <= 32'h000000ff; 5'h19: dmask2_rom <= 32'h0000007f; 5'h1a: dmask2_rom <= 32'h0000003f; 5'h1b: dmask2_rom <= 32'h0000001f; 5'h1c: dmask2_rom <= 32'h0000000f; 5'h1d: dmask2_rom <= 32'h00000007; 5'h1e: dmask2_rom <= 32'h00000003; 5'h1f: dmask2_rom <= 32'h00000001; endcase // barrel shifter stage 3 (0/1), combined with output/hold register if (ds_stage[1]) begin Loading @@ -131,7 +165,9 @@ module bit_stuffer_27_32#( data3[DATA3_LEN-1-32: 0] <= dlen2[0] ? data2[DATA2_LEN-31-1 : 0] : {data2[DATA2_LEN-32-1 : 0], 1'b0}; end dv <= (ds_stage[1] && dlen2[5]) || (flush_stage[1] && !(|data3[DATA3_LEN-1 -: 32])); // dv <= (ds_stage[1] && dlen2[5]) || (flush_stage[1] && !(|data3[DATA3_LEN-1 -: 32])); // dv <= (ds_stage[1] && dlen1[5]) || (flush_stage[1] && !(|data3[DATA3_LEN-1 -: 32])); dv <= (ds_stage[0] && dlen1[5]) || (flush_stage[1] && !(|data3[DATA3_LEN-1 -: 32])); if (rst || ds_stage[1]) bytes_out <= 0; // if the dv was caused by 32 bits full - output 4 bytes else if (flush_stage[1]) bytes_out <= pre_bits_out_w[4:3]; Loading
compressor_jp/bit_stuffer_escape.v +3 −3 Original line number Diff line number Diff line Loading @@ -23,11 +23,11 @@ module bit_stuffer_escape( input xclk, // pixel clock, sync to incoming data input rst, // @xclk // data from external FIFO (35x16 should be OK) input [31:0] din, // input data, MSB aligned input [1:0] bytes_in, // number of bytes, valid @ ds (0 means 4) input flush_in, // end of input data (ignore din/bytes_in) input in_stb, // input data/bytes_in/flush_in strobe input in_stb, // input data/bytes_in strobe input flush_in, // end of input data output reg [31:0] d_out, // output 32-bit data output reg [1:0] bytes_out, // valid @dv(only), 0 means 4 bytes output reg dv, // output data valid Loading
compressor_jp/bit_stuffer_metadata.v 0 → 100644 +160 −0 Original line number Diff line number Diff line /******************************************************************************* * Module: bit_stuffer_metadata * Date:2015-10-25 * Author: andrey * Description: * * Copyright (c) 2015 Elphel, Inc . * bit_stuffer_metadata.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. * * bit_stuffer_metadata.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 bit_stuffer_metadata( input mclk, input mrst, // @posedge mclk, sync reset input xclk, input xrst, // @posedge xclk, sync reset input last_block, // use it to copy timestamp from fifo // time stamping - will copy time at the end of color_first (later than the first hact after vact in the current frame, but before the next one // and before the data is needed for output input ts_pre_stb, // @mclk - 1 cycle before receiving 8 bytes of timestamp data input [7:0] ts_data, // timestamp data (s0,s1,s2,s3,us0,us1,us2,us3==0) input color_first, // @fradv_clk only used for timestamp input [31:0] din, // input data, MSB aligned input [1:0] bytes_in, // number of bytes, valid @ ds (0 means 4) input in_stb, // input data/bytes_in strobe input flush, // end of input data input abort, // @ any, extracts 0->1 and flushes // outputs @ negedge clk output reg [31:0] data_out, // [31:0] output data output reg data_out_valid,// output data valid output reg done, // reset by !en, goes high after some delay after flushing output reg running // from registering timestamp until done `ifdef DEBUG_RING , output reg [3:0] dbg_etrax_dma ,output dbg_ts_rstb ,output [7:0] dbg_ts_dout `endif ); reg [7:0] time_ram0[0:3]; // 0 - seconds, 1 - microseconds MSB in the output 32-bit word, byt LSB of the sec/usec reg [7:0] time_ram1[0:3]; reg [7:0] time_ram2[0:3]; reg [7:0] time_ram3[0:3]; reg [3:0] ts_in=8; reg last_block_d; // last_block delayed by one clock reg color_first_r; reg [2:0] abort_r; reg force_flush; // reg color_first_r; // registered with the same clock as color_first to extract leading edge // stb_time[2] - single-cycle pulse after color_first goes low // reg [19:0] imgsz32; // current image size in multiples of 32-bytes reg [21:0] imgsz4; // current image size in multiples of 4-bytes reg last_stb_4; // last stb_in was 4 bytes reg trailer; reg meta_out; reg [1:0] meta_word; reg zeros_out; // output of 32 bytes (8 words) of zeros wire trailer_done = (imgsz4[2:0] == 7) && zeros_out; wire meta_last = (imgsz4[2:0] == 7) && meta_out; // re-clock enable to this clock wire ts_rstb= last_block && !last_block_d; // enough time to have timestamp data; // one cycle before getting timestamp data from FIFO wire [7:0] ts_dout; // timestamp data, byte at a time wire write_size = (in_stb && (bytes_in != 0)) || (flush && last_stb_4); wire stb_start = !color_first && color_first_r; wire stb = in_stb & !trailer && !force_flush; always @ (posedge xclk) begin if (xrst ||trailer_done) imgsz4 <= 0; else if (stb || trailer) imgsz4 <= imgsz4 + 1; if (stb) last_stb_4 <= (bytes_in == 0); last_block_d <= last_block; color_first_r <= color_first; if (xrst) ts_in <= 8; else if (ts_rstb) ts_in <= 0; else if (!ts_in[3]) ts_in <= ts_in + 1; if ((ts_in[3] && (ts_in[1:0] == 0)) || write_size) time_ram0[ts_in[3:2]] <= ts_in[3]? ({imgsz4[5:0],flush?2'b0:bytes_in}):ts_dout; //ts_in[3:2] == 2'b10 when write_size if ((ts_in[3] && (ts_in[1:0] == 1)) || write_size) time_ram1[ts_in[3:2]] <= ts_in[3]? (imgsz4[13:6]):ts_dout; if ((ts_in[3] && (ts_in[1:0] == 2)) || write_size) time_ram2[ts_in[3:2]] <= ts_in[3]? (imgsz4[21:14]):ts_dout; if ((ts_in[3] && (ts_in[1:0] == 3)) || write_size) time_ram3[ts_in[3:2]] <= ts_in[3]? (8'hff):ts_dout; if (xrst) trailer <= 0; else if (flush || force_flush) trailer <= 1; else if (trailer_done) trailer <= 0; if (xrst) meta_out <= 0; else if ((flush || trailer) && (imgsz4[2:0] == 4)) meta_out <= 1; else if (meta_last) meta_out <= 0; if (!meta_out) meta_word <= 0; else meta_word <= meta_word + 1; if (xrst) zeros_out <= 0; else if (meta_last) zeros_out <= 1; else if (trailer_done) zeros_out <= 0; data_out <= ({32{stb}} & din) | ({32{meta_out}} & {time_ram0[meta_word],time_ram1[meta_word],time_ram2[meta_word],time_ram3[meta_word]}); data_out_valid <= stb || trailer; if (xrst) running <= 0; else if (stb_start) running <= 1; else if (trailer) running <= 0; done <= trailer_done; // re-clock abort, extract leading edge abort_r <= {abort_r[0] & ~abort_r[1], abort_r[0], abort & ~trailer}; if (xrst || trailer) force_flush <= 0; else if (abort_r) force_flush <= 1; end // just for testing `ifdef DEBUG_RING assign dbg_ = ts_rstb; assign dbg_ts_dout = ts_dout; always @ (posedge xclk) begin dbg_etrax_dma <= imgsz4[3:0]; end `endif //color_first && color_first_r timestamp_fifo timestamp_fifo_i ( .sclk (mclk), // input .srst (mrst), // input .pre_stb (ts_pre_stb), // input .din (ts_data), // input[7:0] .aclk (xclk), //fradv_clk), // input .arst (xrst), //fradv_clk), // input .advance (stb_start), // triggers at the 0->1 .rclk (xclk), // input .rrst (xrst), //fradv_clk), // input .rstb (ts_rstb), // input .dout (ts_dout) // output[7:0] reg ); endmodule
compressor_jp/huffman_snglclk.v +26 −16 Original line number Diff line number Diff line Loading @@ -25,7 +25,6 @@ ** */ `include "system_defines.vh" // 01/22/2004 - extended flush until ready (modified stuffer.v too) module huffman_snglclk ( input xclk, // pixel clock, sync to incoming data input rst, // @xclk Loading @@ -47,15 +46,16 @@ module huffman_snglclk ( output last_block, output reg test_lbw, output gotLastBlock, // last block done - flush the rest bits input clk_flush, // other clock to generate synchronized 1-cycle flush_clk output output flush_clk, // 1-cycle flush output @ clk_flush // input clk_flush, // other clock to generate synchronized 1-cycle flush_clk output // output flush_clk, // 1-cycle flush output @ clk_flush output fifo_or_full // FIFO output register full - just for debuging ); // A small input FIFO, only needed for RLL >16 that require several clock cycles to output reg fifo_re; reg fifo_re_r; wire fifo_rdy; wire fifo_re = fifo_re_r && fifo_rdy; wire [15:0] fifo_out; fifo_same_clock #( .DATA_WIDTH(16), Loading @@ -80,8 +80,8 @@ module huffman_snglclk ( wire gotLastWord= !fifo_out[14] && fifo_out[12] && fifo_re; // (AC or RLL) and last bit set wire gotColor= fifo_out[13]; reg [5:0] rll; // 2 MSBs - counter to send "f0" codes reg [3:0] rll1; // valid at cycle "1" reg [3:0] rll2; // valid at cycle "1" // reg [3:0] rll1; // valid at cycle "1" wire [3:0] rll_late; // match AC's length timing reg [2:0] gotAC_r; reg [2:0] gotDC_r; reg [2:0] gotEOB_r; Loading Loading @@ -109,8 +109,8 @@ module huffman_snglclk ( assign fifo_or_full = fifo_rdy; always @(posedge xclk) begin if (rst) fifo_re <= 0; else fifo_re <= fifo_rdy && !(fifo_re && gotRLL) && !(|rll[5:4]); if (rst) fifo_re_r <= 0; else fifo_re_r <= fifo_rdy && !(fifo_re && gotRLL) && !(|rll[5:4]); if (rst) gotAC_r <= 0; else gotAC_r <= {gotAC_r[1:0], gotAC && fifo_re}; Loading @@ -132,8 +132,8 @@ module huffman_snglclk ( if (rst) rll[3:0] <= 0; else if (fifo_re) rll[3:0] <= gotRLL ? fifo_out[3:0] : 4'b0; rll1 <= rll[3:0]; rll2 <= rll1; // rll1 <= rll[3:0]; // rll_late <= rll1; if (rst) gotF0_r[2:1] <= 0; else gotF0_r[2:1] <= {gotF0_r[1], (|rll[5:4])}; Loading @@ -145,7 +145,7 @@ module huffman_snglclk ( htable_addr[7:0] <= ({8{gotEOB_r[2]}} & 8'h0 ) | // generate 00 code (end of block) ({8{gotF0_r[2]}} & 8'hf0 ) | // generate f0 code (16 zeros) ({8{gotDC_r[2]}} & {val_length[3:0], 4'hf}) | ({8{gotAC_r[2]}} & {rll2[3:0], val_length[3:0]}); ({8{gotAC_r[2]}} & {rll_late[3:0], val_length[3:0]}); if (rst) htable_re <= 0; else htable_re <= {htable_re[1:0], gotEOB_r[2] | gotF0_r[2] | gotDC_r[2] | gotAC_r[2]}; Loading Loading @@ -195,7 +195,7 @@ module huffman_snglclk ( ); ram18_var_w_var_r #( .REGISTERS(0), .REGISTERS(1), .LOG2WIDTH_WR(4), .LOG2WIDTH_RD(5), .DUMMY(0) Loading Loading @@ -235,6 +235,16 @@ module huffman_snglclk ( .dout (val_length_late) // output[0:0] ); dly_16 #( .WIDTH(4) ) dly_16_rll_late_i ( .clk (xclk), // input .rst (rst), // input .dly (4'h2), // input[3:0] .din (rll[3:0]), // input[0:0] .dout (rll_late) // output[0:0] ); huffman_merge_code_literal huffman_merge_code_literal_i ( .clk (xclk), // input .in_valid (htable_re[2]), // input Loading @@ -246,7 +256,7 @@ module huffman_snglclk ( .out_bits (do27), // output[26:0] reg .out_len (dl) // output[4:0] reg ); /* pulse_cross_clock flush_clk_i ( .rst (rst), .src_clk (xclk), Loading @@ -255,6 +265,6 @@ module huffman_snglclk ( .out_pulse (flush_clk), .busy ()); */ endmodule
compressor_jp/huffman_stuffer_meta.v 0 → 100644 +151 −0 Original line number Diff line number Diff line /******************************************************************************* * Module: huffman_stuffer_meta * Date:2015-10-26 * Author: andrey * Description: Huffman encoder, bit stuffer, inser meta-data * "New" part of the JPEG/JP4 comressor that used double frequency clock * * Copyright (c) 2015 Elphel, Inc . * huffman_stuffer_meta.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. * * huffman_stuffer_meta.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 huffman_stuffer_meta( input mclk, // system clock to write tables input mrst, input xclk, // pixel clock, sync to incoming data input en_huffman, // @xclk input en_stuffer, // @xclk input abort_stuffer, // @ any // Interface to program Huffman tables input tser_we, // enable write to a table input tser_a_not_d, // address/not data distributed to submodules input [ 7:0] tser_d, // byte-wide serialized tables address/data to submodules // Input data input [15:0] di, // [15:0] specially RLL prepared 16-bit data (to FIFO) (sync to xclk) input ds, // di valid strobe (sync to xclk) // time stamping - will copy time at the end of color_first (later than the first hact after vact in the current frame, but before the next one // and before the data is needed for output input ts_pre_stb, // @mclk - 1 cycle before receiving 8 bytes of timestamp data input [7:0] ts_data, // timestamp data (s0,s1,s2,s3,us0,us1,us2,us3==0) input color_first, // @fradv_clk only used for timestamp // outputs @ negedge clk output [31:0] data_out, // [31:0] output data output data_out_valid,// output data valid output done, // reset by !en, goes high after some delay after flushing output running // from registering timestamp until done `ifdef DEBUG_RING ,output test_lbw, output gotLastBlock, // last block done - flush the rest bits output [3:0] dbg_etrax_dma ,output dbg_ts_rstb ,output [7:0] dbg_ts_dout `endif ); wire [26:0] huffman_do27; wire [4:0] huffman_dl; wire huffman_dv; wire huffman_flush; wire huffman_last_block; wire [31:0] stuffer_do32; wire [1:0] stuffer_bytes; wire stuffer_dv; wire stuffer_flush_out; wire [31:0] escape_do32; wire [1:0] escape_bytes; wire escape_dv; wire escape_flush_out; huffman_snglclk huffman_snglclk_i ( .xclk (xclk), // input .rst (~en_huffman), // input .mclk (mclk), // input .tser_we (tser_we), // input .tser_a_not_d (tser_a_not_d), // input .tser_d (tser_d), // input[7:0] .di (di), // input[15:0] .ds (ds), // input .do27 (huffman_do27), // output[26:0] .dl (huffman_dl), // output[4:0] .dv (huffman_dv), // output .flush (huffman_flush), // output .last_block (huffman_last_block), // output `ifdef DEBUG_RING .test_lbw (test_lbw), .gotLastBlock (gotLastBlock), // last block done - flush the rest bits `else .test_lbw (), .gotLastBlock (), // last block done - flush the rest bits `endif // .clk_flush(), // input // .flush_clk(), // output .fifo_or_full() // output ); bit_stuffer_27_32 #( .DIN_LEN(27) ) bit_stuffer_27_32_i ( .xclk (xclk), // input .rst (~en_huffman), // input .din (huffman_do27), // input[26:0] .dlen (huffman_dl), // input[4:0] .ds (huffman_dv), // input .flush_in (huffman_flush), // input .d_out (stuffer_do32), // output[31:0] .bytes_out (stuffer_bytes), // output[1:0] reg .dv (stuffer_dv), // output reg .flush_out (stuffer_flush_out) // output reg ); bit_stuffer_escape bit_stuffer_escape_i ( .xclk (xclk), // input .rst (~en_huffman), // input .din (stuffer_do32), // input[31:0] .bytes_in (stuffer_bytes), // input[1:0] .in_stb (stuffer_dv), // input .flush_in (stuffer_flush_out), // input .d_out (escape_do32), // output[31:0] reg .bytes_out (escape_bytes), // output[1:0] reg .dv (escape_dv), // output reg .flush_out (escape_flush_out) // output reg ); bit_stuffer_metadata bit_stuffer_metadata_i ( .mclk (mclk), // input .mrst (mrst), // input .xclk (xclk), // input .xrst (~en_stuffer), // input .last_block (huffman_last_block), // input .ts_pre_stb (ts_pre_stb), // input .ts_data (ts_data), // input[7:0] .color_first (color_first), // input .din (escape_do32), // input[31:0] .bytes_in (escape_bytes), // input[1:0] .in_stb (escape_dv), // input .flush (escape_flush_out), // input .abort (abort_stuffer), // input .data_out (data_out), // output[31:0] reg .data_out_valid (data_out_valid), // output reg .done (done), // output reg .running (running) // output reg ); endmodule