Last active
January 21, 2016 14:05
-
-
Save mkatsimpris/8826cc5c518fd3ccfd22 to your computer and use it in GitHub Desktop.
Simple rgb2ycbcr module in myHLD. Any comments and corrections are welcome!!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
constant C_Y_1 : signed(14 downto 0) := to_signed(4899, 15); | |
constant C_Y_2 : signed(14 downto 0) := to_signed(9617, 15); | |
constant C_Y_3 : signed(14 downto 0) := to_signed(1868, 15); | |
constant C_Cb_1 : signed(14 downto 0) := to_signed(-2764, 15); | |
constant C_Cb_2 : signed(14 downto 0) := to_signed(-5428, 15); | |
constant C_Cb_3 : signed(14 downto 0) := to_signed(8192, 15); | |
constant C_Cr_1 : signed(14 downto 0) := to_signed(8192, 15); | |
constant C_Cr_2 : signed(14 downto 0) := to_signed(-6860, 15); | |
constant C_Cr_3 : signed(14 downto 0) := to_signed(-1332, 15); | |
R_s <= signed('0' & fram1_q(7 downto 0)); | |
G_s <= signed('0' & fram1_q(15 downto 8)); | |
B_s <= signed('0' & fram1_q(23 downto 16)); | |
signal Y_reg_1 : signed(23 downto 0); | |
signal Y_reg_2 : signed(23 downto 0); | |
signal Y_reg_3 : signed(23 downto 0); | |
signal Cb_reg_1 : signed(23 downto 0); | |
signal Cb_reg_2 : signed(23 downto 0); | |
signal Cb_reg_3 : signed(23 downto 0); | |
signal Cr_reg_1 : signed(23 downto 0); | |
signal Cr_reg_2 : signed(23 downto 0); | |
signal Cr_reg_3 : signed(23 downto 0); | |
signal Y_reg : signed(23 downto 0); | |
signal Cb_reg : signed(23 downto 0); | |
signal Cr_reg : signed(23 downto 0); | |
signal R_s : signed(8 downto 0); | |
signal G_s : signed(8 downto 0); | |
signal B_s : signed(8 downto 0); | |
------------------------------------------------------------------- | |
-- RGB to YCbCr conversion | |
------------------------------------------------------------------- | |
p_rgb2ycbcr : process(CLK, RST) | |
begin | |
if RST = '1' then | |
Y_Reg_1 <= (others => '0'); | |
Y_Reg_2 <= (others => '0'); | |
Y_Reg_3 <= (others => '0'); | |
Cb_Reg_1 <= (others => '0'); | |
Cb_Reg_2 <= (others => '0'); | |
Cb_Reg_3 <= (others => '0'); | |
Cr_Reg_1 <= (others => '0'); | |
Cr_Reg_2 <= (others => '0'); | |
Cr_Reg_3 <= (others => '0'); | |
Y_Reg <= (others => '0'); | |
Cb_Reg <= (others => '0'); | |
Cr_Reg <= (others => '0'); | |
elsif CLK'event and CLK = '1' then | |
Y_Reg_1 <= R_s*C_Y_1; | |
Y_Reg_2 <= G_s*C_Y_2; | |
Y_Reg_3 <= B_s*C_Y_3; | |
Cb_Reg_1 <= R_s*C_Cb_1; | |
Cb_Reg_2 <= G_s*C_Cb_2; | |
Cb_Reg_3 <= B_s*C_Cb_3; | |
Cr_Reg_1 <= R_s*C_Cr_1; | |
Cr_Reg_2 <= G_s*C_Cr_ | |
Cr_Reg_3 <= B_s*C_Cr_3; | |
Y_Reg <= Y_Reg_1 + Y_Reg_2 + Y_Reg_3; | |
Cb_Reg <= Cb_Reg_1 + Cb_Reg_2 + Cb_Reg_3 + to_signed(128*16384,Cb_Reg'length); | |
Cr_Reg <= Cr_Reg_1 + Cr_Reg_2 + Cr_Reg_3 + to_signed(128*16384,Cr_Reg'length); | |
end if; | |
end process; | |
Y_8bit <= unsigned(Y_Reg(21 downto 14)); | |
Cb_8bit <= unsigned(Cb_Reg(21 downto 14)); | |
Cr_8bit <= unsigned(Cr_Reg(21 downto 14)); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/python | |
from myhdl import * | |
from commons import * | |
from math import * | |
from math import * | |
#Fixed point representation with 1 sign bit and 14 fractional bits | |
fract_bits = 14 | |
sign_bits=1 | |
Y_COEFF=[0.2999,0.587,0.114] | |
CB_COEFF=[-0.1687,-0.3313,0.5] | |
CR_COEFF=[0.5,-0.4187,-0.0813] | |
OFFSET=[0,128,128] | |
Y=[int(round(Y_COEFF[i]*(2**fract_bits )))for i in range(3)] | |
Cb=[int(round(CB_COEFF[i]*(2**fract_bits ))) for i in range(3)] | |
Cr=[int(round(CR_COEFF[i]*(2**fract_bits ))) for i in range(3)] | |
Offset=[int(round(OFFSET[i]*(2**fract_bits ))) for i in range(3)] | |
class RGB(object): | |
def __init__(self, nbits=8): | |
self.nbits=nbits | |
self.red = Signal(intbv(0)[nbits:]) | |
self.green = Signal(intbv(0)[nbits:]) | |
self.blue = Signal(intbv(0)[nbits:]) | |
def next(self, r, g, b): | |
self.red.next = r | |
self.green.next = g | |
self.blue.next = b | |
def bitLength(self): return self.nbits | |
class YCbCr(object): | |
def __init__(self, nbits=8): | |
self.nbits = nbits | |
self.y = Signal(intbv(0)[nbits:]) | |
self.cb = Signal(intbv(0)[nbits:]) | |
self.cr = Signal(intbv(0)[nbits:]) | |
def bitLength(self): return self.nbits | |
def rgb2ycbcr(ycbcr, enable_out, rgb, enable_in, clk, reset): | |
""" A RGB to YCbCr converter with reset. | |
I/O pins: | |
-------- | |
y : output 8-bit unsigned value in range of 0-127 | |
cb : output 8-bit unsigned value in range of 0-128 | |
cr : output 8-bit unsigned value in range of 0-128 | |
enable_out : output True when output is available | |
r : input 8-bit unsigned value in range of 0-255 | |
g : input 8-bit unsigned value in range of 0-255 | |
b : input 8-bit unsigned value in range of 0-255 | |
enable_in : input True when input is available | |
clk : input clock boolean signal | |
reset : input reset boolean signal | |
""" | |
#signals for y,cb,cr registers | |
Y_reg,Cb_reg,Cr_reg=[[Signal(intbv(0,-2**(23),2**(23)-1)) for _ in range(3)] for _ in range(3)] | |
Y_sum,Cb_sum,Cr_sum=[Signal(intbv(0,-2**(23),2**(23)-1)) for _ in range(3)] | |
#signals for signed input RGB | |
R_s,G_s,B_s=[Signal(intbv(0,-2**8,2**8-1)) for _ in range(3)] | |
#signals for coefficient signed conversion | |
Y1_s,Y2_s,Y3_s=[Signal(intbv(Y[i],-2**14,2**14-1)) for i in range(3)] | |
Cb1_s,Cb2_s,Cb3_s=[Signal(intbv(Cb[i],-2**14,2**14-1)) for i in range(3)] | |
Cr1_s,Cr2_s,Cr3_s=[Signal(intbv(Cr[i],-2**14,2**14-1)) for i in range(3)] | |
offset_y,offset_cb,offset_cr=[Signal(intbv(Offset[i],-2**23,2**23-1)) for i in range(3)] | |
@always_comb | |
def logic2(): | |
#input RGB signed conversion | |
R_s.next=rgb.red | |
G_s.next=rgb.green | |
B_s.next=rgb.blue | |
@always_seq(clk.posedge, reset=reset) | |
def logic(): | |
enable_out.next = INACTIVE_LOW | |
if enable_in == ACTIVE_HIGH: | |
Y_reg[0].next=R_s*Y1_s | |
Y_reg[1].next=G_s*Y2_s | |
Y_reg[2].next=B_s*Y3_s | |
Cb_reg[0].next=R_s*Cb1_s | |
Cb_reg[1].next=G_s*Cb2_s | |
Cb_reg[2].next=B_s*Cb3_s | |
Cr_reg[0].next=R_s*Cr1_s | |
Cr_reg[1].next=G_s*Cr2_s | |
Cr_reg[2].next=B_s*Cr3_s | |
Y_sum.next=Y_reg[0]+Y_reg[1]+Y_reg[2]+offset_y | |
Cb_sum.next=Cb_reg[0]+Cb_reg[1]+Cb_reg[2]+offset_cb | |
Cr_sum.next=Cr_reg[0]+Cr_reg[1]+Cr_reg[2]+offset_cr | |
#outputs y,cr,cb unsigned 8 MSB | |
ycbcr.y.next=Y_sum[22:14] | |
ycbcr.cb.next=Cb_sum[22:14] | |
ycbcr.cr.next=Cr_sum[22:14] | |
enable_out.next = ACTIVE_HIGH | |
return logic,logic2 | |
def convert(): | |
ycbcr = YCbCr() | |
rgb = RGB() | |
clk, enable_in, enable_out = [Signal(INACTIVE_LOW) for _ in range(3)] | |
reset = ResetSignal(1, active=ACTIVE_LOW, async=True) | |
toVHDL(rgb2ycbcr,ycbcr, enable_out, rgb, enable_in, clk, reset) | |
convert() | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- File: rgb2ycbcr.vhd | |
-- Generated by MyHDL 0.9.0 | |
-- Date: Thu Jan 21 14:21:38 2016 | |
library IEEE; | |
use IEEE.std_logic_1164.all; | |
use IEEE.numeric_std.all; | |
use std.textio.all; | |
use work.pck_myhdl_090.all; | |
entity rgb2ycbcr is | |
port ( | |
enable_out: out std_logic; | |
enable_in: in std_logic; | |
clk: in std_logic; | |
reset: in std_logic; | |
ycbcr_y: out unsigned(7 downto 0); | |
ycbcr_cb: out unsigned(7 downto 0); | |
ycbcr_cr: out unsigned(7 downto 0); | |
rgb_blue: in unsigned(7 downto 0); | |
rgb_green: in unsigned(7 downto 0); | |
rgb_red: in unsigned(7 downto 0) | |
); | |
end entity rgb2ycbcr; | |
-- A RGB to YCbCr converter with reset. | |
-- | |
-- I/O pins: | |
-- -------- | |
-- y : output 8-bit unsigned value in range of 0-127 | |
-- cb : output 8-bit unsigned value in range of 0-128 | |
-- cr : output 8-bit unsigned value in range of 0-128 | |
-- enable_out : output True when output is available | |
-- r : input 8-bit unsigned value in range of 0-255 | |
-- g : input 8-bit unsigned value in range of 0-255 | |
-- b : input 8-bit unsigned value in range of 0-255 | |
-- enable_in : input True when input is available | |
-- clk : input clock boolean signal | |
-- reset : input reset boolean signal | |
architecture MyHDL of rgb2ycbcr is | |
constant ACTIVE_HIGH: integer := 1; | |
constant INACTIVE_LOW: integer := 0; | |
signal Y2_s: signed (14 downto 0); | |
signal Y3_s: signed (14 downto 0); | |
signal Y1_s: signed (14 downto 0); | |
signal Cr1_s: signed (14 downto 0); | |
signal G_s: signed (8 downto 0); | |
signal Cr_sum: signed (23 downto 0); | |
signal Cr2_s: signed (14 downto 0); | |
signal offset_y: signed (23 downto 0); | |
signal Cr3_s: signed (14 downto 0); | |
signal Cb_sum: signed (23 downto 0); | |
signal R_s: signed (8 downto 0); | |
signal offset_cr: signed (23 downto 0); | |
signal Cb1_s: signed (14 downto 0); | |
signal Y_sum: signed (23 downto 0); | |
signal Cb2_s: signed (14 downto 0); | |
signal offset_cb: signed (23 downto 0); | |
signal Cb3_s: signed (14 downto 0); | |
signal B_s: signed (8 downto 0); | |
type t_array_Cb_reg is array(0 to 3-1) of signed (23 downto 0); | |
signal Cb_reg: t_array_Cb_reg; | |
type t_array_Cr_reg is array(0 to 3-1) of signed (23 downto 0); | |
signal Cr_reg: t_array_Cr_reg; | |
type t_array_Y_reg is array(0 to 3-1) of signed (23 downto 0); | |
signal Y_reg: t_array_Y_reg; | |
begin | |
Y2_s <= to_signed(9617, 15); | |
Y3_s <= to_signed(1868, 15); | |
Y1_s <= to_signed(4914, 15); | |
Cr1_s <= to_signed(8192, 15); | |
Cr2_s <= to_signed(-6860, 15); | |
offset_y <= to_signed(0, 24); | |
Cr3_s <= to_signed(-1332, 15); | |
offset_cr <= to_signed(2097152, 24); | |
Cb1_s <= to_signed(-2764, 15); | |
Cb2_s <= to_signed(-5428, 15); | |
offset_cb <= to_signed(2097152, 24); | |
Cb3_s <= to_signed(8192, 15); | |
RGB2YCBCR_LOGIC: process (clk, reset) is | |
begin | |
if (reset = '0') then | |
Y_sum <= to_signed(0, 24); | |
Cb_sum <= to_signed(0, 24); | |
ycbcr_cb <= to_unsigned(0, 8); | |
enable_out <= '0'; | |
Cr_reg(0) <= to_signed(0, 24); | |
Cr_reg(1) <= to_signed(0, 24); | |
Cr_reg(2) <= to_signed(0, 24); | |
Y_reg(0) <= to_signed(0, 24); | |
Y_reg(1) <= to_signed(0, 24); | |
Y_reg(2) <= to_signed(0, 24); | |
Cr_sum <= to_signed(0, 24); | |
ycbcr_cr <= to_unsigned(0, 8); | |
Cb_reg(0) <= to_signed(0, 24); | |
Cb_reg(1) <= to_signed(0, 24); | |
Cb_reg(2) <= to_signed(0, 24); | |
ycbcr_y <= to_unsigned(0, 8); | |
elsif rising_edge(clk) then | |
enable_out <= '0'; | |
if (enable_in = '1') then | |
Y_reg(0) <= (R_s * Y1_s); | |
Y_reg(1) <= (G_s * Y2_s); | |
Y_reg(2) <= (B_s * Y3_s); | |
Cb_reg(0) <= (R_s * Cb1_s); | |
Cb_reg(1) <= (G_s * Cb2_s); | |
Cb_reg(2) <= (B_s * Cb3_s); | |
Cr_reg(0) <= (R_s * Cr1_s); | |
Cr_reg(1) <= (G_s * Cr2_s); | |
Cr_reg(2) <= (B_s * Cr3_s); | |
Y_sum <= (((Y_reg(0) + Y_reg(1)) + Y_reg(2)) + offset_y); | |
Cb_sum <= (((Cb_reg(0) + Cb_reg(1)) + Cb_reg(2)) + offset_cb); | |
Cr_sum <= (((Cr_reg(0) + Cr_reg(1)) + Cr_reg(2)) + offset_cr); | |
ycbcr_y <= unsigned(Y_sum(22-1 downto 14)); | |
ycbcr_cb <= unsigned(Cb_sum(22-1 downto 14)); | |
ycbcr_cr <= unsigned(Cr_sum(22-1 downto 14)); | |
end if; | |
enable_out <= '1'; | |
end if; | |
end process RGB2YCBCR_LOGIC; | |
R_s <= signed(resize(rgb_red, 9)); | |
G_s <= signed(resize(rgb_green, 9)); | |
B_s <= signed(resize(rgb_blue, 9)); | |
end architecture MyHDL; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment