⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 color_proc333.v

📁 基于fpga的MJPEG编码,用硬件描述语言vlogic写的
💻 V
📖 第 1 页 / 共 3 页
字号:
  always @ (posedge RST or posedge CLK) if (RST) pd0 <= 8'b0; else pd0 <= p1[7:0]; // generates more effective than with 2-bit SRs (line above)
  assign	ppa[8:0]={1'b0,pd0}+{1'b0,p0};
  always @ (posedge CLK) pa0 <=ppa[8:1];  //loosing 1 bit here!
// next - 2 pairs of 8 bit wide 16-bit long serial-in, serial out shift registers. Verify implementation - Should use 32 LUTs
// update 06/10/2004 - make an output pd_c[7:0] 2 cycles after pd_1[7:0] for color processing without additional resources
  reg [17:0] pd_10,pd_11,pd_12,pd_13,pd_14,pd_15,pd_16,pd_17;
//  reg [17:0] pd_20,pd_21,pd_22,pd_23,pd_24,pd_25,pd_26,pd_27;
  reg  [7:0] pd1_dly;
  reg  [7:0] pdc;
  reg [15:0] pd_20,pd_21,pd_22,pd_23,pd_24,pd_25,pd_26,pd_27;
  reg [17:0] pa_10,pa_11,pa_12,pa_13,pa_14,pa_15,pa_16,pa_17;
  reg [17:0] pa_20,pa_21,pa_22,pa_23,pa_24,pa_25,pa_26,pa_27;

  wire [7:0] pd1;
  wire [7:0] pd2;
  wire [7:0] pa1;
  wire [7:0] pa2;

   assign pd1={pd_17[17],pd_16[17],pd_15[17],pd_14[17],pd_13[17],pd_12[17],pd_11[17],pd_10[17]};
   assign pd2={pd_27[15],pd_26[15],pd_25[15],pd_24[15],pd_23[15],pd_22[15],pd_21[15],pd_20[15]};
   assign pa1={pa_17[17],pa_16[17],pa_15[17],pa_14[17],pa_13[17],pa_12[17],pa_11[17],pa_10[17]};
   assign pa2={pa_27[17],pa_26[17],pa_25[17],pa_24[17],pa_23[17],pa_22[17],pa_21[17],pa_20[17]};


  always @ (posedge CLK) pd_10 <= {pd_10[16:0],pd0[0]};
  always @ (posedge CLK) pd_11 <= {pd_11[16:0],pd0[1]};
  always @ (posedge CLK) pd_12 <= {pd_12[16:0],pd0[2]};
  always @ (posedge CLK) pd_13 <= {pd_13[16:0],pd0[3]};
  always @ (posedge CLK) pd_14 <= {pd_14[16:0],pd0[4]};
  always @ (posedge CLK) pd_15 <= {pd_15[16:0],pd0[5]};
  always @ (posedge CLK) pd_16 <= {pd_16[16:0],pd0[6]};
  always @ (posedge CLK) pd_17 <= {pd_17[16:0],pd0[7]};

  always @ (posedge CLK) pd1_dly[7:0] <= pd1[7:0];
  always @ (posedge CLK) pdc[7:0]     <= pd1_dly[7:0];
  always @ (posedge CLK) pd_20 <= {pd_20[14:0],pdc[0]};
  always @ (posedge CLK) pd_21 <= {pd_21[14:0],pdc[1]};
  always @ (posedge CLK) pd_22 <= {pd_22[14:0],pdc[2]};
  always @ (posedge CLK) pd_23 <= {pd_23[14:0],pdc[3]};
  always @ (posedge CLK) pd_24 <= {pd_24[14:0],pdc[4]};
  always @ (posedge CLK) pd_25 <= {pd_25[14:0],pdc[5]};
  always @ (posedge CLK) pd_26 <= {pd_26[14:0],pdc[6]};
  always @ (posedge CLK) pd_27 <= {pd_27[14:0],pdc[7]};

  always @ (posedge CLK) pa_10 <= {pa_10[16:0],pa0[0]};
  always @ (posedge CLK) pa_11 <= {pa_11[16:0],pa0[1]};
  always @ (posedge CLK) pa_12 <= {pa_12[16:0],pa0[2]};
  always @ (posedge CLK) pa_13 <= {pa_13[16:0],pa0[3]};
  always @ (posedge CLK) pa_14 <= {pa_14[16:0],pa0[4]};
  always @ (posedge CLK) pa_15 <= {pa_15[16:0],pa0[5]};
  always @ (posedge CLK) pa_16 <= {pa_16[16:0],pa0[6]};
  always @ (posedge CLK) pa_17 <= {pa_17[16:0],pa0[7]};

  always @ (posedge CLK) pa_20 <= {pa_20[16:0],pa_10[17]};
  always @ (posedge CLK) pa_21 <= {pa_21[16:0],pa_11[17]};
  always @ (posedge CLK) pa_22 <= {pa_22[16:0],pa_12[17]};
  always @ (posedge CLK) pa_23 <= {pa_23[16:0],pa_13[17]};
  always @ (posedge CLK) pa_24 <= {pa_24[16:0],pa_14[17]};
  always @ (posedge CLK) pa_25 <= {pa_25[16:0],pa_15[17]};
  always @ (posedge CLK) pa_26 <= {pa_26[16:0],pa_16[17]};
  always @ (posedge CLK) pa_27 <= {pa_27[16:0],pa_17[17]};
  
  
  wire [7:0] pd_prev= pd2[7:0];
  wire [7:0] pd_next= pd0[7:0];
  wire [7:0] pa_prev= pa2[7:0];
  wire [7:0] pa_next= pa0[7:0];

