Commit c96dad8c authored by Andrey Filippov's avatar Andrey Filippov

Added top module for compressor chain, finished porting color space converter

parent 454a65b4
/*******************************************************************************
* Module: cmprs_buf_average
* Date:2015-06-14
* Author: andrey
* Description: Saves Y and C components to buffers, caculates averages
* during write, then subtracts them during read and provides to
* the after DCT to restore DC
*
* Copyright (c) 2015 <set up in Preferences-Verilog/VHDL Editor-Templates> .
* cmprs_buf_average.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_buf_average.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
// TODO:Clean up even more - remove signals that are not related to calculating/subtracting averages
module cmprs_buf_average#(
parameter CMPRS_COLOR18 = 0, // JPEG 4:2:0 with 18x18 overlapping tiles for de-bayer
parameter CMPRS_COLOR20 = 1, // JPEG 4:2:0 with 18x18 overlapping tiles for de-bayer (not implemented)
parameter CMPRS_MONO16 = 2, // JPEG 4:2:0 with 16x16 non-overlapping tiles, color components zeroed
parameter CMPRS_JP4 = 3, // JP4 mode with 16x16 macroblocks
parameter CMPRS_JP4DIFF = 4, // JP4DIFF mode TODO: see if correct
parameter CMPRS_MONO8 = 7 // Regular JPEG monochrome with 8x8 macroblocks (not yet implemented)
)(
input xclk, // global clock input, compressor single clock rate
input frame_en,
input [2:0] converter_type, // valid @ pre_first_in
input pre_first_in, // marks the first input pixel from the external memory buffer
input yc_pre_first_out, // pre first output from color converter(s) to the Y/C buffers (was pre_first_out)
input [ 1:0] bayer_phase, // valid @ pre_first_in
input jp4_dc_improved,// valid @ pre_first_in
input hdr, // valid @ pre_first_in
input subtract_dc_in, // valid @ pre_first_in: enable subtracting of DC component
input first_mb_in, // valid @ pre_first_in - reading first macroblock
input last_mb_in, // valid @ pre_first_in - reading last macroblock
input [ 7:0] yaddrw,
input ywe,
input [ 8:0] signed_y,
input [ 7:0] caddrw,
input cwe,
input [ 8:0] signed_c,
output [ 9:0] do, // [9:0] data out (4:2:0) (signed, average=0)
// When is it valid?
output [ 8:0] avr, // [8:0] DC (average value) - RAM output, no register. For Y components 9'h080..9'h07f, for C - 9'h100..9'h0ff!
output dv, // out data valid (will go high for at least 64 cycles)
output ds, // single-cycle mark of the first_r pixel in a 64 (8x8) - pixel block
output [ 2:0] tn, // [2:0] tile number 0..3 - Y, 4 - Cb, 5 - Cr (valid with start)
output reg first, // sending first_r MCU (valid @ ds)
output reg last, // sending last_r MCU (valid @ ds)
// below signals valid at ds ( 1 later than tn, first_r, last_r)
output [2:0] component_num, //[2:0] - component number (YCbCr: 0 - Y, 1 - Cb, 2 - Cr, JP4: 0-1-2-3 in sequence (depends on shift) 4 - don't use
output component_color, // use color quantization table (YCbCR, jp4diff)
output component_first, // first_r this component in a frame (DC absolute, otherwise - difference to previous)
output reg component_lastinmb // last_r component in a macroblock;
);
wire [5:0] component_numsLS; // component_num[0] vs tn
wire [5:0] component_numsMS; // component_num[1] vs tn
wire [5:0] component_numsHS; // component_num[2] vs tn
wire [5:0] component_colorsS; // use color quantization table (YCbCR, jp4diff)
wire [5:0] component_firstsS; // first_r this component in a frame (DC absolute, otherwise - difference to previous)
reg [5:0] component_numsL; // component_num[0] vs tn
reg [5:0] component_numsM; // component_num[1] vs tn
reg [5:0] component_numsH; // component_num[2] vs tn
reg [5:0] component_colors; // use color quantization table (YCbCR, jp4diff)
reg [5:0] component_firsts; // first_r this component in a frame (DC absolute, otherwise - difference to previous)
// Y and C components buffer filled in by color conversion module
reg [1:0] wpage; // page (0/1) where data is being written to (both Y and CbCr)
reg [1:0] rpage; // page (0/1) from where data is sent out ( both Y and CbCr)
reg [8:0] raddr; // output address of buffer memories (MSB selects Y(0)/CbCr(1))
wire four_blocks; // decoded from converter_type
reg four_blocks_rd; // 4 blocks/macroblock, valid with raddr
wire [1:0] y_ren; // read enable for Y buffer ([0] - ren, [1] - regen)
wire [1:0] c_ren; // read enable for C buffer ([0] - ren, [1] - regen)
reg y_ren_r; // regen for Y buffer
reg c_ren_r; // regen for C buffer
wire [8:0] y_out; // data output from Y block buffer, valid @
wire [8:0] c_out; // data output from C block buffer, valid @
wire pre_subtract_dc;
reg subtract_dc;
wire pre_color_enable;
reg color_enable;
wire color_enable_d;// delay by 2 clocks to match data
wire pre_first_mb;
wire pre_last_mb;
// Copied from old code - check/fix it
reg [3:0] accYen;
reg [1:0] accCen; // individual accumulator enable (includes clearing)
reg [3:0] accYfirst;
reg [1:0] accCfirst; // add to zero, instead of to acc @ acc*en
reg [8:0] preAccY, preAccC; // registered data from color converters, matching acc selection latency
reg [14:0] accY0,accY1,accY2,accY3,accC0,accC1;
reg cs_first_out;
wire cs_first_out_late; // delay by 16 cycles - safe for overlap to set subrtact_dc mode
reg [5:0] accCntrY0,accCntrY1,accCntrY2,accCntrY3,accCntrC0,accCntrC1;
wire [3:0] pre_accYdone;
wire [1:0] pre_accCdone; // need to make sure that pre_accCdone do_r not happen with pre_accYdone
reg [3:0] accYrun;
reg [1:0] accCrun;
reg [3:0] accYdone; // only bit 0 is used as a start of output
reg accYdoneAny;
reg [1:0] avrY_wa, pre_avrY_wa;
reg avrC_wa, pre_avrC_wa;
reg avrPage_wa, pre_avrPage_wa;
reg avr_we; // Write to memory that stores average value
reg [8:0] avermem[0:15]; // average values memory - 2 pages (MSB) of 6 block values
wire [3:0] avr_wa= {avrPage_wa,accYdoneAny?{1'b0,avrY_wa[1:0]}:{2'b10,avrC_wa}};
reg [3:0] avr_ra; // read address for "average" memory
reg [8:0] avr_r; // registered output data from average memory (simultaneouis with regsitered buffer data)
// truncating average values
wire [8:0] avrY_di= avrY_wa[1] ? (avrY_wa[0]?accY3[14:6]:accY2[14:6]):(avrY_wa[0]?accY1[14:6]:accY0[14:6]);
wire [8:0] avrC_di= avrC_wa ?accC1[14:6]:accC0[14:6];
reg [1:0] buf_sel;
reg [9:0] pre_do;
reg [9:0] do_r;
reg dv_pre3; //3 cycles ahead of dv (data valid)
reg ds_pre3; //3 cycles ahead of ds (data strobe - first cycle of dv)
reg raddr_lastInBlock;
reg raddr_updateBlock; // first_r in block, after last_r also. Should be when *_r match the currently selected converter for the macroblock
reg ccv_out_start_d; // ccv_out_start delayed by 1 clock to match time of raddr_updateBlock
reg [ 2:0] converter_type_r;
reg ccv_out_start; // find the best way to calculate (maybe just a common counter with different presets)
// active 1 clk before start or reading blocks
// accCntr* counters after the first value will be set to 1 (was 0 before)
assign pre_accYdone[3:0] = {(accCntrY3[5:0] == 6'h3f) ? 1'b1 : 1'b0,
(accCntrY2[5:0] == 6'h3f) ? 1'b1 : 1'b0,
(accCntrY1[5:0] == 6'h3f) ? 1'b1 : 1'b0,
(accCntrY0[5:0] == 6'h3f) ? 1'b1 : 1'b0} & accYen[3:0];
assign pre_accCdone[1:0] = {(accCntrC1[5:0] == 6'h3f) ? 1'b1 : 1'b0,
(accCntrC0[5:0] == 6'h3f) ? 1'b1 : 1'b0} & accCen[1:0];
assign y_ren={y_ren_r,!raddr[8]};
assign c_ren={c_ren_r,raddr[8] && !raddr[7]};
// assign output signals
assign avr = avr_r; // avermem[avr_ra[3:0]];
assign do = do_r;
assign tn[2:0] = raddr[8:6];
// component_num,component_color,component_first for different converters vs tn (1 bit per tn (0..5)
assign component_num[2:0]= {component_numsH[0],component_numsM[0],component_numsL[0]};
assign component_color = component_colors[0];
assign component_first = component_firsts[0];
// Calculate average values for each block, count them to know when all 64 are ready, store trunctaed result in 9*16 memory
always @ (posedge xclk) begin
cs_first_out<= yc_pre_first_out;
if (ywe) preAccY[8:0] <= signed_y[8:0];
if (cwe) preAccC[8:0] <= signed_c[8:0];
accYen[3:0] <= {4{frame_en & ywe}} & { yaddrw[7] & yaddrw[6],
yaddrw[7] & ~yaddrw[6],
~yaddrw[7] & yaddrw[6],
~yaddrw[7] & ~yaddrw[6]};
accCen[1:0] <= {2{frame_en & cwe}} & { caddrw[6],
~caddrw[6]};
accYfirst[3:0] <= {4{cs_first_out}} | (accYfirst[3:0] & ~accYen[3:0]);
accCfirst[1:0] <= {2{cs_first_out}} | (accCfirst[1:0] & ~accCen[1:0]);
if (accYen[0]) accY0[14:0]<= (accYfirst[0]?15'h0:accY0[14:0]) + {{6{preAccY[8]}},preAccY[8:0]};
if (accYen[1]) accY1[14:0]<= (accYfirst[1]?15'h0:accY1[14:0]) + {{6{preAccY[8]}},preAccY[8:0]};
if (accYen[2]) accY2[14:0]<= (accYfirst[2]?15'h0:accY2[14:0]) + {{6{preAccY[8]}},preAccY[8:0]};
if (accYen[3]) accY3[14:0]<= (accYfirst[3]?15'h0:accY3[14:0]) + {{6{preAccY[8]}},preAccY[8:0]};
if (accCen[0]) accC0[14:0]<= (accCfirst[0]?15'h0:accC0[14:0]) + {{6{preAccC[8]}},preAccC[8:0]};
if (accCen[1]) accC1[14:0]<= (accCfirst[1]?15'h0:accC1[14:0]) + {{6{preAccC[8]}},preAccC[8:0]};
if (!frame_en) accCntrY0[5:0]<= 6'h0;
else if (accYen[0]) accCntrY0[5:0]<= (accYfirst[0]?6'h1:(accCntrY0[5:0]+1)); // was set to 0 before
if (!frame_en) accCntrY1[5:0]<= 6'h0;
else if (accYen[1]) accCntrY1[5:0]<= (accYfirst[1]?6'h1:(accCntrY1[5:0]+1));
if (!frame_en) accCntrY2[5:0]<= 6'h0;
else if (accYen[2]) accCntrY2[5:0]<= (accYfirst[2]?6'h1:(accCntrY2[5:0]+1));
if (!frame_en) accCntrY3[5:0]<= 6'h0;
else if (accYen[3]) accCntrY3[5:0]<= (accYfirst[3]?6'h1:(accCntrY3[5:0]+1));
if (!frame_en) accCntrC0[5:0]<= 6'h0;
else if (accCen[0]) accCntrC0[5:0]<= (accCfirst[0]?6'h1:(accCntrC0[5:0]+1));
if (!frame_en) accCntrC1[5:0]<= 6'h0;
else if (accCen[1]) accCntrC1[5:0]<= (accCfirst[1]?6'h1:(accCntrC1[5:0]+1));
accYrun[3:0] <= {4{frame_en}} & ((accYfirst[3:0] & accYen[3:0]) | (accYrun[3:0] & ~pre_accYdone[3:0]));
accCrun[1:0] <= {2{frame_en}} & ((accCfirst[1:0] & accCen[1:0]) | (accCrun[1:0] & ~pre_accCdone[1:0]));
accYdone[3:0] <= pre_accYdone[3:0] & accYrun[3:0];
accYdoneAny <= |(pre_accYdone[3:0] & accYrun[3:0]);
avr_we <= |(pre_accYdone[3:0] & accYrun[3:0]) || |(pre_accCdone[1:0] & accCrun[1:0]);
// Delay write addresses to find write address of the block for which average value is recorded
pre_avrY_wa[1:0] <= yaddrw[7:6];
avrY_wa[1:0] <= pre_avrY_wa[1:0];
pre_avrC_wa <= caddrw[ 6];
avrC_wa <= pre_avrC_wa;
pre_avrPage_wa <= wpage[0];
avrPage_wa <= pre_avrPage_wa;
if (avr_we) avermem[avr_wa[3:0]] <= subtract_dc?(accYdoneAny?avrY_di[8:0]:avrC_di[8:0]):9'h0;
end
always @(posedge xclk) begin
if (!frame_en) wpage <= 0;
else if (yc_pre_first_out) wpage <= wpage + 1; // will start from 1, not 0. Maybe changed to there strobe - end of writing
if (ccv_out_start) begin
rpage[1:0] <= wpage[1:0];
four_blocks_rd <= four_blocks;
first <= pre_first_mb;
last <= pre_last_mb;
color_enable <= pre_color_enable; // valid with address
end
// read buffers timing
// Is it that raddr[8:7] == 2'b11 means "disable
if (!frame_en) raddr[8:0] <= 9'h180;
else if (ccv_out_start) raddr[8:0] <= 0;
else if (!raddr[8] || (!four_blocks_rd && !raddr[7])) raddr[8:0] <= raddr[8:0]+1; // for 4 blocks - count for 0,1; 6 blocks - 0,1,2
// Reading output data and combining with the average values
y_ren_r <= y_ren[0];
c_ren_r <= c_ren[0];
if (cs_first_out_late) subtract_dc <= pre_subtract_dc;
avr_ra[3:0] <= {rpage[0],raddr[8:6]};
avr_r <= avermem[avr_ra[3:0]];
buf_sel <= {buf_sel[0],raddr[8]};
pre_do[9:0] <= buf_sel[1]?(color_enable_d?({c_out[8],c_out[8:0]}-{avr[8],avr[8:0]}):10'b0):({y_out[8],y_out[8:0]}-{avr[8],avr[8:0]});
do_r[9:0] <= pre_do[9:0];
raddr_lastInBlock <= frame_en && (raddr[5:0]==6'h3e);
raddr_updateBlock <= raddr_lastInBlock || ccv_out_start;
ccv_out_start_d <= ccv_out_start;
if (!frame_en) dv_pre3 <= 0;
else if (raddr_updateBlock) dv_pre3 <= !raddr[8] || (!four_blocks_rd && !raddr[7]);
ds_pre3 <= raddr_updateBlock && (!raddr[8] || (!four_blocks_rd && !raddr[7]));
// generate blobk type data
// Shift registers - generating block attributes to be used later in compressor
if (raddr_updateBlock) begin
if (ccv_out_start_d) begin // ccv_out_start_d valid with raddr_updateBlock
component_numsL[5:0] <= component_numsLS[5:0];
component_numsM[5:0] <= component_numsMS[5:0];
component_numsH[5:0] <= component_numsHS[5:0];
component_colors[5:0] <= component_colorsS[5:0];
component_firsts[5:0] <= pre_first_mb? component_firstsS[5:0]:6'h0;
end else begin
component_numsL[5:0] <= {1'b0,component_numsL[5:1]};
component_numsM[5:0] <= {1'b0,component_numsM[5:1]};
component_numsH[5:0] <= {1'b0,component_numsH[5:1]};
component_colors[5:0] <= {1'b0,component_colors[5:1]};
component_firsts[5:0] <= {1'b0,component_firsts[5:1]};
end
end
component_lastinmb <= tn[0] && (four_blocks_rd? tn[1] : tn[2]); // last component in a macroblock;
end
// when to start reading out data from the buffer
always @ (posedge xclk) if (pre_first_in)begin
converter_type_r <= converter_type;
end
always @ (posedge xclk) begin
case (converter_type_r)
CMPRS_COLOR18: ccv_out_start <= (yaddrw[7:0]==8'hc4); //TODO: adjust to minimal latency?
CMPRS_COLOR20: ccv_out_start <= (yaddrw[7:0]==8'hc4); //TODO: adjust to minimal latency?
CMPRS_MONO16: ccv_out_start <= accYdone[0];
CMPRS_JP4: ccv_out_start <= accYdone[0];
CMPRS_JP4DIFF: ccv_out_start <= accYdone[0];
CMPRS_MONO8: ccv_out_start <= accYdone[0];
default: ccv_out_start <= accYdone[0];
endcase
end
// delay from the start of data output from color converter to copy subtract_dc to be valid when average values are set
dly_16 #(.WIDTH(1)) i_cs_first_out_late (.clk(xclk),.rst(1'b0), .dly(15), .din(cs_first_out), .dout(cs_first_out_late));
dly_16 #(.WIDTH(1)) i_color_enable_d (.clk(xclk),.rst(1'b0), .dly( 1), .din(color_enable), .dout(color_enable_d));
dly_16 #(.WIDTH(1)) i_dv (.clk(xclk),.rst(1'b0), .dly( 2), .din(dv_pre3), .dout(dv));
dly_16 #(.WIDTH(1)) i_ds (.clk(xclk),.rst(1'b0), .dly( 2), .din(ds_pre3), .dout(ds));
cmprs_tile_mode2_decode #(
.CMPRS_COLOR18 (CMPRS_COLOR18),
.CMPRS_COLOR20 (CMPRS_COLOR20),
.CMPRS_MONO16 (CMPRS_MONO16),
.CMPRS_JP4 (CMPRS_JP4),
.CMPRS_JP4DIFF (CMPRS_JP4DIFF),
.CMPRS_MONO8 (CMPRS_MONO8)
) cmprs_tile_mode2_decode_i (
.xclk (xclk), // input
.pre_first_in (pre_first_in), // input
.converter_type (converter_type), // input[2:0]
.bayer_phase (bayer_phase), // input[1:0]
.jp4_dc_improved (jp4_dc_improved), // input
.hdr (hdr), // input
.subtract_dc_in (subtract_dc_in), // input
.first_mb_in (first_mb_in), // input
.last_mb_in (last_mb_in), // input
.four_blocks (four_blocks), // output reg
.subtract_dc (pre_subtract_dc), // output reg
.first_mb (pre_first_mb), // output reg
.last_mb (pre_last_mb), // output reg
.color_enable (pre_color_enable), // prevent JPEG random colors
.component_numsL (component_numsLS), // output[5:0] reg
.component_numsM (component_numsMS), // output[5:0] reg
.component_numsH (component_numsHS), // output[5:0] reg
.component_colors (component_colorsS), // output[5:0] reg
.component_first (component_firstsS) // output[5:0] reg
);
ram18p_var_w_var_r #(
.REGISTERS (1), // will need to delay output strobe(s) by 1
.LOG2WIDTH_WR (3),
.LOG2WIDTH_RD (3),
.DUMMY (0)
) i_y_buff (
.rclk (xclk), // input
.raddr ({1'b0,rpage[1:0],raddr[7:0]}), // input[11:0]
.ren (y_ren[0]), // input // TODO: modify to read only when needed
.regen (y_ren[1]), // input
.data_out (y_out[8:0]), // output[8:0]
.wclk (xclk), // input
.waddr ({1'b0,wpage[1:0],yaddrw[7:0]}), // input[11:0]
.we (ywe), // input
.web (4'hf), // input[7:0]
.data_in (signed_y[8:0]) // input[9:0]
);
ram18p_var_w_var_r #(
.REGISTERS (1), // will need to delay output strobe(s) by 1
.LOG2WIDTH_WR (3),
.LOG2WIDTH_RD (3),
.DUMMY (0)
) i_CrCb_buff (
.rclk (xclk), // input
.raddr ({1'b0,rpage[1:0],raddr[7:0]}), // input[11:0]
.ren (c_ren[0]), // input // TODO: modify to read only when needed
.regen (c_ren[0]), // input
.data_out (c_out[8:0]), // output[8:0]
.wclk (xclk), // input
.waddr ({1'b0,wpage[1:0],yaddrw[7:0]}), // input[11:0]
.we (ywe), // input
.web (4'hf), // input[7:0]
.data_in (signed_c[8:0]) // input[71:0]
);
endmodule
......@@ -49,7 +49,9 @@ module cmprs_macroblock_buf_iface #(
// controller this can just be the same as mb_pre_end_in
output mb_pre_start_out, // 1 clock cycle before stream of addresses to the buffer
output [ 1:0] start_page, // page to read next tile from (or first of several pages)
output [ 6:0] macroblock_x // macroblock left pixel x relative to a tile (page) Maximal page - 128 bytes wide
output [ 6:0] macroblock_x, // macroblock left pixel x relative to a tile (page) Maximal page - 128 bytes wide
output reg first_mb, // during first macroblock (valid @mb_pre_start_out)
output last_mb // during last macroblock (valid @mb_pre_start_out)
);
......@@ -79,12 +81,14 @@ module cmprs_macroblock_buf_iface #(
reg mb_first_in_row;
reg mb_last_in_row;
reg mb_last_row;
wire mb_last;
// wire last_mb;
reg [ 2:0] next_valid; // number of next valid page (only 2 LSB are actual page number)
reg [ 2:0] next_invalid; // oldest valid page
reg [ 1:0] add_invalid; // advance next_invalid pointer by this value, send next_page pulses
reg [ 2:0] used_pages; // number of pages simultaneously used for the last macroblock
reg [ 2:0] needed_page; // calculate at MB start
reg pre_first_mb; // from frame start to mb_pre_start[2]
// reg first_mb; // from mb_pre_start[2] to mb_pre_start[1]
wire starting;
reg frame_pre_run;
......@@ -97,11 +101,11 @@ module cmprs_macroblock_buf_iface #(
assign mb_pre_start_out=mb_pre_start[5]; // first after wait?
assign macroblock_x = mbl_x;
assign mb_last = mb_last_row && mb_last_in_row;
assign last_mb = mb_last_row && mb_last_in_row;
assign starting = |mb_pre_start;
assign mb_pre_start_w = (mb_pre_end_in && (!mb_last || frame_en_w)) || (!frame_pre_run && frame_en_w && !frame_en_r && !starting);
assign frame_pre_start_w = frame_en_w && ((mb_pre_end_in && mb_last) || (!frame_pre_run && !frame_en_r && !starting));
assign mb_pre_start_w = (mb_pre_end_in && (!last_mb || frame_en_w)) || (!frame_pre_run && frame_en_w && !frame_en_r && !starting);
assign frame_pre_start_w = frame_en_w && ((mb_pre_end_in && last_mb) || (!frame_pre_run && !frame_en_r && !starting));
assign start_page = next_invalid[1:0]; // oldest page needed for this macroblock
always @ (posedge xclk) begin
......@@ -117,7 +121,7 @@ module cmprs_macroblock_buf_iface #(
if (!frame_en) frame_pre_run <= 0;
else if (mb_pre_start_w) frame_pre_run <= 1;
else if (mb_pre_end_in && mb_last) frame_pre_run <= 0;
else if (mb_pre_end_in && last_mb) frame_pre_run <= 0;
if (frame_pre_start_r) mb_rows_left <= n_block_rows_m1;
else if (mb_pre_start[0] && mb_last_in_row) mb_rows_left <= mb_rows_left - 1;
......@@ -129,6 +133,11 @@ module cmprs_macroblock_buf_iface #(
if (mb_pre_start[1]) mb_last_in_row <= (mb_cols_left == 0);
if (!frame_en || mb_pre_start[1]) pre_first_mb <= 0;
else if (frame_pre_start_r) pre_first_mb <= 1;
if (mb_pre_start[1]) first_mb <= pre_first_mb;
// pages read from the external memory, previous one is the last in the buffer
if (reset_page_rd) next_valid <= 0;
else if (page_ready) next_valid <= next_valid + 1;
......
/*******************************************************************************
* Module: cmprs_tile_mode2_decode
* Date:2015-06-14
* Author: andrey
* Description: Decode mode parameters, registered at pre-start of the macroblock
* data to color conversion module
*
* Copyright (c) 2015 <set up in Preferences-Verilog/VHDL Editor-Templates> .
* cmprs_tile_mode2_decode.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_tile_mode2_decode.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_tile_mode2_decode #(
parameter CMPRS_COLOR18 = 0, // JPEG 4:2:0 with 18x18 overlapping tiles for de-bayer
parameter CMPRS_COLOR20 = 1, // JPEG 4:2:0 with 18x18 overlapping tiles for de-bayer (not implemented)
parameter CMPRS_MONO16 = 2, // JPEG 4:2:0 with 16x16 non-overlapping tiles, color components zeroed
parameter CMPRS_JP4 = 3, // JP4 mode with 16x16 macroblocks
parameter CMPRS_JP4DIFF = 4, // JP4DIFF mode TODO: see if correct
parameter CMPRS_MONO8 = 7 // Regular JPEG monochrome with 8x8 macroblocks (not yet implemented)
)(
input xclk,
input pre_first_in, // marks the first input pixel
input [2:0] converter_type,
input [ 1:0] bayer_phase,
input jp4_dc_improved,
input hdr,
input subtract_dc_in,
input first_mb_in, // valid @ pre_first_in - reading first macroblock
input last_mb_in, // valid @ pre_first_in - reading last macroblock
output reg four_blocks, // 1 - 4 blocks, 0 - 6 blocks
output reg subtract_dc, // enable subtracting DC components
output reg first_mb, // valid @ pre_first_in - reading first macroblock
output reg last_mb, // valid @ pre_first_in - reading last macroblock
output reg color_enable, // prevent JPEG random colors
output reg [5:0] component_numsL, // component_num [0]
output reg [5:0] component_numsM, // component_num [1]
output reg [5:0] component_numsH, // component_num [2]
output reg [5:0] component_colors, // use color quantization table (YCbCR, jp4diff)
output reg [5:0] component_first // first_r this component in a frame (DC absolute, otherwise - difference to previous)
);
reg [2:0] converter_type_r;
reg jp4_dc_improved_r;
reg hdr_r;
reg [3:0] bayer_phase_onehot;
always @ (posedge xclk) if (pre_first_in)begin
converter_type_r [2:0] <= converter_type[2:0];
jp4_dc_improved_r <= jp4_dc_improved;
hdr_r <= hdr;
subtract_dc <= subtract_dc_in;
first_mb <= first_mb_in;
last_mb <= last_mb_in;
bayer_phase_onehot[3:0]<={(bayer_phase[1:0]==2'h3)?1'b1:1'b0,
(bayer_phase[1:0]==2'h2)?1'b1:1'b0,
(bayer_phase[1:0]==2'h1)?1'b1:1'b0,
(bayer_phase[1:0]==2'h0)?1'b1:1'b0};
case (converter_type_r)
CMPRS_COLOR18: begin
component_numsL <= 6'h10; // component_num [0]
component_numsM <= 6'h20; // component_num [1]
component_numsH <= 6'h00; // component_num [2]
component_colors <= 6'h30; // use color quantization table (YCbCR, jp4diff)
component_first <= 6'h31; // first_r this component in a frame (DC absolute, otherwise - difference to previous)
four_blocks <= 0; // 6 blocks/maceoblock mode
color_enable <= 1'b1;
end
CMPRS_COLOR20: begin
component_numsL <= 6'h10; // component_num [0]
component_numsM <= 6'h20; // component_num [1]
component_numsH <= 6'h3f; // component_num [2]
component_colors <= 6'h30; // use color quantization table (YCbCR, jp4diff)
component_first <= 6'h31; // first_r this component in a frame (DC absolute, otherwise - difference to previous)
four_blocks <= 0; // 6 blocks/maceoblock mode
color_enable <= 1'b1;
end
CMPRS_MONO16: begin
component_numsL <= 6'h10; // component_num [0]
component_numsM <= 6'h20; // component_num [1]
component_numsH <= 6'h30; // component_num [2]
component_colors <= 6'h30; // use color quantization table (YCbCR, jp4diff)
component_first <= 6'h31; // first_r this component in a frame (DC absolute, otherwise - difference to previous)
four_blocks <= 0; // 6 blocks/maceoblock mode
color_enable <= 1'b0;
end
CMPRS_JP4: begin
component_numsL <= jp4_dc_improved_r?6'h0a:6'h10; // LSb of component_num
component_numsM <= jp4_dc_improved_r?6'h0c:6'h20; // MSb of component_num
component_numsH <= 6'h30; // component_num [2]
component_colors <= 6'h30; // use color quantization table (YCbCR, jp4diff)
component_first <= jp4_dc_improved_r?6'h3f:6'h31; // first_r this component in a frame (DC absolute, otherwise - difference to previous)
four_blocks <= 1; // 4 blocks/maceoblock mode
color_enable <= 1'b0;
end
CMPRS_JP4DIFF: begin
component_numsL <= 6'h0a; // LSb of component_num
component_numsM <= 6'h0c; // MSb of component_num
component_numsH <= 6'h30; // component_num [2]
component_colors <= {2'h3,~bayer_phase_onehot[3:0] | (hdr_r? {~bayer_phase_onehot[1:0],~bayer_phase_onehot[3:2]} : 4'h0)}; // use color quantization table (YCbCR, jp4diff)
component_first <= 6'h3f; // first_r this component in a frame (DC absolute, otherwise - difference to previous)
four_blocks <= 1; // 4 blocks/maceoblock mode
color_enable <= 1'b0;
end
CMPRS_MONO8: begin
/*
component_numsL <= 6'h00; // TODO: Implement, put actuqal data in this and other fields
component_numsM <= 6'h00;
component_numsH <= 6'h30;
component_colors <= 6'h30;
component_first <= 6'h31;
color_enable <= 1'b0;
*/
end
default: begin
component_numsL <= 'bx;
component_numsM <= 'bx;
component_numsH <= 'bx;
component_colors <= 'bx;
component_first <= 'bx;
four_blocks <= 'bx;
color_enable <= 'bx;
end
endcase
end
endmodule
/*******************************************************************************
* Module: cmprs_tile_mode_decode
* Date:2015-06-14
* Author: andrey
* Description: Decode tile/macroblocks parameters from compressor type
*
* Copyright (c) 2015 <set up in Preferences-Verilog/VHDL Editor-Templates> .
* cmprs_tile_mode_decode.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_tile_mode_decode.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_tile_mode_decode #(
parameter CMPRS_COLOR18 = 0, // JPEG 4:2:0 with 18x18 overlapping tiles for de-bayer
parameter CMPRS_COLOR20 = 1, // JPEG 4:2:0 with 18x18 overlapping tiles for de-bayer (not implemented)
parameter CMPRS_MONO16 = 2, // JPEG 4:2:0 with 16x16 non-overlapping tiles, color components zeroed
parameter CMPRS_JP4 = 3, // JP4 mode with 16x16 macroblocks
parameter CMPRS_JP4DIFF = 4, // JP4DIFF mode TODO: see if correct
parameter CMPRS_MONO8 = 7 // Regular JPEG monochrome with 8x8 macroblocks (not yet implemented)
)(
input [2:0] converter_type,
output reg [ 5:0] mb_w_m1, // macroblock width minus 1 // 3 LSB not used, SHOULD BE SET to 3'b111
output reg [ 5:0] mb_h_m1, // macroblock horizontal period (8/16) // 3 LSB not used SHOULD BE SET to 3'b111
output reg [ 4:0] mb_hper, // macroblock horizontal period (8/16) // 3 LSB not used TODO: assign from converter_type[2:0]
output reg [ 1:0] tile_width, // memory tile width (can be 128 for monochrome JPEG) Can be 32/64/128: 0 - 16, 1 - 32, 2 - 64, 3 - 128
output reg tile_col_width // 0 - 16 pixels, 1 -32 pixels
);
// wire [ 2:0] converter_type; // 0 - color18, 1 - color20, 2 - mono, 3 - jp4, 4 - jp4-diff, 7 - mono8 (not yet implemented)
always @(converter_type) begin
case (converter_type)
CMPRS_COLOR18: begin
mb_w_m1 <= 17; // macroblock width minus 1 // 3 LSB not used, SHOULD BE SET to 3'b111
mb_h_m1 <= 17; // macroblock horizontal period (8/16) // 3 LSB not used SHOULD BE SET to 3'b111
mb_hper <= 16; // macroblock horizontal period (8/16) // 3 LSB not used TODO: assign from converter_type[2:0]
tile_width <= 1; // memory tile width (can be 128 for monochrome JPEG) Can be 32/64/128: 0 - 16, 1 - 32, 2 - 64, 3 - 128
tile_col_width <= 1; // 0 - 16 pixels, 1 -32 pixels
end
CMPRS_COLOR20: begin
mb_w_m1 <= 19; // macroblock width minus 1 // 3 LSB not used, SHOULD BE SET to 3'b111
mb_h_m1 <= 19; // macroblock horizontal period (8/16) // 3 LSB not used SHOULD BE SET to 3'b111
mb_hper <= 16; // macroblock horizontal period (8/16) // 3 LSB not used TODO: assign from converter_type[2:0]
tile_width <= 1; // memory tile width (can be 128 for monochrome JPEG) Can be 32/64/128: 0 - 16, 1 - 32, 2 - 64, 3 - 128
tile_col_width <= 1; // 0 - 16 pixels, 1 -32 pixels
end
CMPRS_MONO16: begin
mb_w_m1 <= 15; // macroblock width minus 1 // 3 LSB not used, SHOULD BE SET to 3'b111
mb_h_m1 <= 15; // macroblock horizontal period (8/16) // 3 LSB not used SHOULD BE SET to 3'b111
mb_hper <= 16; // macroblock horizontal period (8/16) // 3 LSB not used TODO: assign from converter_type[2:0]
tile_width <= 2; // memory tile width (can be 128 for monochrome JPEG) Can be 32/64/128: 0 - 16, 1 - 32, 2 - 64, 3 - 128
tile_col_width <= 1; // 0 - 16 pixels, 1 -32 pixels
end
CMPRS_JP4: begin
mb_w_m1 <= 15; // macroblock width minus 1 // 3 LSB not used, SHOULD BE SET to 3'b111
mb_h_m1 <= 15; // macroblock horizontal period (8/16) // 3 LSB not used SHOULD BE SET to 3'b111
mb_hper <= 16; // macroblock horizontal period (8/16) // 3 LSB not used TODO: assign from converter_type[2:0]
tile_width <= 2; // memory tile width (can be 128 for monochrome JPEG) Can be 32/64/128: 0 - 16, 1 - 32, 2 - 64, 3 - 128
tile_col_width <= 1; // 0 - 16 pixels, 1 -32 pixels
end
CMPRS_JP4DIFF: begin
mb_w_m1 <= 15; // macroblock width minus 1 // 3 LSB not used, SHOULD BE SET to 3'b111
mb_h_m1 <= 15; // macroblock horizontal period (8/16) // 3 LSB not used SHOULD BE SET to 3'b111
mb_hper <= 16; // macroblock horizontal period (8/16) // 3 LSB not used TODO: assign from converter_type[2:0]
tile_width <= 2; // memory tile width (can be 128 for monochrome JPEG) Can be 32/64/128: 0 - 16, 1 - 32, 2 - 64, 3 - 128
tile_col_width <= 1; // 0 - 16 pixels, 1 -32 pixels
end
CMPRS_MONO8: begin
mb_w_m1 <= 7; // macroblock width minus 1 // 3 LSB not used, SHOULD BE SET to 3'b111
mb_h_m1 <= 7; // macroblock horizontal period (8/16) // 3 LSB not used SHOULD BE SET to 3'b111
mb_hper <= 8; // macroblock horizontal period (8/16) // 3 LSB not used TODO: assign from converter_type[2:0]
tile_width <= 3; // memory tile width (can be 128 for monochrome JPEG) Can be 32/64/128: 0 - 16, 1 - 32, 2 - 64, 3 - 128
tile_col_width <= 1; // 0 - 16 pixels, 1 -32 pixels
end
default: begin
mb_w_m1 <= 'bx; // macroblock width minus 1 // 3 LSB not used, SHOULD BE SET to 3'b111
mb_h_m1 <= 'bx; // macroblock horizontal period (8/16) // 3 LSB not used SHOULD BE SET to 3'b111
mb_hper <= 'bx; // macroblock horizontal period (8/16) // 3 LSB not used TODO: assign from converter_type[2:0]
tile_width <= 'bx; // memory tile width (can be 128 for monochrome JPEG) Can be 32/64/128: 0 - 16, 1 - 32, 2 - 64, 3 - 128
tile_col_width <= 'bx; // 0 - 16 pixels, 1 -32 pixels
end
endcase
end
endmodule
......@@ -48,7 +48,7 @@ module color_proc393 (
output dv_raw, // data valid for di (for testing to bypass color conversion - use di[7:0])
input ignore_color, //zero Cb/Cr components
input four_blocks, // use only 6 blocks for the output, not 6
input four_blocks, // use only 4 blocks for the output, not 6
input jp4_dc_improved, // in JP4 mode, compare DC coefficients to the same color ones
input [ 1:0] tile_margin, // margins around 16x16 tiles (0/1/2)
input [ 2:0] tile_shift, // tile shift from top left corner
......@@ -56,7 +56,7 @@ module color_proc393 (
input scale_diff, // divide differences by 2 (to fit in 8-bit range)
input hdr, // second green absolute, not difference
output [ 9:0] do, // [9:0] data out (4:2:0) (signed, average=0)
output [ 8:0] avr, // [8:0] DC (average value) - RAM output, no register. For Y components 9'h080..9'h07f, for C - 9'h100..9'h0ff!
output [ 8:0] avr, // [8:0] DC (average value) - RAM output, no register. For Y components 9'h080..9'h07f, for C - 9'h100..9'h0ff!
output dv, // out data valid (will go high for at least 64 cycles)
output ds, // single-cycle mark of the first_r pixel in a 64 (8x8) - pixel block
output [ 2:0] tn, // [2:0] tile number 0..3 - Y, 4 - Cb, 5 - Cr (valid with start)
......@@ -273,50 +273,56 @@ module color_proc393 (
wire [8:0] avrY_di= avrY_wa[1] ? (avrY_wa[0]?accY3[14:6]:accY2[14:6]):(avrY_wa[0]?accY1[14:6]:accY0[14:6]);
wire [8:0] avrC_di= avrC_wa ?accC1[14:6]:accC0[14:6];
assign avr = avermem[avr_ra[3:0]];
assign pre_accYdone[3:0] = {(accCntrY3[5:0]==6'h3e)?1'b1:1'b0,(accCntrY2[5:0]==6'h3e)?1'b1:1'b0,(accCntrY1[5:0]==6'h3e)?1'b1:1'b0,(accCntrY0[5:0]==6'h3e)?1'b1:1'b0} & accYen[3:0];
assign pre_accCdone[1:0] = { (accCntrC1[5:0]==6'h3e)?1'b1:1'b0,(accCntrC0[5:0]==6'h3e)?1'b1:1'b0} & accCen[1:0];
assign pre_accYdone[3:0] = {(accCntrY3[5:0]==6'h3e)?1'b1:1'b0,
(accCntrY2[5:0]==6'h3e)?1'b1:1'b0,
(accCntrY1[5:0]==6'h3e)?1'b1:1'b0,
(accCntrY0[5:0]==6'h3e)?1'b1:1'b0} & accYen[3:0];
assign pre_accCdone[1:0] = {(accCntrC1[5:0]==6'h3e)?1'b1:1'b0,
(accCntrC0[5:0]==6'h3e)?1'b1:1'b0} & accCen[1:0];
always @ (posedge clk) begin
cs_first_out<=cs_pre_first_out;
if (ywe) preAccY[8:0] <= y_in[8:0];
if (cwe) preAccC[8:0] <= c_in[8:0];
accYen[3:0] <= {4{en & ywe}} & {yaddrw[7] & yaddrw[6], yaddrw[7] & ~yaddrw[6],~ yaddrw[7] & yaddrw[6], ~yaddrw[7] & ~yaddrw[6]};
accCen[1:0] <= {2{en & cwe}} & {caddrw[6], ~caddrw[6]};
accYfirst[3:0] <= {4{cs_first_out}} | (accYfirst[3:0] & ~accYen[3:0]);
accCfirst[1:0] <= {2{cs_first_out}} | (accCfirst[1:0] & ~accCen[1:0]);
if (accYen[0]) accY0[14:0]<= (accYfirst[0]?15'h0:accY0[14:0]) + {{6{preAccY[8]}},preAccY[8:0]};
if (accYen[1]) accY1[14:0]<= (accYfirst[1]?15'h0:accY1[14:0]) + {{6{preAccY[8]}},preAccY[8:0]};
if (accYen[2]) accY2[14:0]<= (accYfirst[2]?15'h0:accY2[14:0]) + {{6{preAccY[8]}},preAccY[8:0]};
if (accYen[3]) accY3[14:0]<= (accYfirst[3]?15'h0:accY3[14:0]) + {{6{preAccY[8]}},preAccY[8:0]};
if (accCen[0]) accC0[14:0]<= (accCfirst[0]?15'h0:accC0[14:0]) + {{6{preAccC[8]}},preAccC[8:0]};
if (accCen[1]) accC1[14:0]<= (accCfirst[1]?15'h0:accC1[14:0]) + {{6{preAccC[8]}},preAccC[8:0]};
if (!en) accCntrY0[5:0]<= 6'h0; else if (accYen[0]) accCntrY0[5:0]<= (accYfirst[0]?6'h0:(accCntrY0[5:0]+1));
if (!en) accCntrY1[5:0]<= 6'h0; else if (accYen[1]) accCntrY1[5:0]<= (accYfirst[1]?6'h0:(accCntrY1[5:0]+1));
if (!en) accCntrY2[5:0]<= 6'h0; else if (accYen[2]) accCntrY2[5:0]<= (accYfirst[2]?6'h0:(accCntrY2[5:0]+1));
if (!en) accCntrY3[5:0]<= 6'h0; else if (accYen[3]) accCntrY3[5:0]<= (accYfirst[3]?6'h0:(accCntrY3[5:0]+1));
if (!en) accCntrC0[5:0]<= 6'h0; else if (accCen[0]) accCntrC0[5:0]<= (accCfirst[0]?6'h0:(accCntrC0[5:0]+1));
if (!en) accCntrC1[5:0]<= 6'h0; else if (accCen[1]) accCntrC1[5:0]<= (accCfirst[1]?6'h0:(accCntrC1[5:0]+1));
accYrun[3:0] <= {4{en}} & ((accYfirst[3:0] & accYen[3:0]) | (accYrun[3:0] & ~pre_accYdone[3:0]));
accCrun[1:0] <= {2{en}} & ((accCfirst[1:0] & accCen[1:0]) | (accCrun[1:0] & ~pre_accCdone[1:0]));
accYdone[3:0] <= pre_accYdone[3:0] & accYrun[3:0];
accYdoneAny <= |(pre_accYdone[3:0] & accYrun[3:0]);
avr_we <= |(pre_accYdone[3:0] & accYrun[3:0]) || |(pre_accCdone[1:0] & accCrun[1:0]);
pre_avrY_wa[1:0] <= yaddrw[7:6];
avrY_wa[1:0] <= pre_avrY_wa[1:0];
pre_avrC_wa <= caddrw[ 6];
avrC_wa <= pre_avrC_wa;
pre_avrPage_wa <= wpage[0];
avrPage_wa <= pre_avrPage_wa;
if (avr_we) avermem[avr_wa[3:0]] <= en_sdc?(accYdoneAny?avrY_di[8:0]:avrC_di[8:0]):9'h0;
avr_ra[3:0] <= {rpage[0],raddr[8:6]};
raddr8_d <= raddr[8];
cs_first_out<=cs_pre_first_out;
if (ywe) preAccY[8:0] <= y_in[8:0];
if (cwe) preAccC[8:0] <= c_in[8:0];
accYen[3:0] <= {4{en & ywe}} & {yaddrw[7] & yaddrw[6],
yaddrw[7] & ~yaddrw[6],
~yaddrw[7] & yaddrw[6],
~yaddrw[7] & ~yaddrw[6]};
accCen[1:0] <= {2{en & cwe}} & { caddrw[6],
~caddrw[6]};
accYfirst[3:0] <= {4{cs_first_out}} | (accYfirst[3:0] & ~accYen[3:0]);
accCfirst[1:0] <= {2{cs_first_out}} | (accCfirst[1:0] & ~accCen[1:0]);
if (accYen[0]) accY0[14:0]<= (accYfirst[0]?15'h0:accY0[14:0]) + {{6{preAccY[8]}},preAccY[8:0]};
if (accYen[1]) accY1[14:0]<= (accYfirst[1]?15'h0:accY1[14:0]) + {{6{preAccY[8]}},preAccY[8:0]};
if (accYen[2]) accY2[14:0]<= (accYfirst[2]?15'h0:accY2[14:0]) + {{6{preAccY[8]}},preAccY[8:0]};
if (accYen[3]) accY3[14:0]<= (accYfirst[3]?15'h0:accY3[14:0]) + {{6{preAccY[8]}},preAccY[8:0]};
if (accCen[0]) accC0[14:0]<= (accCfirst[0]?15'h0:accC0[14:0]) + {{6{preAccC[8]}},preAccC[8:0]};
if (accCen[1]) accC1[14:0]<= (accCfirst[1]?15'h0:accC1[14:0]) + {{6{preAccC[8]}},preAccC[8:0]};
if (!en) accCntrY0[5:0]<= 6'h0; else if (accYen[0]) accCntrY0[5:0]<= (accYfirst[0]?6'h0:(accCntrY0[5:0]+1));
if (!en) accCntrY1[5:0]<= 6'h0; else if (accYen[1]) accCntrY1[5:0]<= (accYfirst[1]?6'h0:(accCntrY1[5:0]+1));
if (!en) accCntrY2[5:0]<= 6'h0; else if (accYen[2]) accCntrY2[5:0]<= (accYfirst[2]?6'h0:(accCntrY2[5:0]+1));
if (!en) accCntrY3[5:0]<= 6'h0; else if (accYen[3]) accCntrY3[5:0]<= (accYfirst[3]?6'h0:(accCntrY3[5:0]+1));
if (!en) accCntrC0[5:0]<= 6'h0; else if (accCen[0]) accCntrC0[5:0]<= (accCfirst[0]?6'h0:(accCntrC0[5:0]+1));
if (!en) accCntrC1[5:0]<= 6'h0; else if (accCen[1]) accCntrC1[5:0]<= (accCfirst[1]?6'h0:(accCntrC1[5:0]+1));
accYrun[3:0] <= {4{en}} & ((accYfirst[3:0] & accYen[3:0]) | (accYrun[3:0] & ~pre_accYdone[3:0]));
accCrun[1:0] <= {2{en}} & ((accCfirst[1:0] & accCen[1:0]) | (accCrun[1:0] & ~pre_accCdone[1:0]));
accYdone[3:0] <= pre_accYdone[3:0] & accYrun[3:0];
accYdoneAny <= |(pre_accYdone[3:0] & accYrun[3:0]);
avr_we <= |(pre_accYdone[3:0] & accYrun[3:0]) || |(pre_accCdone[1:0] & accCrun[1:0]);
pre_avrY_wa[1:0] <= yaddrw[7:6];
avrY_wa[1:0] <= pre_avrY_wa[1:0];
pre_avrC_wa <= caddrw[ 6];
avrC_wa <= pre_avrC_wa;
pre_avrPage_wa <= wpage[0];
avrPage_wa <= pre_avrPage_wa;
if (avr_we) avermem[avr_wa[3:0]] <= en_sdc?(accYdoneAny?avrY_di[8:0]:avrC_di[8:0]):9'h0;
avr_ra[3:0] <= {rpage[0],raddr[8:6]};
raddr8_d <= raddr[8];
end
reg transfer_ended=0; /// there was already EOT pulse for the current frame
......@@ -400,7 +406,7 @@ module color_proc393 (
yaddrw[7:0] <= {conv18_yaddrw[7],conv18_yaddrw[3],conv18_yaddrw[6:4],conv18_yaddrw[2:0]};
c_in[8:0] <= {conv18_c_in[8:0]};
cwe <= conv18_cwe;
pre_color_enable <= 1'b1;
pre_color_enable <= 1'b1;
caddrw[7:0] <= {1'b0,conv18_caddrw[6:0]};
ccv_out_start <= (conv18_yaddrw[7:0]==8'hc5); //TODO: adjust to minimal latency?
component_numsLS <= 6'h10; // component_num [0]
......@@ -416,7 +422,7 @@ module color_proc393 (
yaddrw[7:0] <= {conv20_yaddrw[7],conv20_yaddrw[3],conv20_yaddrw[6:4],conv20_yaddrw[2:0]};
c_in[8:0] <= {conv20_c_in[8:0]};
cwe <= conv20_cwe;
pre_color_enable <= 1'b1;
pre_color_enable <= 1'b1;
caddrw[7:0] <= {1'b0,conv20_caddrw[6:0]};
ccv_out_start <= (conv20_yaddrw[7:0]==8'hc5); //TODO: adjust to minimal latency?
component_numsLS <= 6'h10; // component_num [0]
......
/*******************************************************************************
* Module: csconvert
* Date:2015-06-14
* Author: andrey
* Description: Color space convert: combine differnt color modes
*
* Copyright (c) 2015 <set up in Preferences-Verilog/VHDL Editor-Templates> .
* csconvert.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.
*
* csconvert.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 csconvert#(
parameter CMPRS_COLOR18 = 0, // JPEG 4:2:0 with 18x18 overlapping tiles for de-bayer
parameter CMPRS_COLOR20 = 1, // JPEG 4:2:0 with 18x18 overlapping tiles for de-bayer (not implemented)
parameter CMPRS_MONO16 = 2, // JPEG 4:2:0 with 16x16 non-overlapping tiles, color components zeroed
parameter CMPRS_JP4 = 3, // JP4 mode with 16x16 macroblocks
parameter CMPRS_JP4DIFF = 4, // JP4DIFF mode TODO: see if correct
parameter CMPRS_MONO8 = 7 // Regular JPEG monochrome with 8x8 macroblocks (not yet implemented)
)(
input xclk,
input frame_en,
input [ 2:0] converter_type,
input ignore_color, //zero Cb/Cr components
// input four_blocks, // use only 4 blocks for the output, not 6
// input jp4_dc_improved, // in JP4 mode, compare DC coefficients to the same color ones
input scale_diff, // divide differences by 2 (to fit in 8-bit range)
input hdr, // second green absolute, not difference
input limit_diff, // 1 - limit color outputs to -128/+127 range, 0 - let them be limited downstream (==1)
input [ 9:0] m_cb, // [9:0] scale for CB - default 0.564 (10'h90)
input [ 9:0] m_cr, // [9:0] scale for CB - default 0.713 (10'hb6)
input [ 7:0] mb_din, // input bayer data in scanline sequence, GR/BG sequence
input [ 1:0] bayer_phase,
input pre_first_in, // marks the first input pixel
output reg [ 8:0] signed_y, // - now signed char, -128(black) to +127 (white)
output reg [ 8:0] signed_c, // new, q is just signed char
output reg [ 7:0] yaddrw, // address for the external buffer memory to write 16x16x8bit Y data
output reg ywe, // wrire enable of Y data
output reg [ 7:0] caddrw, // address for the external buffer memory 2x8x8x8bit Cb+Cr data (MSB=0 - Cb, 1 - Cr)
output reg cwe, // write enable for CbCr data
output reg pre_first_out,
// output reg pre_color_enable,
// output reg ccv_out_start, //TODO: adjust to minimal latency?
output reg [ 7:0] n000, // not clear how they are used, make them just with latency1 from old
output reg [ 7:0] n255);
// outputs to be multiplexed:
wire [7:0] conv18_signed_y, conv20_signed_y, mono16_signed_y, jp4_signed_y;
wire [8:0] jp4diff_signed_y, conv18_signed_c, conv20_signed_c;
wire [7:0] conv18_yaddrw, conv20_yaddrw, mono16_yaddrw, jp4_yaddrw, jp4diff_yaddrw;
wire [6:0] conv18_caddrw, conv20_caddrw;
wire conv18_ywe, conv18_cwe, conv20_ywe, conv20_cwe, mono16_ywe, jp4_ywe, jp4diff_ywe;
wire conv18_pre_first_out, conv20_pre_first_out, mono16_pre_first_out, jp4_pre_first_out, jp4diff_pre_first_out;
wire [7:0] conv18_n000, conv20_n000, mono16_n000, jp4_n000, jp4diff_n000;
wire [7:0] conv18_n255, conv20_n255, mono16_n255, jp4_n255, jp4diff_n255;
reg [ 7:0] en_converters;
reg ignore_color_r; //zero Cb/Cr components
reg [2:0] converter_type_r;
// reg jp4_dc_improved_r;
// reg four_blocks_r;
reg scale_diff_r;
reg hdr_r;
// reg [1:0] tile_margin_r;
reg [1:0] bayer_phase_r;
// reg [3:0] bayer_phase_onehot;
// wire limit_diff = 1'b1; // as in the prototype - just a constant 1
/*
reg [5:0] component_numsLS; // component_num [0]
reg [5:0] component_numsMS; // component_num [1]
reg [5:0] component_numsHS; // component_num [2]
reg [5:0] component_colorsS; // use color quantization table (YCbCR, jp4diff)
reg [5:0] component_firstsS; // first_r this component in a frame (DC absolute, otherwise - difference to previous)
*/
always @ (posedge xclk) begin
if (pre_first_in) begin
converter_type_r [2:0] <= converter_type[2:0];
ignore_color_r <= ignore_color;
// jp4_dc_improved_r <= jp4_dc_improved;
// four_blocks_r <= four_blocks;
scale_diff_r <= scale_diff;
hdr_r <= hdr;
// tile_margin_r[1:0] <= tile_margin[1:0];
bayer_phase_r[1:0] <= bayer_phase[1:0];
// bayer_phase_onehot[3:0]<={(bayer_phase[1:0]==2'h3)?1'b1:1'b0,
// (bayer_phase[1:0]==2'h2)?1'b1:1'b0,
// (bayer_phase[1:0]==2'h1)?1'b1:1'b0,
// (bayer_phase[1:0]==2'h0)?1'b1:1'b0};
end
// generate one-hot converter enable
if (!frame_en) en_converters[CMPRS_COLOR18] <= 0;
else if (pre_first_in) en_converters[CMPRS_COLOR18] <= converter_type == CMPRS_COLOR18;
if (!frame_en) en_converters[CMPRS_COLOR20] <= 0;
else if (pre_first_in) en_converters[CMPRS_COLOR20] <= converter_type == CMPRS_COLOR20;
if (!frame_en) en_converters[CMPRS_MONO16] <= 0;
else if (pre_first_in) en_converters[CMPRS_MONO16] <= converter_type == CMPRS_MONO16;
if (!frame_en) en_converters[CMPRS_JP4] <= 0;
else if (pre_first_in) en_converters[CMPRS_JP4] <= converter_type == CMPRS_JP4;
if (!frame_en) en_converters[CMPRS_JP4DIFF] <= 0;
else if (pre_first_in) en_converters[CMPRS_JP4DIFF] <= converter_type == CMPRS_JP4DIFF;
if (!frame_en) en_converters[CMPRS_MONO8] <= 0;
else if (pre_first_in) en_converters[CMPRS_MONO8] <= converter_type == CMPRS_MONO8;
end
csconvert18a i_csconvert18 (
.RST (!en_converters[CMPRS_COLOR18]), // input
.CLK (xclk), // input
.mono (ignore_color_r), // input
.limit_diff (limit_diff), // input 1 - limit color outputs to -128/+127 range, 0 - let them be limited downstream
.m_cb (m_cb[9:0]), // input[9:0] scale for CB - default 0.564 (10'h90)
.m_cr (m_cr[9:0]), // input[9:0] scale for CB - default 0.713 (10'hb6)
.din (mb_din[7:0]), // input[7:0]
.pre_first_in (pre_first_in), // input
.signed_y (conv18_signed_y[7:0]),// output[7:0]
.q (conv18_signed_c[8:0]),// output[8:0]
.yaddr (conv18_yaddrw[7:0]), // output[7:0]
.ywe (conv18_ywe), // output
.caddr (conv18_caddrw[6:0]), // output[6:0]
.cwe (conv18_cwe), // output
.pre_first_out (conv18_pre_first_out),// output
.bayer_phase (bayer_phase_r[1:0]), // input[1:0]
.n000 (conv18_n000[7:0]), // output[7:0]
.n255 (conv18_n255[7:0])); // output[7:0]
csconvert_mono i_csconvert_mono (
.en (en_converters[CMPRS_MONO16]),
.clk (xclk),
.din (mb_din[7:0]),
.pre_first_in (pre_first_in),
.y_out (mono16_signed_y[7:0]),
.yaddr (mono16_yaddrw[7:0]),
.ywe (mono16_ywe),
.pre_first_out(mono16_pre_first_out));
csconvert_jp4 i_csconvert_jp4 (
.en (en_converters[CMPRS_JP4]),
.clk (xclk),
.din (mb_din[7:0]),
.pre_first_in (pre_first_in),
.y_out (jp4_signed_y[7:0]),
.yaddr (jp4_yaddrw[7:0]),
.ywe (jp4_ywe),
.pre_first_out (jp4_pre_first_out));
csconvert_jp4diff i_csconvert_jp4diff (
.en (en_converters[CMPRS_JP4DIFF]),
.clk (xclk),
.scale_diff (scale_diff_r),
.hdr (hdr_r),
.din (mb_din[7:0]),
.pre_first_in (pre_first_in),
.y_out (jp4diff_signed_y[8:0]),
.yaddr (jp4diff_yaddrw[7:0]),
.ywe (jp4diff_ywe),
.pre_first_out (jp4diff_pre_first_out),
.bayer_phase (bayer_phase_r[1:0]));
//TODO: temporary plugs, until module for 20x20 is created
// will be wrong, of course
assign conv20_signed_y[7:0]= conv18_signed_y[7:0];
assign conv20_yaddrw[7:0]= conv18_yaddrw[7:0];
assign conv20_ywe= conv18_ywe;
assign conv20_signed_c[8:0]= conv18_signed_c[8:0];
assign conv20_caddrw[6:0]= conv18_caddrw[6:0];
assign conv20_cwe= conv18_cwe;
assign conv20_pre_first_out= conv18_pre_first_out;
// TODO: temporary assign N000 and N255 for other (not csconvert18) modes until they are implemented in those modules
assign conv20_n000= conv18_n000;
assign mono16_n000= conv18_n000;
assign jp4_n000= conv18_n000;
assign jp4diff_n000= conv18_n000;
assign conv20_n255= conv18_n255;
assign mono16_n255= conv18_n255;
assign jp4_n255= conv18_n255;
assign jp4diff_n255= conv18_n255;
// multiplex outputs
// average for each block should be calculated before the data goes to output output
always @ (posedge xclk) case (converter_type_r[2:0])
CMPRS_COLOR18:begin //color 18
pre_first_out <= conv18_pre_first_out;
signed_y[8:0] <= {conv18_signed_y[7],conv18_signed_y[7:0]};
ywe <= conv18_ywe;
yaddrw[7:0] <= {conv18_yaddrw[7],conv18_yaddrw[3],conv18_yaddrw[6:4],conv18_yaddrw[2:0]};
signed_c[8:0] <= {conv18_signed_c[8:0]};
cwe <= conv18_cwe;
caddrw[7:0] <= {1'b0,conv18_caddrw[6:0]};
n000 <= conv18_n000;
n255 <= conv18_n255;
// pre_color_enable <= 1'b1;
// ccv_out_start <= (conv18_yaddrw[7:0]==8'hc5); //TODO: adjust to minimal latency?
end
CMPRS_COLOR20:begin //color 20
pre_first_out <= conv20_pre_first_out;
signed_y[8:0] <= {conv20_signed_y[7],conv20_signed_y[7:0]};
ywe <= conv20_ywe;
yaddrw[7:0] <= {conv20_yaddrw[7],conv20_yaddrw[3],conv20_yaddrw[6:4],conv20_yaddrw[2:0]};
signed_c[8:0] <= {conv20_signed_c[8:0]};
cwe <= conv20_cwe;
caddrw[7:0] <= {1'b0,conv20_caddrw[6:0]};
n000 <= conv20_n000;
n255 <= conv20_n255;
// pre_color_enable <= 1'b1;
// ccv_out_start <= (conv20_yaddrw[7:0]==8'hc5); //TODO: adjust to minimal latency?
end
CMPRS_MONO16:begin //mono
pre_first_out <= mono16_pre_first_out;
signed_y[8:0] <= {mono16_signed_y[7],mono16_signed_y[7:0]};
ywe <= mono16_ywe;
yaddrw[7:0] <= {mono16_yaddrw[7],mono16_yaddrw[3],mono16_yaddrw[6:4],mono16_yaddrw[2:0]};
signed_c[8:0] <= 9'h0;
cwe <= 1'b0;
caddrw[7:0] <= 8'h0;
n000 <= mono16_n000;
n255 <= mono16_n255;
// pre_color_enable <= 1'b0;
// ccv_out_start <= accYdone[0];
end
CMPRS_JP4:begin // jp4
pre_first_out <= jp4_pre_first_out;
signed_y[8:0] <= {jp4_signed_y[7],jp4_signed_y[7:0]};
ywe <= jp4_ywe;
yaddrw[7:0] <= {jp4_yaddrw[7],jp4_yaddrw[3],jp4_yaddrw[6:4],jp4_yaddrw[2:0]};
signed_c[8:0] <= 9'h0;
cwe <= 1'b0;
caddrw[7:0] <= 8'h0;
n000 <= jp4_n000;
n255 <= jp4_n255;
// pre_color_enable <= 1'b0;
// ccv_out_start <= accYdone[0];
end
CMPRS_JP4DIFF:begin //jp4diff
pre_first_out <= jp4diff_pre_first_out;
signed_y[8:0] <= {jp4diff_signed_y[8:0]};
ywe <= jp4diff_ywe;
yaddrw[7:0] <= {jp4diff_yaddrw[7],jp4diff_yaddrw[3],jp4diff_yaddrw[6:4],jp4diff_yaddrw[2:0]};
signed_c[8:0] <= 9'h0;
cwe <= 1'b0;
caddrw[7:0] <= 8'h0;
n000 <= jp4diff_n000;
n255 <= jp4diff_n255;
// pre_color_enable <= 1'b0;
// ccv_out_start <= accYdone[0];
end
endcase
endmodule
......@@ -286,14 +286,14 @@ module csconvert18a(
// SRL16 i_nxtline(.Q(nxtline),.D(!RST && ywe_r && (yaddr_r[3:0]==4'hf) && (yaddr_r[7:4]!=4'hf)), .CLK(CLK), .A0(1'b1), .A1(1'b0), .A2(1'b0), .A3(1'b0)); // dly=1+1
always @ (posedge CLK) begin
ywe_r <= !RST && (ystrt || nxtline || (ywe_r && (yaddr_r[3:0]!=4'hf)));
yaddr_r[7:4] <= (RST || strt)? 4'h0: (nxtline?(yaddr_r[7:4]+1):yaddr_r[7:4]);
yaddr_r[3:0] <= ywe_r? (yaddr_r[3:0]+1):4'h0;
odd_pix <= RST || strt || ~odd_pix;
if (RST || strt) odd_line <= 1'b0;
else if (yaddr_r[3:0]==4'hd) odd_line <= ~odd_line;
if (RST || strt) pix_green <=bayer_phase[1]^bayer_phase[0];
else pix_green <=~(yaddr_r[3:0]==4'hd)^pix_green;
ywe_r <= !RST && (ystrt || nxtline || (ywe_r && (yaddr_r[3:0]!=4'hf)));
yaddr_r[7:4] <= (RST || strt)? 4'h0: (nxtline?(yaddr_r[7:4]+1):yaddr_r[7:4]);
yaddr_r[3:0] <= ywe_r? (yaddr_r[3:0]+1):4'h0;
odd_pix <= RST || strt || ~odd_pix;
if (RST || strt) odd_line <= 1'b0;
else if (yaddr_r[3:0]==4'hd) odd_line <= ~odd_line;
if (RST || strt) pix_green <=bayer_phase[1]^bayer_phase[0];
else pix_green <=~(yaddr_r[3:0]==4'hd)^pix_green;
end
// First block generates 2 8-bit values (latency=3)- pixel (p2) and average value of previous and next pixel in the same
......
......@@ -57,14 +57,27 @@ module jp_channel#(
wire [ 4:0] left_marg; // left margin (for not-yet-implemented) mono JPEG (8 lines tile row) can need 7 bits (mod 32 - tile)
wire [12:0] n_blocks_in_row_m1; // number of macroblocks in a macroblock row minus 1
wire [12: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 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
wire [ 2:0] converter_type; // 0 - color18, 1 - color20, 2 - mono, 3 - jp4, 4 - jp4-diff, 7 - mono8 (not yet implemented)
wire scale_diff; // divide differences by 2 (to fit in 8-bit range)
wire hdr; // second green absolute, not difference
wire subtract_dc_in; // subtract/restore DC components
wire [ 9:0] m_cb; // [9:0] scale for CB - default 0.564 (10'h90)
wire [ 9:0] m_cr; // [9:0] scale for CB - default 0.713 (10'hb6)
wire [ 2:0] converter_type; // 0 - color18, 1 - color20, 2 - mono, 3 - jp4, 4 - jp4-diff, 7 - mono8 (not yet implemented)
//TODO: assign next 5 values from converter_type[2:0]
reg [ 5:0] mb_w_m1; // macroblock width minus 1 // 3 LSB not used, SHOULD BE SET to 3'b111
reg [ 5:0] mb_h_m1; // macroblock horizontal period (8/16) // 3 LSB not used SHOULD BE SET to 3'b111
reg [ 4:0] mb_hper; // macroblock horizontal period (8/16) // 3 LSB not used TODO: assign from converter_type[2:0]
reg [ 1:0] tile_width; // memory tile width (can be 128 for monochrome JPEG) Can be 32/64/128: 0 - 16, 1 - 32, 2 - 64, 3 - 128
reg tile_col_width; // 0 - 16 pixels, 1 -32 pixels
wire [ 5:0] mb_w_m1; // macroblock width minus 1 // 3 LSB not used, SHOULD BE SET to 3'b111
wire [ 5:0] mb_h_m1; // macroblock horizontal period (8/16) // 3 LSB not used SHOULD BE SET to 3'b111
wire [ 4:0] mb_hper; // macroblock horizontal period (8/16) // 3 LSB not used TODO: assign from converter_type[2:0]
wire [ 1:0] tile_width; // memory tile width (can be 128 for monochrome JPEG) Can be 32/64/128: 0 - 16, 1 - 32, 2 - 64, 3 - 128
wire tile_col_width; // 0 - 16 pixels, 1 -32 pixels
// signals connecting modules: cmprs_macroblock_buf_iface_i and cmprs_pixel_buf_iface_i:
......@@ -73,7 +86,12 @@ module jp_channel#(
// controller this can just be the same as mb_pre_end_in
wire mb_pre_start; // 1 clock cycle before stream of addresses to the buffer
wire [ 1:0] start_page; // page to read next tile from (or first of several pages)
wire [ 6:0] macroblock_x; // macroblock left pixel x relative to a tile (page) Maximal page - 128 bytes wide
wire [ 6:0] macroblock_x; // macroblock left pixel x relative to a tile (page) Maximal page - 128 bytes wide
// signals connecting modules: cmprs_macroblock_buf_iface_i and cmprs_buf_average:
wire first_mb; // output reg
wire last_mb; // output
// signals connecting modules: cmprs_pixel_buf_iface_i and chn_rd_buf_i:
wire [ 7:0] buf_di; // data from the buffer
......@@ -86,61 +104,60 @@ module jp_channel#(
wire mb_pre_first_out; // Macroblock data out strobe - 1 cycle just before data valid
wire mb_data_valid; // Macroblock data out valid
// set derived parameters from converter_type
wire limit_diff = 1'b1; // as in the prototype - just a constant 1
// signals connecting modules: csconvert and cmprs_buf_average:
wire [8:0] signed_y; // was y_in
wire [8:0] signed_c; // was c_in
wire [7:0] yaddrw;
wire ywe;
wire [7:0] caddrw;
wire cwe;
wire yc_pre_first_out; // pre first output from color converter (was pre_first_out) - last cycle of writing (may inc wpage
// How they are used? Can it be average instead?
wire [7:0] n000; // number of all 0 in macroblock (255 for 256), valid only for color JPEG
wire [7:0] n255; // number of all 255 in macroblock (255 for 256), valid only for color JPEG
// signals connecting modules: cmprs_buf_average and ???:
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_ds; // single-cycle mark of the first_r pixel in a 64 (8x8) - pixel block
wire [ 2:0] yc_nodc_tn; // [2:0] tile number 0..3 - Y, 4 - Cb, 5 - Cr (valid with start)
wire yc_nodc_first; // sending first_r MCU (valid @ ds)
wire yc_nodc_last; // sending last_r MCU (valid @ ds)
// below signals valid at ds ( 1 later than tn, first_r, last_r)
wire [2:0] yc_nodc_component_num; //[2:0] - component number (YCbCr: 0 - Y, 1 - Cb, 2 - Cr, JP4: 0-1-2-3 in sequence (depends on shift) 4 - don't use
wire yc_nodc_component_color; // use color quantization table (YCbCR, jp4diff)
wire yc_nodc_component_first; // first_r this component in a frame (DC absolute, otherwise - difference to previous)
wire yc_nodc_component_lastinmb; // last_r component in a macroblock;
// set derived parameters from converter_type
// wire [ 2:0] converter_type; // 0 - color18, 1 - color20, 2 - mono, 3 - jp4, 4 - jp4-diff, 7 - mono8 (not yet implemented)
always @(converter_type) begin
case (converter_type)
CMPRS_COLOR18: begin
mb_w_m1 <= 17; // macroblock width minus 1 // 3 LSB not used, SHOULD BE SET to 3'b111
mb_h_m1 <= 17; // macroblock horizontal period (8/16) // 3 LSB not used SHOULD BE SET to 3'b111
mb_hper <= 16; // macroblock horizontal period (8/16) // 3 LSB not used TODO: assign from converter_type[2:0]
tile_width <= 1; // memory tile width (can be 128 for monochrome JPEG) Can be 32/64/128: 0 - 16, 1 - 32, 2 - 64, 3 - 128
tile_col_width <= 1; // 0 - 16 pixels, 1 -32 pixels
end
CMPRS_COLOR20: begin
mb_w_m1 <= 19; // macroblock width minus 1 // 3 LSB not used, SHOULD BE SET to 3'b111
mb_h_m1 <= 19; // macroblock horizontal period (8/16) // 3 LSB not used SHOULD BE SET to 3'b111
mb_hper <= 16; // macroblock horizontal period (8/16) // 3 LSB not used TODO: assign from converter_type[2:0]
tile_width <= 1; // memory tile width (can be 128 for monochrome JPEG) Can be 32/64/128: 0 - 16, 1 - 32, 2 - 64, 3 - 128
tile_col_width <= 1; // 0 - 16 pixels, 1 -32 pixels
end
CMPRS_MONO16: begin
mb_w_m1 <= 15; // macroblock width minus 1 // 3 LSB not used, SHOULD BE SET to 3'b111
mb_h_m1 <= 15; // macroblock horizontal period (8/16) // 3 LSB not used SHOULD BE SET to 3'b111
mb_hper <= 16; // macroblock horizontal period (8/16) // 3 LSB not used TODO: assign from converter_type[2:0]
tile_width <= 2; // memory tile width (can be 128 for monochrome JPEG) Can be 32/64/128: 0 - 16, 1 - 32, 2 - 64, 3 - 128
tile_col_width <= 1; // 0 - 16 pixels, 1 -32 pixels
end
CMPRS_JP4: begin
mb_w_m1 <= 15; // macroblock width minus 1 // 3 LSB not used, SHOULD BE SET to 3'b111
mb_h_m1 <= 15; // macroblock horizontal period (8/16) // 3 LSB not used SHOULD BE SET to 3'b111
mb_hper <= 16; // macroblock horizontal period (8/16) // 3 LSB not used TODO: assign from converter_type[2:0]
tile_width <= 2; // memory tile width (can be 128 for monochrome JPEG) Can be 32/64/128: 0 - 16, 1 - 32, 2 - 64, 3 - 128
tile_col_width <= 1; // 0 - 16 pixels, 1 -32 pixels
end
CMPRS_JP4DIFF: begin
mb_w_m1 <= 15; // macroblock width minus 1 // 3 LSB not used, SHOULD BE SET to 3'b111
mb_h_m1 <= 15; // macroblock horizontal period (8/16) // 3 LSB not used SHOULD BE SET to 3'b111
mb_hper <= 16; // macroblock horizontal period (8/16) // 3 LSB not used TODO: assign from converter_type[2:0]
tile_width <= 2; // memory tile width (can be 128 for monochrome JPEG) Can be 32/64/128: 0 - 16, 1 - 32, 2 - 64, 3 - 128
tile_col_width <= 1; // 0 - 16 pixels, 1 -32 pixels
end
CMPRS_MONO8: begin
mb_w_m1 <= 7; // macroblock width minus 1 // 3 LSB not used, SHOULD BE SET to 3'b111
mb_h_m1 <= 7; // macroblock horizontal period (8/16) // 3 LSB not used SHOULD BE SET to 3'b111
mb_hper <= 8; // macroblock horizontal period (8/16) // 3 LSB not used TODO: assign from converter_type[2:0]
tile_width <= 3; // memory tile width (can be 128 for monochrome JPEG) Can be 32/64/128: 0 - 16, 1 - 32, 2 - 64, 3 - 128
tile_col_width <= 1; // 0 - 16 pixels, 1 -32 pixels
end
default: begin
mb_w_m1 <= 'bx; // macroblock width minus 1 // 3 LSB not used, SHOULD BE SET to 3'b111
mb_h_m1 <= 'bx; // macroblock horizontal period (8/16) // 3 LSB not used SHOULD BE SET to 3'b111
mb_hper <= 'bx; // macroblock horizontal period (8/16) // 3 LSB not used TODO: assign from converter_type[2:0]
tile_width <= 'bx; // memory tile width (can be 128 for monochrome JPEG) Can be 32/64/128: 0 - 16, 1 - 32, 2 - 64, 3 - 128
tile_col_width <= 'bx; // 0 - 16 pixels, 1 -32 pixels
end
endcase
end
cmprs_tile_mode_decode #( // fully combinatorial
.CMPRS_COLOR18(0),
.CMPRS_COLOR20(1),
.CMPRS_MONO16(2),
.CMPRS_JP4(3),
.CMPRS_JP4DIFF(4),
.CMPRS_MONO8(7)
) cmprs_tile_mode_decode_i (
.converter_type (converter_type), // input[2:0]
.mb_w_m1 (mb_w_m1), // output[5:0] reg
.mb_h_m1 (mb_h_m1), // output[5:0] reg
.mb_hper (mb_hper), // output[4:0] reg
.tile_width (tile_width), // output[1:0] reg
.tile_col_width (tile_col_width) // output reg
);
//mb_pre_first_out
// Port buffer - TODO: Move to memory controller
mcntrl_buf_rd #(
.LOG2WIDTH_RD(3) // 64 bit external interface
......@@ -178,7 +195,10 @@ module jp_channel#(
.mb_release_buf (mb_release_buf), // input
.mb_pre_start_out (mb_pre_start), // output
.start_page (start_page), // output[1:0]
.macroblock_x (macroblock_x) // output[6:0]
.macroblock_x (macroblock_x), // output[6:0]
.first_mb (first_mb), // output reg
.last_mb (last_mb) // output
);
cmprs_pixel_buf_iface #(
......@@ -209,14 +229,79 @@ module jp_channel#(
.start_page (start_page), // input[1:0]
.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
.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
);
/*
*/
csconvert #(
.CMPRS_COLOR18 (CMPRS_COLOR18),
.CMPRS_COLOR20 (CMPRS_COLOR20),
.CMPRS_MONO16 (CMPRS_MONO16),
.CMPRS_JP4 (CMPRS_JP4),
.CMPRS_JP4DIFF (CMPRS_JP4DIFF),
.CMPRS_MONO8 (CMPRS_MONO8)
) csconvert_i (
.xclk (xclk), // input
.frame_en (frame_en), // input
.converter_type (converter_type), // input[2:0]
.ignore_color (ignore_color), // input
.scale_diff (scale_diff), // input
.hdr (hdr), // input
.limit_diff (limit_diff), // input
.m_cb (m_cb), // input[9:0]
.m_cr (m_cr), // input[9:0]
.mb_din (mb_data_out), // input[7:0]
.bayer_phase (bayer_phase), // input[1:0]
.pre_first_in (mb_pre_first_out), // input
.signed_y (signed_y), // output[8:0] reg
.signed_c (signed_c), // output[8:0] reg
.yaddrw (yaddrw), // output[7:0] reg
.ywe (ywe), // output reg
.caddrw (caddrw), // output[7:0] reg
.cwe (cwe), // output reg
.pre_first_out (yc_pre_first_out), // output reg
.n000 (n000), // output[7:0] reg
.n255 (n255) // output[7:0] reg
);
cmprs_buf_average #(
.CMPRS_COLOR18 (CMPRS_COLOR18),
.CMPRS_COLOR20 (CMPRS_COLOR20),
.CMPRS_MONO16 (CMPRS_MONO16),
.CMPRS_JP4 (CMPRS_JP4),
.CMPRS_JP4DIFF (CMPRS_JP4DIFF),
.CMPRS_MONO8 (CMPRS_MONO8)
) cmprs_buf_average_i (
.xclk (xclk), // input
.frame_en (frame_en), // input
.converter_type (converter_type), // input[2:0]
.pre_first_in (mb_pre_first_out), // input
.yc_pre_first_out (yc_pre_first_out), // input
.bayer_phase (bayer_phase), // input[1:0]
.jp4_dc_improved (jp4_dc_improved), // input
.hdr (hdr), // input
.subtract_dc_in (subtract_dc_in), // input
.first_mb_in (first_mb), // input - calculate in cmprs_macroblock_buf_iface
.last_mb_in (last_mb), // input - calculate in cmprs_macroblock_buf_iface
.yaddrw (yaddrw), // input[7:0]
.ywe (ywe), // input
.signed_y (signed_y), // input[8:0]
.caddrw (caddrw), // input[7:0]
.cwe (cwe), // input
.signed_c (signed_c), // input[8:0]
.do (yc_nodc), // output[9:0]
.avr (yc_avr), // output[8:0]
.dv (yc_nodc_dv), // output
.ds (yc_nodc_ds), // output
.tn (yc_nodc_tn), // output[2:0]
.first (yc_nodc_first), // output reg
.last (yc_nodc_last), // output reg
.component_num (yc_nodc_component_num), // output[2:0]
.component_color (yc_nodc_component_color), // output
.component_first (yc_nodc_component_first), // output
.component_lastinmb (yc_nodc_component_lastinmb) // output reg
);
endmodule
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