diff --git a/README.md b/README.md index d4396eb..7141f13 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Hard-PNG | ![diagram](./figures/diagram.png) | | :----: | -| 图1 : Hard-PNG 原理框图 | +| **图1** : Hard-PNG 原理框图 | @@ -34,37 +34,39 @@ png 图像文件的扩展名为 .png 。以本库中的 SIM/test_image/img01.png # 使用 Hard-PNG -RTL 目录中的 hard_png.sv 是一个能够输入 png 码流,输出解压后的像素的模块,它的接口如图2所示。 +RTL 目录中的 hard_png.sv 是一个能够输入 png 码流,输出解压后的像素的模块,它的接口如**图2**所示。 | ![接口图](./figures/interface.png) | | :----: | -| 图2 : hard_png 接口图 | +| **图2** : hard_png 接口图 | -hard_png 的使用方法很简单,在输入一张 png 图像的码流前,先要给模块复位(令 rstn=0 至少一个时钟周期),然后解除复位(令 rstn=1),然后输入 png 码流,并从图象基本信息输出接口和像素输出接口中得到解码结果。 +## 输入码流 -以 SIM/test_image/img01.png 为例,我们应该以图3的时序把 png 码流中的98个字节逐一输入到 hard_png 中。其中 ivalid 和 iready 构成了握手信号: ivalid=1 时说明外部想发送一个字节给 hard_png。iready=1 时说明 hard_png 已经准备好接收一个字节。只有 ivalid 和 iready 同时=1 时,ibyte 才被成功的输入 hard_png 中。 +hard_png 的使用方法很简单,以 SIM/test_image/img01.png 这张图像为例,如**图3**,在输入一张图象的码流前,先要令 istart 上产生一个高电平脉冲(宽度至少为一个时钟周期),然后通过 ivalid 和 ibyte 信号来输入码流(这张图象的 png 码流有 98 字节,这 98 字节都要逐一输入给 hard_png),其中 ivalid 和 iready 构成了握手信号: ivalid=1 时说明外部想发送一个字节给 hard_png。iready=1 时说明 hard_png 已经准备好接收一个字节。只有 ivalid 和 iready 同时=1 时握手才成功,ibyte 才被成功的输入 hard_png 中。 | ![输入时序图](./figures/wave1.png) | | :----: | -| 图3 : hard_png 的输入波形图 | +| **图3** : hard_png 的输入波形图 | -在输入的同时,解压结果从模块中输出,如图4。在一帧图象输出前,newframe 信号会出现一个时钟周期的高电平脉冲,同时 colortype, width, height 有效。其中: +当一张 png 图象的码流输入结束后,可以立即或稍后输入下一张图像(也就是让 istart 上产生高电平脉冲,然后输入码流)。 -- width, height 分别为图象的宽度和高度 -- colortype 为 png 图像的颜色类型,含义如下表。 +## 输出图像信息和像素 -| colortype | 3'd0 | 3'd1 | 3'd2 | 3'd3 | 3‘d4 | +在输入码流的同时,这张图象的解压结果(也就是图像基本信息和原始像素)会从模块中输出,如**图4**,在图象的像素输出前,ovalid 信号会出现一个时钟周期的高电平脉冲,同时 colortype, width, height 会有效。其中: + +- width, height 分别是图象的宽度和高度 +- colortype 是 png 图像的颜色类型,含义如下表。 + +| colortype 值 | 3'd0 | 3'd1 | 3'd2 | 3'd3 | 3‘d4 | | :-------: | :--: | :--: | :--: | :--: | :--: | | 颜色类型 | 灰度 | 灰度+A | RGB | RGB+A | 索引RGB | | 备注 | R=G=B,A=0xFF | R=G=B≠A | R≠G≠B,A=0xFF | R≠G≠B≠A | R≠G≠B,A=0xFF | -然后,ovalid=1 代表该时钟周期有一个像素输出,该像素的 R,G,B,A 通道分别出现在 opixelr,opixelg,opixelb,opixela 信号上。 +然后,ovalid=1 代表该时钟周期有一个像素输出,该像素的 R,G,B,A 通道会分别出现在 opixelr,opixelg,opixelb,opixela 信号上。 | ![输出时序图](./figures/wave2.png) | | :----: | -| 图4 : hard_png 的输出波形图 | - -当一个 png 图象输入结束后,可以立即或稍后输入下一张图像(复位->解除复位->输入码流)。 +| **图4** : hard_png 的输出波形图 | @@ -79,7 +81,7 @@ hard_png 的使用方法很简单,在输入一张 png 图像的码流前,先 使用 iverilog 进行仿真前,需要安装 iverilog ,见:[iverilog_usage](https://github.com/WangXuan95/WangXuan95/blob/main/iverilog_usage/iverilog_usage.md) -然后双击 tb_hard_png_run_iverilog.bat 运行仿真,会运行大约半小时(可以中途强制关闭,但产生的仿真波形就是不全的)。 +然后双击 tb_hard_png_run_iverilog.bat 即可运行仿真,会运行大约半小时(可以中途强制关闭,但产生的仿真波形就是不全的)。 仿真运行完后,可以打开生成的 dump.vcd 文件查看波形。 @@ -120,18 +122,19 @@ total 400 pixels validation successful!! | FPGA 型号 | LUT | LUT(%) | FF | FF(%) | Logic | Logic(%) | BRAM | BRAM(%) | | :----------------------------: | :--: | :----: | :--: | :---: | :---: | :------: | :-----: | :-----: | | Xilinx Artix-7 XC7A35T | 2581 | 13% | 2253 | 5% | - | - | 792kbit | 44% | -| Altera Cyclone IV EP4CE40F23C6 | - | - | - | - | 4551 | 11% | 427kbit | 37% | +| Altera Cyclone IV EP4CE40F23C6 | - | - | - | - | 4682 | 11% | 427kbit | 37% | ## 性能 在 Altera Cyclone IV EP4CE40F23C6 上部署 hard_png ,时钟频率= 50MHz (正好时序收敛)。根据仿真时每个图像消耗的时钟周期数,可以算出压缩图像时的性能,举例如下表。 -| png文件名 | 颜色类型 | 图象长宽 | png 码流大小 (字节) | 消耗的时钟周期数 | 消耗时间 | -| :-----------: | :----------: | :----------: | :--------------: | :---------------: | :---------------: | -| img05.png | RGB | 300x256 | 96536 | 1105702 | 23ms | -| img06.png | 灰度 | 300x263 | 37283 | 395335 | 8ms | -| img10.png | 索引RGB | 631x742 | 193489 | 2374224 | 48ms | -| img14.png | 索引RGB | 1920x1080 | 818885 | 10177644 | 204ms | +| 文件名 | 颜色类型 | 图象长宽 | 像素数 | png 码流大小 (字节) | 时钟周期数 | 消耗时间 | +| :-----------: | :----------: | :----------: | :--------------: | :---------------: | :---------------: | ------------- | +| img05.png | RGB | 300x256 | 76800 | 96536 | 1105702 | 23ms | +| img06.png | 灰度 | 300x263 | 78900 | 37283 | 395335 | 8ms | +| img09.png | RGBA | 300x263 | 78900 | 125218 | 1382303 | 28ms | +| img10.png | 索引RGB | 631x742 | 468202 | 193489 | 2374224 | 48ms | +| img14.png | 索引RGB | 1920x1080 | 2073600 | 818885 | 10177644 | 204ms | diff --git a/RTL/hard_png.sv b/RTL/hard_png.sv index 60e3bf5..f38ef22 100644 --- a/RTL/hard_png.sv +++ b/RTL/hard_png.sv @@ -10,11 +10,12 @@ module hard_png ( input wire rstn, input wire clk, // png data input stream + input wire istart, input wire ivalid, output reg iready, input wire [ 7:0] ibyte, // image frame configuration output - output reg newframe, + output reg ostart, output wire [ 2:0] colortype, // 0:gray 1:gray+A 2:RGB 3:RGBA 4:RGB-plte output wire [13:0] width, // image width output wire [31:0] height, // image height @@ -23,11 +24,9 @@ module hard_png ( output wire [ 7:0] opixelr, opixelg, opixelb, opixela ); -initial newframe = 1'b0; +initial ostart = 1'b0; initial ovalid = 1'b0; -reg imagevalid = '0; - reg isplte = '0; reg [ 1:0] bpp = '0; // bytes per pixel @@ -88,7 +87,9 @@ generate genvar ii; if(~rstn) latchbytes[ii] <= '0; else begin - if(ivalid) + if(istart) + latchbytes[ii] <= '0; + else if(ivalid) latchbytes[ii] <= lastbytes[ii+1]; end end @@ -134,7 +135,7 @@ wire parametervalid = ( lastbytes[7]==8'h0 && ); always_comb - if(imagevalid && cnt>0 && curr_name==IDAT && gapcnt==2'd0) begin + if(cnt>0 && curr_name==IDAT && gapcnt==2'd0) begin iready = pready; pvalid = ivalid; pbyte = ibyte; @@ -152,7 +153,6 @@ always @ (posedge clk or negedge rstn) gapcnt <= '0; busy <= 1'b0; sizevalid <= 1'b0; - imagevalid <= 1'b0; curr_name <= NONE; ispltetmp <= 1'b0; bpptmp <= '0; @@ -164,18 +164,38 @@ always @ (posedge clk or negedge rstn) ppr <= '0; bpr <= '0; rpf <= '0; - newframe <= 1'b0; + ostart <= 1'b0; plte_wen <= 1'b0; plte_waddr <= '0; plte_wdata <= '0; plte_bytecnt <= '0; plte_pixcnt <= '0; end else begin - newframe <= 1'b0; + ostart <= 1'b0; plte_wen <= 1'b0; plte_waddr <= '0; plte_wdata <= '0; - if(ivalid) begin + if(istart) begin + bcnt <= '0; + cnt <= '0; + crccnt <= '0; + gapcnt <= '0; + busy <= 1'b0; + sizevalid <= 1'b0; + curr_name <= NONE; + ispltetmp <= 1'b0; + bpptmp <= '0; + pprtmp <= '0; + bprtmp <= '0; + rpftmp <= '0; + isplte <= 1'b0; + bpp <= '0; + ppr <= '0; + bpr <= '0; + rpf <= '0; + plte_bytecnt <= '0; + plte_pixcnt <= '0; + end else if(ivalid) begin plte_bytecnt <= '0; plte_pixcnt <= '0; if(~busy) begin @@ -190,7 +210,6 @@ always @ (posedge clk or negedge rstn) cnt <= cnt - 1; gapcnt <= 2'd2; if(cnt==6) begin - imagevalid <= 1'b0; rpftmp <= l32bit; if(h32bit[31:14]=='0) begin sizevalid <= 1'b1; @@ -211,15 +230,13 @@ always @ (posedge clk or negedge rstn) endcase end else if(cnt==1) begin if(sizevalid && parametervalid && (bprtmp[15:14]==2'd0)) begin - newframe <= 1'b1; - imagevalid <= 1'b1; + ostart <= 1'b1; isplte <= ispltetmp; bpp <= bpptmp; ppr <= pprtmp; bpr <= bprtmp[13:0]; rpf <= rpftmp; end else begin - imagevalid <= 1'b0; isplte <= 1'b0; bpp <= '0; ppr <= '0; @@ -230,7 +247,7 @@ always @ (posedge clk or negedge rstn) end else if(curr_name==IDAT) begin if(gapcnt>2'd0) gapcnt <= gapcnt - 2'd1; - if(imagevalid && gapcnt==2'd0) begin + if(gapcnt==2'd0) begin if(pready) cnt <= cnt - 1; end else begin @@ -291,36 +308,26 @@ always @ (posedge clk or negedge rstn) // uz_inflate //----------------------------------------------------------------------------------------------------------------------- -reg end_stream = '0; +reg end_stream = '0; wire huffman_ovalid; wire [7:0] huffman_obyte; -reg raw_ovalid; -reg [7:0] raw_obyte; -reg raw_mode = 1'b0; -reg raw_format = '0; - -reg [ 2:0] status = '0; -reg [15:0] rcnt = '0; reg [ 2:0] uz_cnt = '0; reg [ 7:0] rbyte = '0; -reg tvalid; -wire tready; -reg tbit; +reg tvalid; +wire tready; +reg tbit; always @ (posedge clk or negedge rstn) if(~rstn) begin mvalid <= 1'b0; mbyte <= '0; end else begin - if(~imagevalid) begin + if(istart) begin mvalid <= 1'b0; mbyte <= '0; - end else if(raw_mode) begin - mvalid <= raw_ovalid; - mbyte <= raw_obyte; end else begin mvalid <= huffman_ovalid; mbyte <= huffman_obyte; @@ -328,98 +335,33 @@ always @ (posedge clk or negedge rstn) end always_comb - if(~imagevalid) begin - raw_ovalid = 1'b0; - raw_obyte = '0; - pready = 1'b0; - tvalid = 1'b0; - tbit = 1'b0; + if(uz_cnt==3'h0) begin + pready = tready; + tvalid = pvalid; + tbit = pbyte[0]; end else begin - raw_ovalid = 1'b0; - raw_obyte = '0; - if(raw_mode) begin - pready = 1'b1; - tvalid = 1'b0; - tbit = 1'b0; - if(status>=3) begin - raw_ovalid = pvalid; - raw_obyte = pbyte; - end - end if(raw_format) begin - pready = 1'b1; - tvalid = 1'b0; - tbit = 1'b0; - end else if(uz_cnt==3'h0) begin - pready = tready; - tvalid = pvalid; - tbit = pbyte[0]; - end else begin - pready = 1'b0; - tvalid = 1'b1; - tbit = rbyte[uz_cnt]; - end + pready = 1'b0; + tvalid = 1'b1; + tbit = rbyte[uz_cnt]; end always @ (posedge clk or negedge rstn) if(~rstn) begin - raw_mode <= 1'b0; uz_cnt <= '0; rbyte <= '0; - rcnt <= '0; - status <= '0; end else begin - if(~imagevalid) begin - raw_mode <= 1'b0; + if(istart) begin uz_cnt <= '0; rbyte <= '0; - rcnt <= '0; - status <= '0; - end else if(raw_mode) begin - uz_cnt <= '0; - rbyte <= '0; - if(pvalid) begin - if (status==0) begin - rcnt[15:8] <= pbyte; - status <= status + 3'h1; - end else if(status==1) begin - status <= status + 3'h1; - end else if(status==2) begin - if(rcnt>0) begin - rcnt <= rcnt - 16'd1; - status <= status + 3'h1; - end else begin - raw_mode <= 1'b0; - status <= '0; - end - end else begin - if(rcnt>0) begin - rcnt <= rcnt - 16'd1; - end else begin - raw_mode <= 1'b0; - status <= '0; - end - end - end end else begin - rcnt <= '0; - status <= '0; - if(raw_format) begin - if(pvalid) begin - raw_mode <= 1'b1; - rcnt[ 7:0] <= pbyte; + if(uz_cnt==3'h0) begin + if(pvalid & tready) begin + uz_cnt <= uz_cnt + 3'h1; + rbyte <= pbyte; end - uz_cnt <= '0; - rbyte <= '0; end else begin - if(uz_cnt==3'h0) begin - if(pvalid & tready) begin - uz_cnt <= uz_cnt + 3'h1; - rbyte <= pbyte; - end - end else begin - if(tready) - uz_cnt <= uz_cnt + 3'h1; - end + if(tready) + uz_cnt <= uz_cnt + 3'h1; end end end @@ -440,8 +382,6 @@ reg srepeat = 1'b0; reg symbol_valid = 1'b0; reg [7:0] symbol = '0; -reg decoder_new = 1'b1; - reg [ 1:0] iword = '0; reg [ 1:0] ibcnt = '0; reg [ 4:0] precode_wpt = '0; @@ -484,14 +424,14 @@ reg [ 3:0] dscnt=4'h0, dsmax=4'h0; enum {T, D, R, S} huffman_status = T; -wire lentree_ien = ~end_stream & ~raw_format & tvalid & lentree_done & ~lentree_codeen & (repeat_mode==REPEAT_NONE && repeat_len==8'd0) & (tree_wpt3'd0) & (tree_wpt4'd0)) ) ) ); + ( tree_done & ~codetree_codeen & ~distree_codeen & (huffman_status==T || huffman_status==D || (huffman_status==R && dscnt>4'd0)) ) ); reg [ 8:0] lengthb= '0; reg [ 5:0] lengthe= '0; @@ -575,20 +515,17 @@ endtask always @ (posedge clk or negedge rstn) if(~rstn) begin - {raw_format, end_stream} <= '0; - decoder_new <= 1'b1; + end_stream <= '0; reset_all_regs; end else begin - if(raw_mode) begin - {raw_format, end_stream} <= '0; - decoder_new <= 1'b1; + if(istart) begin + end_stream <= '0; reset_all_regs; end else begin symbol_valid <= 1'b0; symbol <= '0; irepeat <= 1'b0; srepeat <= 1'b0; - decoder_new <= 1'b0; lentree_write(); codetree_write(); distree_write(); @@ -602,16 +539,12 @@ always @ (posedge clk or negedge rstn) end else if(precode_wpt==1) begin bfix <= tbit; end else begin - case({tbit,bfix}) - 2'b00 : - raw_format <= 1'b1; - 2'b01 : begin + if( {tbit,bfix} == 2'b01 ) begin precode_wpt <= '1; lentree_wpt <= '1; tree_wpt <= '1; fixed_tree <= 1'b1; end - endcase end end end else if(precode_wpt<17) begin @@ -777,6 +710,7 @@ huffman_builder #( ) lentree_builder ( .rstn ( rstn ), .clk ( clk ), + .istart ( istart ), .wren ( lentree_wen ), .wraddr ( lentree_waddr ), .wrdata ( lentree_wdata ), @@ -796,7 +730,7 @@ huffman_decoder #( ) lentree_decoder ( .rstn ( rstn ), .clk ( clk ), - .inew ( decoder_new ), + .istart ( istart ), .ien ( lentree_ien ), .ibit ( tbit ), .oen ( lentree_codeen ), @@ -817,6 +751,7 @@ huffman_builder #( ) codetree_builder ( .rstn ( rstn ), .clk ( clk ), + .istart ( istart ), .wren ( codetree_wen ), .wraddr ( codetree_waddr ), .wrdata ( (5)'(codetree_wdata) ), @@ -844,7 +779,7 @@ huffman_decoder #( ) codetree_decoder ( .rstn ( rstn ), .clk ( clk ), - .inew ( decoder_new ), + .istart ( istart ), .ien ( codetree_ien ), .ibit ( tbit ), .oen ( codetree_codeen), @@ -865,9 +800,10 @@ huffman_builder #( ) distree_builder ( .rstn ( rstn ), .clk ( clk ), + .istart ( istart ), .wren ( distree_wen ), .wraddr ( distree_waddr ), - .wrdata ( (5)'(distree_wdata) ), + .wrdata ( (5)'(distree_wdata) ), .run ( tree_run ), .done ( distree_done ), .rdaddr ( distree_raddr ), @@ -892,7 +828,7 @@ huffman_decoder #( ) distree_decoder ( .rstn ( rstn ), .clk ( clk ), - .inew ( decoder_new ), + .istart ( istart ), .ien ( distree_ien ), .ibit ( tbit ), .oen ( distree_codeen ), @@ -923,7 +859,10 @@ always @ (posedge clk or negedge rstn) if(~rstn) wptr <= '0; else begin - if(huffman_ovalid) wptr <= (wptr<(REPEAT_BUFFER_MAXLEN-16'd1)) ? wptr+16'd1 : '0; + if(istart) + wptr <= '0; + else if(huffman_ovalid) + wptr <= (wptr<(REPEAT_BUFFER_MAXLEN-16'd1)) ? wptr+16'd1 : '0; end always @ (posedge clk or negedge rstn) @@ -932,7 +871,11 @@ always @ (posedge clk or negedge rstn) sptr <= '0; eptr <= '0; end else begin - if(srepeat) begin + if(istart) begin + rptr <= '0; + sptr <= '0; + eptr <= '0; + end else if(srepeat) begin rptr <= sptrw; sptr <= sptrw; eptr <= eptrw; @@ -948,7 +891,7 @@ always @ (posedge clk or negedge rstn) if(~rstn) repeat_valid <= '0; else - repeat_valid <= irepeat; + repeat_valid <= istart ? '0 : irepeat; reg [7:0] mem_repeat_buffer [REPEAT_BUFFER_MAXLEN]; @@ -996,7 +939,7 @@ always @ (posedge clk or negedge rstn) nfirstrow <= 1'b0; col <= '0; end else begin - if(~imagevalid) begin + if(istart) begin nfirstrow <= 1'b0; col <= '0; end else if(mvalid) begin @@ -1013,9 +956,9 @@ always @ (posedge clk or negedge rstn) if(~rstn) begin mode <= '0; end else begin - if(~imagevalid) begin + if(istart) mode <= '0; - end else if(mvalid && col==14'h0) + else if(mvalid && col==14'h0) mode <= mbyte[2:0]; end @@ -1027,7 +970,7 @@ always_comb 3'd3 : fdata = mbyte + SSdata[8:1]; default: fdata = mbyte + paeth( (nfirstcol ? LLdata : 8'h0), (nfirstrow ? UUdata : 8'h0), - (nfirstrow&nfirstcol ? ULdata : 8'h0) ); + (nfirstrow & nfirstcol ? ULdata : 8'h0) ); endcase always @ (posedge clk or negedge rstn) @@ -1035,7 +978,7 @@ always @ (posedge clk or negedge rstn) bvalid <= 1'b0; bbyte <= '0; end else begin - if(~imagevalid) begin + if(istart) begin bvalid <= 1'b0; bbyte <= '0; end else begin @@ -1052,7 +995,7 @@ always @ (posedge clk or negedge rstn) if(~rstn) begin mem_sr_currline[0] <= '0; end else begin - if(~imagevalid) begin + if(istart) begin mem_sr_currline[0] <= '0; end else if(mvalid) mem_sr_currline[0] <= fdata; @@ -1063,7 +1006,7 @@ generate genvar isrcl; if(~rstn) begin mem_sr_currline[isrcl+1] <= '0; end else begin - if(~imagevalid) begin + if(istart) begin mem_sr_currline[isrcl+1] <= '0; end else if(mvalid) mem_sr_currline[isrcl+1] <= mem_sr_currline[isrcl]; @@ -1080,7 +1023,7 @@ always @ (posedge clk or negedge rstn) if(~rstn) begin mem_sr_prevline[0] <= '0; end else begin - if(~imagevalid) begin + if(istart) begin mem_sr_prevline[0] <= '0; end else if(mvalid) mem_sr_prevline[0] <= UUdata; @@ -1091,7 +1034,7 @@ generate genvar isrpl; if(~rstn) begin mem_sr_prevline[isrpl+1] <= '0; end else begin - if(~imagevalid) begin + if(istart) begin mem_sr_prevline[isrpl+1] <= '0; end else if(mvalid) mem_sr_prevline[isrpl+1] <= mem_sr_prevline[isrpl]; @@ -1111,7 +1054,7 @@ always @ (posedge clk or negedge rstn) if(~rstn) begin sb_lidata <= '0; end else begin - if(~imagevalid) begin + if(istart) begin sb_lidata <= '0; end else if(mvalid) sb_lidata <= fdata; @@ -1121,7 +1064,7 @@ always @ (posedge clk or negedge rstn) if(~rstn) begin sb_ptr <= '0; end else begin - if(~imagevalid) begin + if(istart) begin sb_ptr <= '0; end else if(mvalid) begin if(sb_ptr < (bpr-14'd1)) @@ -1136,7 +1079,7 @@ always @ (posedge clk or negedge rstn) sb_ldata <= '0; sb_rvalid <= 1'b0; end else begin - if(~imagevalid) begin + if(istart) begin sb_ldata <= '0; sb_rvalid <= 1'b0; end else begin @@ -1177,7 +1120,7 @@ always @ (posedge clk or negedge rstn) {pr, pg, pb, pa} <= 0; end else begin ovalid <= 1'b0; - if(newframe) begin + if(istart | ostart) begin pixcnt <= '0; {pr, pg, pb, pa} <= 0; end else if(bvalid) begin diff --git a/RTL/huffman_builder.sv b/RTL/huffman_builder.sv index eccc8d9..ab69075 100644 --- a/RTL/huffman_builder.sv +++ b/RTL/huffman_builder.sv @@ -12,6 +12,7 @@ module huffman_builder #( parameter OUTWIDTH = 10 ) ( rstn, clk, + istart, wren, wraddr, wrdata, run , done, rdaddr, rddata @@ -25,6 +26,7 @@ endfunction input rstn; input clk; +input istart; input wren; input [ clogb2(NUMCODES-1)-1:0] wraddr; input [ CODEBITS -1:0] wrdata; @@ -33,18 +35,19 @@ output done; input [clogb2(2*NUMCODES-1)-1:0] rdaddr; output [ OUTWIDTH-1:0] rddata; -wire rstn; -wire clk; -wire wren; -wire [ clogb2(NUMCODES-1)-1:0] wraddr; -wire [ CODEBITS -1:0] wrdata; -wire run; -wire done; -wire [clogb2(2*NUMCODES-1)-1:0] rdaddr; -reg [ OUTWIDTH-1:0] rddata; +wire rstn; +wire clk; +wire istart; +wire wren; +wire [ clogb2(NUMCODES-1)-1:0] wraddr; +wire [ CODEBITS -1:0] wrdata; +wire run; +wire done; +wire [clogb2(2*NUMCODES-1)-1:0] rdaddr; +reg [ OUTWIDTH-1:0] rddata; -reg [clogb2(NUMCODES)-1:0] blcount [BITLENGTH]; -reg [ (1<0; - treepos <= ntreepos; - tpos <= ntpos; - lii <= ii; - lnn <= nn; + if(istart) begin + valid <= '0; + treepos <= '0; + tpos <= '0; + lii <= '0; + lnn <= '0; + end else begin + valid <= build_tree2d & nn0; + treepos <= ntreepos; + tpos <= ntpos; + lii <= ii; + lnn <= nn; + end end always @ (posedge clk or negedge rstn) if(~rstn) blen <= '0; else begin - if(islast) blen <= blenn; + if(istart) + blen <= '0; + else if(islast) + blen <= blenn; end always @ (posedge clk or negedge rstn) @@ -96,7 +110,7 @@ always @ (posedge clk or negedge rstn) for(int i=0; i= (clogb2(2*NUMCODES-1))'(2*NUMCODES-1) ) clear_tree2d <= 1'b1; @@ -153,12 +174,6 @@ always @ (posedge clk or negedge rstn) build_tree2d <= 1'b1; end end - end else begin - ii <= '0; - idx <= '0; - build_tree2d <= 1'b0; - clearidx <= '0; - clear_tree2d <= 1'b0; end end @@ -177,7 +192,9 @@ always @ (posedge clk or negedge rstn) if(~rstn) begin nodefilled <= '0; end else begin - if(~run) + if(istart) + nodefilled <= '0; + else if(~run) nodefilled <= (clogb2(2*NUMCODES-1))'(1); else if(valid & rdfilled & lii>0) nodefilled <= nodefilled + (clogb2(2*NUMCODES-1))'(1); diff --git a/RTL/huffman_decoder.sv b/RTL/huffman_decoder.sv index c864925..706ef31 100644 --- a/RTL/huffman_decoder.sv +++ b/RTL/huffman_decoder.sv @@ -10,7 +10,8 @@ module huffman_decoder #( parameter OUTWIDTH = 10 )( rstn, clk, - inew, ien, ibit, + istart, + ien, ibit, oen, ocode, rdaddr, rddata ); @@ -22,22 +23,22 @@ function automatic integer clogb2(input integer val); endfunction input rstn, clk; -input inew, ien, ibit; +input istart, ien, ibit; output oen; output [ OUTWIDTH-1:0] ocode; output [clogb2(2*NUMCODES-1)-1:0] rdaddr; input [ OUTWIDTH-1:0] rddata; -wire rstn, clk; -wire inew, ien, ibit; -reg oen = 1'b0; -reg [ OUTWIDTH-1:0] ocode = '0; -wire [clogb2(2*NUMCODES-1)-1:0] rdaddr; -wire [ OUTWIDTH-1:0] rddata; +wire rstn, clk; +wire istart, ien, ibit; +reg oen = 1'b0; +reg [ OUTWIDTH-1:0] ocode = '0; +wire [clogb2(2*NUMCODES-1)-1:0] rdaddr; +wire [ OUTWIDTH-1:0] rddata; -reg [clogb2(2*NUMCODES-1)-2:0] tpos = '0; -wire [clogb2(2*NUMCODES-1)-2:0] ntpos; -reg ienl = 1'b0; +reg [clogb2(2*NUMCODES-1)-2:0] tpos = '0; +wire [clogb2(2*NUMCODES-1)-2:0] ntpos; +reg ienl = 1'b0; assign rdaddr = {ntpos, ibit}; @@ -47,13 +48,13 @@ always @ (posedge clk or negedge rstn) if(~rstn) ienl <= '0; else - ienl <= inew ? '0 : ien; + ienl <= istart ? '0 : ien; always @ (posedge clk or negedge rstn) if(~rstn) tpos <= '0; else - tpos <= inew ? '0 : ntpos; + tpos <= istart ? '0 : ntpos; always_comb if(ienl && rddata