// now the result Y calculation depends on the pixel position (bx,by). It consists of 3 terms, each with different coefficient.
// first term always includes pd1[7:0]
// if (bx[1]==by[1]) // 00 or 11
// second term is pa1, third - (pd0+pd2)/2
// else
// second term is (pa1 + (pd0+pd2)/2)/2, third - (pa0+pa2)/2
  reg		[7:0] m1;
  reg		[7:0] m2;
  reg		[7:0] m3;
  wire	[8:0]	pd02s=   {1'b0,pd_prev[7:0]}+{1'b0,pd_next[7:0]};   // will use pd02s[8:1]
  wire	[8:0]	pa1pd02s={1'b0,pa1[7:0]}+{1'b0,pd02s[8:1]}; // will use pa1pd02s[8:1]
  wire	[8:0]	pa02s=   {1'b0,pa_prev[7:0]}+{1'b0,pa_next[7:0]};   // will use pa02s[8:1]
  always @ (posedge CLK) m1 <= pd1[7:0];
//  always @ (posedge CLK) m2 <= (odd_pix==odd_line)? pa1[7:0]   : pa1pd02s[8:1];
//  always @ (posedge CLK) m3 <= (odd_pix==odd_line)? pd02s[8:1] : pa02s[8:1];
  always @ (posedge CLK) m2 <= pix_green? pa1[7:0]   : pa1pd02s[8:1];
  always @ (posedge CLK) m3 <= pix_green? pd02s[8:1] : pa02s[8:1];
