* @brief Bit stuffer combines variable length fragments (up to 16 bits long)
* from the Huffman encoder to a byte stream, escapes every 0xff byte with
* 0x00 and adds file length and timestamp metadata
* Modified from bit_stuffer_metadata to include raw byte stream as alternative
*
* @copyright Copyright (c) 2015 Elphel, Inc .
*
* <b>License:</b>
*
* bit_stuffer_raw_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_raw_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/> .
*
* Additional permission under GNU GPL version 3 section 7:
* If you modify this Program, or any covered work, by linking or combining it
* with independent modules provided by the FPGA vendor only (this permission
* does not extend to any 3-rd party modules, "soft cores" or macros) under
* different license terms solely for the purpose of generating binary "bitstream"
* files and/or simulating the code, the copyright holders of this Program give
* you the right to distribute the covered work without those independent modules
* as long as the source code for them is available from the FPGA vendor free of
* charge, and there is no dependence on any encrypted modules for simulating of
* the combined code. This permission applies to you if the distributed code
* contains all the components and scripts required to completely simulate it
* with at least one of the Free Software programs.
*/
`timescale1ns/1ps
modulebit_stuffer_raw_metadata(
inputmclk,
inputmrst,// @posedge mclk, sync reset
inputxclk,
inputxrst,// @posedge xclk, sync reset
inputlast_block,// use it to copy timestamp from fifo // TODO: leading edge is Need for raw also
// 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
inputts_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)
inputcolor_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)
inputin_stb,// input data/bytes_in strobe
inputflush,// end of input data
inputabort,// @ any, extracts 0->1 and flushes (for both modes!)
// RAW mode ports, all @ xclk
inputraw_mode,// operating in raw mode (uncompressed)
inputraw_be16,// swap byte pairs to outut 16-bit big endian data
input[7:0]raw_bytes,// raw bypass byte data in little endian order
inputraw_start,// single-cycle set "running"
inputraw_prefb,// 1 cycle before sequence of 4 bytes
inputraw_ts_copy,// single-cycle copy timestamp (some time before flush)
inputraw_flush,// flush remaining data, length and timestamp
// outputs @ negedge clk
outputreg[31:0]data_out,// [31:0] output data
outputregdata_out_valid,// output data valid
outputregdone,// reset by !en, goes high after some delay after flushing
outputregrunning// from registering timestamp until done
`ifdefDEBUG_RING
,outputreg[3:0]dbg_etrax_dma
,outputdbg_ts_rstb
,output[7:0]dbg_ts_dout
`endif
);
// Processing raw
reg[31:0]raw32;
regraw_stb;
reg[3:0]raw_bs;
always@(posedgexclk)begin
if(xrst)raw_bs<=0;
elseraw_bs<=raw_be16?
{raw_bs[0],raw_bs[3],raw_prefb,raw_bs[1]}:
{raw_bs[2],raw_bs[1],raw_bs[0],raw_prefb};
if(xrst)raw_stb<=0;
elseraw_stb<=raw_be16?raw_bs[2]:raw_bs[3];
if(raw_bs[0])raw32[7:0]<=raw_bytes;
if(raw_bs[1])raw32[15:8]<=raw_bytes;
if(raw_bs[2])raw32[23:16]<=raw_bytes;
if(raw_bs[3])raw32[31:24]<=raw_bytes;
end
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;
reglast_block_d;// last_block delayed by one clock
regcolor_first_r;
reg[2:0]abort_r;
regforce_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
reglast_stb_4;// last stb_in was 4 bytes
regtrailer;
regmeta_out;
reg[1:0]meta_word;
regzeros_out;// output of 32 bytes (8 words) of zeros
wiretrailer_done=(imgsz4[2:0]==7)&&zeros_out;
wiremeta_last=(imgsz4[2:0]==7)&&meta_out;
// re-clock enable to this clock
wirets_rstb=raw_mode?raw_ts_copy:(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
wirewrite_size=(in_stb&&(bytes_in!=0))||(flush&&last_stb_4);// TODO: never in raw mode?
if((!ts_in[3]&&(ts_in[1:0]==0))||write_size)time_ram0[ts_in[3:2]]<=ts_in[3]?({imgsz4[5:0],(flush||raw_mode)?2'b0:bytes_in}):ts_dout;//ts_in[3:2] == 2'b10 when write_size