Loading compressor_jp/huff_fifo393.v +46 −103 Original line number Diff line number Diff line Loading @@ -24,146 +24,89 @@ ** -----------------------------------------------------------------------------** ** */ //used the other edge of the clk2x module huff_fifo393 ( input xclk, // pixel clock, posedge input xclk2x, // twice frequency - uses negedge inside input en, // will reset if ==0 (sync to xclk) input [15:0] di, // data in (sync to xclk) input ds, // din valid (sync to xclk) input want_read, input want_read_early, output reg dav, // FIFO output latch has data (fifo_or_full) `ifdef INFER_LATCHES output reg [15:0] q_latch `else output [15:0] q_latch `endif input want_read, // will be and-ed with dav output dav, // FIFO output latch has data (fifo_or_full) output reg [15:0] q ); // output data reg [9:0] wa; reg [9:0] sync_wa; // delayed wa, re_latch-calculated at output clock reg [9:0] ra_r; wire [15:0] fifo_o; reg ds1; // ds delayed by one xclk to give time to block ram to write data. Not needed likely. reg synci; reg [1:0] synco; reg [2:0] synco; reg sync_we; // single xclk2x period pulse for each ds@xclk reg en2x; // en sync to xclk2x; reg re_r; reg fifo_dav; // RAM output reg has data reg dav_and_fifo_dav; wire ram_dav; // RAM has data inside reg [9:0] diff_a; wire next_re; reg load_q; `ifdef INFER_LATCHES reg [9:0] ra_latch; reg re_latch; `else wire [9:0] ra_latch; wire re_latch; `endif wire [3:0] re; reg [2:0] nempty_r; // output register and RAM registers not empty wire [3:0] nempty; // output register and RAM register and RAM internal are not empty wire many; assign dav = nempty[0]; assign nempty = {(|diff_a), nempty_r}; assign many = &(nempty); // memory and all the register chain are full assign re = {4{many & want_read}} | {nempty[3] & ~nempty[2], // read memory location nempty[2] & ~nempty[1], // regen nempty[1] & ~nempty[0], // copy to q- register nempty[0] & want_read}; // external read when data is available always @ (posedge xclk) begin // input stage, no overrun detection. TODO: propagate half-full? if (!en) wa <= 0; else if (ds) wa <= wa+1; always @ (posedge xclk) begin // input stage, no overrun detection if (!en) wa[9:0] <= 10'b0; else if (ds) wa[9:0] <= wa[9:0]+1; ds1 <= ds && en; if (!en) synci <= 1'b0; else if (ds1) synci <= ~synci; end always @ (negedge xclk2x) begin en2x <= en; synco[1:0] <= {synco[0],synci}; sync_we <= en2x && (synco[0] != synco[1]); synco <= {synco[1:0],synci}; sync_we <= en2x && (synco[1] != synco[2]); end assign ram_dav= sync_we || (diff_a[9:0] != 10'b0); assign next_re= ram_dav && (!dav_and_fifo_dav || want_read); always @ (negedge xclk2x) begin dav <= en2x && (fifo_dav || (dav && !want_read)); fifo_dav <= en2x && (ram_dav ||(dav && fifo_dav && !want_read)); dav_and_fifo_dav <= en2x && (fifo_dav || (dav && !want_read)) && (ram_dav ||(dav && fifo_dav && !want_read)); // will optimize auto re_r <= en2x && next_re; if (!en2x) nempty_r[0] <= 0; else if (re[1] ^ re[0]) nempty_r[0] <=re[1]; if (!en2x) sync_wa[9:0] <= 10'b0; else if (sync_we) sync_wa[9:0] <= sync_wa[9:0]+1; if (!en2x) nempty_r[1] <= 0; else if (re[2] ^ re[1]) nempty_r[1] <=re[2]; if (!en2x) ra_r [9:0] <= 10'b0; else if (next_re) ra_r [9:0] <= ra_r[9:0]+1; if (!en2x) nempty_r[2] <= 0; else if (re[3] ^ re[2]) nempty_r[2] <=re[3]; if (!en2x) diff_a[9:0] <= 10'b0; else if (sync_we && !next_re) diff_a[9:0] <= diff_a[9:0]+1; else if (!sync_we && next_re) diff_a[9:0] <= diff_a[9:0]-1; if (!en2x) ra_r <= 0; else if (re[3]) ra_r <= ra_r + 1; end if (!en2x) diff_a <= 0; else if ( sync_we && !re[3]) diff_a <= diff_a + 1; else if (!sync_we && re[3]) diff_a <= diff_a - 1; always @ (posedge xclk2x) begin load_q <= dav?want_read_early:re_r; end if (!en2x) q <= 0; else if (re[1]) q <= fifo_o; `ifdef INFER_LATCHES always @* if (xclk2x) re_latch <= next_re; always @* if (xclk2x) ra_latch <= ra_r; always @* if (~xclk2x) if (load_q) q_latch <= fifo_o; end `else latch_g_ce #( .WIDTH (1), .INIT (0), .IS_CLR_INVERTED (0), .IS_G_INVERTED (0) ) latch_re_i ( .rst (1'b0), // input .g (xclk2x), // input .ce (1'b1), // input .d_in (next_re), // input[0:0] .q_out (re_latch) // output[0:0] ); latch_g_ce #( .WIDTH (10), .INIT (0), .IS_CLR_INVERTED (0), .IS_G_INVERTED (0) ) latch_ra_i ( .rst (1'b0), // input .g (xclk2x), // input .ce (1'b1), // input .d_in (ra_r), // input[0:0] .q_out (ra_latch) // output[0:0] ); latch_g_ce #( .WIDTH (16), .INIT (0), .IS_CLR_INVERTED (0), .IS_G_INVERTED (1'b1) // inverted! ) latch_q_i ( .rst (1'b0), // input .g (xclk2x), // input .ce (load_q), // input .d_in (fifo_o), // input[0:0] .q_out (q_latch) // output[0:0] ); `endif ram18_var_w_var_r #( .REGISTERS (0), .REGISTERS (1), .LOG2WIDTH_WR (4), .LOG2WIDTH_RD (4), .DUMMY (0) ) i_fifo ( .rclk (xclk2x), // input .raddr (ra_latch[9:0]), // input[9:0] .ren (re_latch), // input .regen (1'b1), // input .raddr (ra_r[9:0]), // input[9:0] .ren (re[3]), // input .regen (re[2]), // input .data_out (fifo_o[15:0]), // output[15:0] .wclk (xclk), // input .waddr (wa[9:0]), // input[9:0] Loading Loading
compressor_jp/huff_fifo393.v +46 −103 Original line number Diff line number Diff line Loading @@ -24,146 +24,89 @@ ** -----------------------------------------------------------------------------** ** */ //used the other edge of the clk2x module huff_fifo393 ( input xclk, // pixel clock, posedge input xclk2x, // twice frequency - uses negedge inside input en, // will reset if ==0 (sync to xclk) input [15:0] di, // data in (sync to xclk) input ds, // din valid (sync to xclk) input want_read, input want_read_early, output reg dav, // FIFO output latch has data (fifo_or_full) `ifdef INFER_LATCHES output reg [15:0] q_latch `else output [15:0] q_latch `endif input want_read, // will be and-ed with dav output dav, // FIFO output latch has data (fifo_or_full) output reg [15:0] q ); // output data reg [9:0] wa; reg [9:0] sync_wa; // delayed wa, re_latch-calculated at output clock reg [9:0] ra_r; wire [15:0] fifo_o; reg ds1; // ds delayed by one xclk to give time to block ram to write data. Not needed likely. reg synci; reg [1:0] synco; reg [2:0] synco; reg sync_we; // single xclk2x period pulse for each ds@xclk reg en2x; // en sync to xclk2x; reg re_r; reg fifo_dav; // RAM output reg has data reg dav_and_fifo_dav; wire ram_dav; // RAM has data inside reg [9:0] diff_a; wire next_re; reg load_q; `ifdef INFER_LATCHES reg [9:0] ra_latch; reg re_latch; `else wire [9:0] ra_latch; wire re_latch; `endif wire [3:0] re; reg [2:0] nempty_r; // output register and RAM registers not empty wire [3:0] nempty; // output register and RAM register and RAM internal are not empty wire many; assign dav = nempty[0]; assign nempty = {(|diff_a), nempty_r}; assign many = &(nempty); // memory and all the register chain are full assign re = {4{many & want_read}} | {nempty[3] & ~nempty[2], // read memory location nempty[2] & ~nempty[1], // regen nempty[1] & ~nempty[0], // copy to q- register nempty[0] & want_read}; // external read when data is available always @ (posedge xclk) begin // input stage, no overrun detection. TODO: propagate half-full? if (!en) wa <= 0; else if (ds) wa <= wa+1; always @ (posedge xclk) begin // input stage, no overrun detection if (!en) wa[9:0] <= 10'b0; else if (ds) wa[9:0] <= wa[9:0]+1; ds1 <= ds && en; if (!en) synci <= 1'b0; else if (ds1) synci <= ~synci; end always @ (negedge xclk2x) begin en2x <= en; synco[1:0] <= {synco[0],synci}; sync_we <= en2x && (synco[0] != synco[1]); synco <= {synco[1:0],synci}; sync_we <= en2x && (synco[1] != synco[2]); end assign ram_dav= sync_we || (diff_a[9:0] != 10'b0); assign next_re= ram_dav && (!dav_and_fifo_dav || want_read); always @ (negedge xclk2x) begin dav <= en2x && (fifo_dav || (dav && !want_read)); fifo_dav <= en2x && (ram_dav ||(dav && fifo_dav && !want_read)); dav_and_fifo_dav <= en2x && (fifo_dav || (dav && !want_read)) && (ram_dav ||(dav && fifo_dav && !want_read)); // will optimize auto re_r <= en2x && next_re; if (!en2x) nempty_r[0] <= 0; else if (re[1] ^ re[0]) nempty_r[0] <=re[1]; if (!en2x) sync_wa[9:0] <= 10'b0; else if (sync_we) sync_wa[9:0] <= sync_wa[9:0]+1; if (!en2x) nempty_r[1] <= 0; else if (re[2] ^ re[1]) nempty_r[1] <=re[2]; if (!en2x) ra_r [9:0] <= 10'b0; else if (next_re) ra_r [9:0] <= ra_r[9:0]+1; if (!en2x) nempty_r[2] <= 0; else if (re[3] ^ re[2]) nempty_r[2] <=re[3]; if (!en2x) diff_a[9:0] <= 10'b0; else if (sync_we && !next_re) diff_a[9:0] <= diff_a[9:0]+1; else if (!sync_we && next_re) diff_a[9:0] <= diff_a[9:0]-1; if (!en2x) ra_r <= 0; else if (re[3]) ra_r <= ra_r + 1; end if (!en2x) diff_a <= 0; else if ( sync_we && !re[3]) diff_a <= diff_a + 1; else if (!sync_we && re[3]) diff_a <= diff_a - 1; always @ (posedge xclk2x) begin load_q <= dav?want_read_early:re_r; end if (!en2x) q <= 0; else if (re[1]) q <= fifo_o; `ifdef INFER_LATCHES always @* if (xclk2x) re_latch <= next_re; always @* if (xclk2x) ra_latch <= ra_r; always @* if (~xclk2x) if (load_q) q_latch <= fifo_o; end `else latch_g_ce #( .WIDTH (1), .INIT (0), .IS_CLR_INVERTED (0), .IS_G_INVERTED (0) ) latch_re_i ( .rst (1'b0), // input .g (xclk2x), // input .ce (1'b1), // input .d_in (next_re), // input[0:0] .q_out (re_latch) // output[0:0] ); latch_g_ce #( .WIDTH (10), .INIT (0), .IS_CLR_INVERTED (0), .IS_G_INVERTED (0) ) latch_ra_i ( .rst (1'b0), // input .g (xclk2x), // input .ce (1'b1), // input .d_in (ra_r), // input[0:0] .q_out (ra_latch) // output[0:0] ); latch_g_ce #( .WIDTH (16), .INIT (0), .IS_CLR_INVERTED (0), .IS_G_INVERTED (1'b1) // inverted! ) latch_q_i ( .rst (1'b0), // input .g (xclk2x), // input .ce (load_q), // input .d_in (fifo_o), // input[0:0] .q_out (q_latch) // output[0:0] ); `endif ram18_var_w_var_r #( .REGISTERS (0), .REGISTERS (1), .LOG2WIDTH_WR (4), .LOG2WIDTH_RD (4), .DUMMY (0) ) i_fifo ( .rclk (xclk2x), // input .raddr (ra_latch[9:0]), // input[9:0] .ren (re_latch), // input .regen (1'b1), // input .raddr (ra_r[9:0]), // input[9:0] .ren (re[3]), // input .regen (re[2]), // input .data_out (fifo_o[15:0]), // output[15:0] .wclk (xclk), // input .waddr (wa[9:0]), // input[9:0] Loading