/*
Y[0,0]=(0x96*P[0,0]+   0x4d*((P[0,-1]+P[0,1])/2) +               0x1d*((P[-1,0]+P[1,0])/2))>>8
Y[0,1]=(0x4d*P[0,1]+   0x96*((P[-1,1]+P[0,0]+P[0,2]+P[1,1])/4)+  0x1d*((P[-1,0]+P[-1,2]+P[1,0]+P[1,2])/4))>>8
Y[1,0]=(0x1d*P[1,0]+   0x96*((P[0,0]+P[1,-1]+P[1,1]+P[2,0])/4)+  0x4d*((P[0,-1]+P[0,1]+P[2,-1]+P[2,1])/4))>>8
Y[1,1]=(0x96*P[1,1]+   0x1d*((P[1,0]+P[1,2])/2 +                 0x4d*((P[0,1] +P[2,1])/2)))>>8
+-----+--------+-------+-------+-------+-------+-------+
|     |  (0)   |       |       |   *   |   *   | *   * |
|     |  G R   |   *   | * + * |   +   | * + * |   +   |
|     |  B G   |       |       |   *   |   *   | *   * |
+-----+--------+-------+-------+-------+-------+-------+
|  0  | P[0,0] |  0x96 |  0x4d |  0x1d |       |       |
|     +--------+-------+-------+-------+-------+-------+
| G R | P[0,1] |  0x4d |       |       |  0x96 |  0x1d |
|     +--------+-------+-------+-------+-------+-------+
| B G | P[1,0] |  0x1d |       |       |  0x96 |  0x4d |
|     +--------+-------+-------+-------+-------+-------+
|     | P[1,1] |  0x96 |  0x1d |  0x4d |       |       |
+-----+--------+-------+-------+-------+-------+-------+
|  1  | P[0,0] |  0x4d |       |       |  0x96 |  0x1d |
|     +--------+-------+-------+-------+-------+-------+
| R G | P[0,1] |  0x96 |  0x4d |  0x1d |       |       |
|     +--------+-------+-------+-------+-------+-------+
| G B | P[1,0] |  0x96 |  0x1d |  0x4d |       |       |
|     +--------+-------+-------+-------+-------+-------+
|     | P[1,1] |  0x1d |       |       |  0x96 |  0x4d |
+-----+--------+-------+-------+-------+-------+-------+
|  2  | P[0,0] |  0x1d |       |       |  0x96 |  0x4d |
|     +--------+-------+-------+-------+-------+-------+
| B G | P[0,1] |  0x96 |  0x1d |  0x4d |       |       |
|     +--------+-------+-------+-------+-------+-------+
| G R | P[1,0] |  0x96 |  0x4d |  0x1d |       |       |
|     +--------+-------+-------+-------+-------+-------+
|     | P[1,1] |  0x4d |       |       |  0x96 |  0x1d |
+-----+--------+-------+-------+-------+-------+-------+
|  3  | P[0,0] |  0x96 |  0x1d |  0x4d |       |       |
|     +--------+-------+-------+-------+-------+-------+
| G B | P[0,1] |  0x1d |       |       |  0x96 |  0x4d |
|     +--------+-------+-------+-------+-------+-------+
| R G | P[1,0] |  0x4d |       |       |  0x96 |  0x1d |
|     +--------+-------+-------+-------+-------+-------+
|     | P[1,1] |  0x96 |  0x4d |  0x1d |       |       |
+-----+--------+-------+-------+-------+-------+-------+


*/
  reg [7:0] k1;
  reg [7:0] k2;
  reg [7:0] k3;
  always @ (posedge CLK) case ({bayer_phase[1:0],odd_line,odd_pix})
// 0 - GR/BG
    4'b0000: begin
               k1<=8'h96;
               k2<=8'h4d;
               k3<=8'h1d;
             end
    4'b0001: begin
               k1<=8'h4d;
               k2<=8'h96;
               k3<=8'h1d;
             end
    4'b0010: begin
               k1<=8'h1d;
               k2<=8'h96;
               k3<=8'h4d;
             end
    4'b0011: begin
               k1<=8'h96;
               k2<=8'h1d;
               k3<=8'h4d;
             end
// 1 - RG/GB
    4'b0100: begin
               k1<=8'h4d;
               k2<=8'h96;
               k3<=8'h1d;
             end
    4'b0101: begin
               k1<=8'h96;
               k2<=8'h4d;
               k3<=8'h1d;
             end
    4'b0110: begin
               k1<=8'h96;
               k2<=8'h1d;
               k3<=8'h4d;
             end
    4'b0111: begin
               k1<=8'h1d;
               k2<=8'h96;
               k3<=8'h4d;
             end
// 2 - BG/GR
    4'b1000: begin
               k1<=8'h1d;
               k2<=8'h96;
               k3<=8'h4d;
             end
    4'b1001: begin
               k1<=8'h96;
               k2<=8'h1d;
               k3<=8'h4d;
             end
    4'b1010: begin
               k1<=8'h96;
               k2<=8'h4d;
               k3<=8'h1d;
             end
    4'b1011: begin
               k1<=8'h4d;
               k2<=8'h96;
               k3<=8'h1d;
             end
// 3 - GB/RG
    4'b1100: begin
               k1<=8'h96;
               k2<=8'h1d;
               k3<=8'h4d;
             end
    4'b1101: begin
               k1<=8'h1d;
               k2<=8'h96;
               k3<=8'h4d;
             end
    4'b1110: begin
               k1<=8'h4d;
               k2<=8'h96;
               k3<=8'h1d;
             end
    4'b1111: begin
               k1<=8'h96;
               k2<=8'h4d;
               k3<=8'h1d;
             end
  endcase

  wire [15:0] mm1=m1[7:0]*k1[7:0];
  wire [15:0] mm2=m2[7:0]*k2[7:0];
  wire [15:0] mm3=m3[7:0]*k3[7:0];

  reg   [7:0] y;
  reg   [7:0] y0;	// bypass in monochrome mode
//  wire   [7:0] y0;	// bypass in monochrome mode
  reg   [15:0] y1,y2,y3; 
  wire	[15:0] y_sum =y1+y2+y3;
  always @ (posedge CLK) y0 <= m1;
  always @ (posedge CLK) y1 <= mm1;
  always @ (posedge CLK) y2 <= mm2;
  always @ (posedge CLK) y3 <= mm3;
  always @ (posedge CLK) y[7:0] <= mono ? y0 : (y_sum[15:8]+y_sum[7]);


// Try easier and hope better algorithm of color extractions that should perform better on gradients.
// It will rely on the fact that Y is already calculated, so instead of processing 4 pixels it will
// calculate Cb for "B" pixel, and Cr - for "R", subtracting calculated "Y" for that pixel.
//Cb = 0.564*(B-Y)+128
//Cr = 0.713*(R-Y)+128
// First - delay pd1[7:0] by 2 clock periods - to match "Y" output (one ahead, actually)
// It is better to implement it earlier - while calculating pd2 - anyway it had to be delayed by 18 (16+2) form pd1 - make it in 2 stages 2 +16
// pdc[7:0] - one cycle ahead of the "Y" for each pixel
// Try multiplication by constant without the register for that constant, just 2:1 mux. Still use aregister for the other operand (is it needed?)
reg   [7:0] cbcrmult1;
wire  [7:0] cbcrmult2; // 1 of 2 constants - should be valid during ywe and 1 more cycle ("use_cr"
wire [15:0] cbcrmulto; // output of 8x8 multiplier
reg   [8:0] cbcrmultr; // 1 extra bit for precision (before subtraction)
reg   [8:0] cbcr;      // after subraction (with extra bit preserved)
reg         sel_cbcrmult1; // 0 - use pdc[7:0], 1 - use y[7:0]. Should be valid 1 cycle ahead of ywe!
reg         use_cr;        // in this line cr is calculated. Valid during ywe and 1 cycle after
reg         sub_y;         // output accumulator/subtractor. 0 - load new data, 1 - subtract. Walid 2 cycles after ywe
wire        cwe0;          // preliminary cwe (to be modulated by odd/even pixels)
reg         cstrt;         //ystrt dealyed by 1
reg         cnxt;          // nxtline delayed by 1 
always @ (posedge CLK) begin
  if (~(ywe || ystrt || nxtline)) sel_cbcrmult1 <= ~(bayer_phase[1] ^ bayer_phase[0] ^ odd_line);
  else      sel_cbcrmult1 <= ~sel_cbcrmult1;
  sub_y <= ~sel_cbcrmult1;
  cbcrmult1 <= sel_cbcrmult1?y[7:0]:pdc[7:0];
  if (~ywe) use_cr <= ~(bayer_phase[1] ^ odd_line);
end
assign      cbcrmult2=use_cr?8'hb6:8'h90;  // maybe will need a register? (use_cr will still be good as it is valid early)
assign      cbcrmulto=cbcrmult1*cbcrmult2;
// will preserve extra bit, but do not need to add half of the truncated MSB - on average there will be no shift after subtraction
always @ (posedge CLK) begin
  cbcrmultr[8:0] <= cbcrmulto[15:7];
  cbcr[8:0] <= sub_y? (cbcr[8:0]-cbcrmultr[8:0]+ 1'b1):cbcrmultr[8:0];
end
  assign q[7:0]=	{~cbcr[8],cbcr[7:1]}; // -128, discarded extra bit (need truncating?)
SRL16 i_cwe0    (.D(ywe ),  .Q(cwe0), .A0(1'b1), .A1(1'b0), .A2(1'b0), .A3(1'b0), .CLK(CLK)); // dly=2=1+1
always @ (posedge CLK) begin
      cstrt <= ystrt;
      cnxt  <= nxtline;
      cwe <= cwe0 && sub_y; 
      caddr[2:0]<= cwe0?(caddr[2:0]+cwe):3'b0;
      if (cstrt)     caddr[6:3] <={~bayer_phase[1],3'b0};
      else if (cnxt) caddr[6:3] <={~caddr[6],caddr[5:3]+(bayer_phase[1]^caddr[6])};
end
  always @ (posedge CLK) begin
    y_eq_0   <= (y0[7:0] == 8'h0);
    y_eq_255 <= (y0[7:0] == 8'hff);
    if (strt) n000[7:0] <= 8'h0;
    else if ((n000[7:0]!=8'hff) && y_eq_0 && ywe) n000[7:0] <= n000[7:0]+1;
    if (strt) n255[7:0] <= 8'h0;
    else if ((n255[7:0]!=8'hff) && y_eq_255 && ywe) n255[7:0] <= n255[7:0]+1;
  end


endmodule

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -