📄 gen_itu.v
字号:
`timescale 1ns / 1 ns
module gen_itu (
clk, // clock input
ce, // clock enable
rst, // async reset input
std, // video standard code input
s, // color space select bit for 4444
early_v, // when asserted, the V bit is allowed to fall early
q, // video output
field, // field bits
v_blank, // vertical blanking bit
h_blank, // horizontal blanking bit
trs // asserted during TRS
);
//-----------------------------------------------------------------------------
//Parameter definitions
//This group of parameters defines the bit widths of various fields in the module.
parameter HCNT_WIDTH = 12; // Width of hcnt
parameter VCNT_WIDTH = 10; // Width of vcnt
parameter HCNT_MSB = HCNT_WIDTH - 1; // MS bit # of hcnt
parameter VCNT_MSB = VCNT_WIDTH - 1; // MS bit # of vcnt
//Control the total number of clocks per line for the various video standards.
//And control the horizontal TRS locations for the various standards.
parameter H_TOTAL_NTSC_422 = 1716;
parameter EAV_NTSC_422 = 1440;
parameter SAV_NTSC_422 = 1712;
parameter H_TOTAL_NTSC_422_WIDE = 2288;
parameter EAV_NTSC_422_WIDE = 1920;
parameter SAV_NTSC_422_WIDE = 2284;
parameter H_TOTAL_NTSC_4444 = 3432;
parameter EAV_NTSC_4444 = 2880;
parameter SAV_NTSC_4444 = 3428;
parameter H_TOTAL_NTSC_COMPOSITE = 910;
parameter EAV_NTSC_COMPOSITE = 790;
parameter H_TOTAL_PAL_422 = 1728;
parameter EAV_PAL_422 = 1440;
parameter SAV_PAL_422 = 1724;
parameter H_TOTAL_PAL_422_WIDE = 2304;
parameter EAV_PAL_422_WIDE = 1920;
parameter SAV_PAL_422_WIDE = 2300;
parameter H_TOTAL_PAL_4444 = 3456;
parameter EAV_PAL_4444 = 2880;
parameter SAV_PAL_4444 = 3452;
parameter H_TOTAL_PAL_COMPOSITE = 1135;
parameter EAV_PAL_COMPOSITE = 967;
//PAL composite video has two extra samples per field.
//These samples are on lines 313 and 625 and are numbered 1135 and 1136.
//They appear immediately prior to the first active picture sample.
//These parameters control the generation of these extra samples.
//Note that because the vcnt increments before the start of active video,
//the line numbers for the extra lines need to be one more than indicated above.
parameter PAL_CMPST_FLD1_EXTRA = 314;
parameter PAL_CMPST_FLD2_EXTRA = 1;
parameter H_TOTAL_PAL_CMPST_EXTRA = H_TOTAL_PAL_COMPOSITE + 2;
//controls the vertical positioning of various elements of the video signal.
parameter V_TOTAL_NTSC = 525;
parameter FLD1_START_NTSC = 4;
parameter FLD1_FIRST_ACTIVE_NTSC = 20;
parameter FLD1_LAST_ACTIVE_NTSC = 263;
parameter FLD2_START_NTSC = 266;
parameter FLD2_FIRST_ACTIVE_NTSC = 283;
parameter FLD2_LAST_ACTIVE_NTSC = 525;
parameter V_TOTAL_PAL = 625;
parameter FLD1_START_PAL = 1;
parameter FLD1_FIRST_ACTIVE_PAL = 23;
parameter FLD1_LAST_ACTIVE_PAL = 310;
parameter FLD2_START_PAL = 313;
parameter FLD2_FIRST_ACTIVE_PAL = 336;
parameter FLD2_LAST_ACTIVE_PAL = 623;
//defines the encoding for the video standards output code.
parameter [2:0]
NTSC_422 = 3'b000,
NTSC_COMPOSITE = 3'b001,
NTSC_422_WIDE = 3'b010,
NTSC_4444 = 3'b011,
PAL_422 = 3'b100,
PAL_COMPOSITE = 3'b101,
PAL_422_WIDE = 3'b110,
PAL_4444 = 3'b111;
//When the early fall of the V bit is enabled, this parameter specifies
//how many lines early the V bit falls.
parameter EARLY_V_OFFSET = 10;
//These parameters define the BLACK color levels for the output video.
parameter YCBCR_4444_BLANK_Y = 10'h040;
parameter YCBCR_4444_BLANK_CB = 10'h200;
parameter YCBCR_4444_BLANK_CR = 10'h200;
parameter YCBCR_4444_BLANK_A = 10'h040;
parameter RGB_4444_BLANK_R = 10'h040;
parameter RGB_4444_BLANK_G = 10'h040;
parameter RGB_4444_BLANK_B = 10'h040;
parameter RGB_4444_BLANK_A = 10'h040;
parameter YCBCR_422_BLANK_Y = 10'h040;
parameter YCBCR_422_BLANK_C = 10'h200;
//-----------------------------------------------------------------------------
// Signal definitions
// IO definitions
input clk;
input ce;
input rst;
input [2:0] std;
input s;
input early_v;
output [9:0] q;
output [2:0] field;
output v_blank;
output h_blank;
output trs;
reg [9:0] q;
reg [2:0] field;
reg trs;
// internal signals
reg [HCNT_MSB:0] hcnt; // horizontal counter
reg [VCNT_MSB:0] vcnt; // vertical counter
reg [2:0] field_count; // field counter for composite video
reg f; // field bit for component standards
reg v; // v blank bit
reg h; // h blank bit
reg [HCNT_MSB:0] h_last; // total h count for current standard (H_TOTAL - 1)
reg [HCNT_MSB:0] eav_loc; // location of EAV for current standard
reg [HCNT_MSB:0] sav_loc; // location of SAV for current standard
reg [VCNT_MSB:0] v_last; // total v count for current standard
reg [VCNT_MSB:0] fld1_last; // starting position of field 1
reg [VCNT_MSB:0] fld1_act_start; // starting position of active video field 1
reg [VCNT_MSB:0] fld1_act_end; // ending position of active video field 1
reg [VCNT_MSB:0] fld2_last; // starting position of field 2
reg [VCNT_MSB:0] fld2_act_start; // starting position of active video field 2
reg [VCNT_MSB:0] fld2_act_end; // ending position of active video field 2
reg [HCNT_MSB:0] h_reset; // reset value for hcnt
reg [VCNT_MSB:0] v_reset; // reset value for vcnt
reg [2:0] int_std; // internal version of std input bits
wire new_std; // asserted when std != int_std
reg reload; // synchronous version of new_std
reg [9:0] xyz; // the TRS XYZ word for component video
wire eav_next; // asserted when EAV will start on next sample
reg sav_next; // asserted when SAV will start on next sample
reg f_reset; // reset value for f
reg [2:0] fcount_reset; // reset value for field counter
reg [9:0] trs_id; // the TRS ID word for composite video
reg [2:0] trs_word; // counter for TRS word
reg [2:0] trs_length; // number of words in TRS
reg [4:0] trs_id_line; // line number for trs_id word
//Whenever the std code changes, this code assigns new values to the various
//values used to reset the hcnt, vcnt, f, and field_count registers.
always @ (std)
case(std)
NTSC_422:
begin
h_reset <= EAV_NTSC_422 - 1;
v_reset <= V_TOTAL_NTSC;
f_reset <= 1'b1;
fcount_reset <= 0;
end
NTSC_COMPOSITE:
begin
h_reset <= EAV_NTSC_COMPOSITE - 1;
v_reset <= V_TOTAL_NTSC;
f_reset <= 1'b1;
fcount_reset <= 3'b011;
end
NTSC_422_WIDE:
begin
h_reset <= EAV_NTSC_422_WIDE - 1;
v_reset <= V_TOTAL_NTSC;
f_reset <= 1'b1;
fcount_reset <= 0;
end
NTSC_4444:
begin
h_reset <= EAV_NTSC_4444 - 1;
v_reset <= V_TOTAL_NTSC;
f_reset <= 1'b1;
fcount_reset <= 0;
end
PAL_422:
begin
h_reset <= EAV_PAL_422 - 1;
v_reset <= FLD2_LAST_ACTIVE_PAL;
f_reset <= 1'b1;
fcount_reset <= 0;
end
PAL_COMPOSITE:
begin
h_reset <= EAV_PAL_COMPOSITE - 1;
v_reset <= FLD2_LAST_ACTIVE_PAL;
f_reset <= 1'b1;
fcount_reset <= 3'b111;
end
PAL_422_WIDE:
begin
h_reset <= EAV_PAL_422_WIDE - 1;
v_reset <= FLD2_LAST_ACTIVE_PAL;
f_reset <= 1'b1;
fcount_reset <= 0;
end
PAL_4444:
begin
h_reset <= EAV_PAL_4444 - 1;
v_reset <= FLD2_LAST_ACTIVE_PAL;
f_reset <= 1'b1;
fcount_reset <= 0;
end
endcase
//int_std is an internal synchronous version of the std input bits that specify
//which video standard to generate.
always @ (posedge clk or posedge rst)
if (rst)
int_std <= std;
else
if (ce & new_std)
int_std <= std;
// new_std is asynchronously asserted when std and int_std do not match.
// reload is a synchronous version of new_std.
assign new_std = (std != int_std);
always @ (posedge clk or posedge rst)
if (rst)
reload <= 1'b0;
else if (ce)
reload <= new_std;
//trs_length indicates the number of words in the TRS symbol for the current
//video standard:4 for the component video standars and 5 for the composite video standards.
always @ (int_std)
if (int_std == NTSC_COMPOSITE || int_std == PAL_COMPOSITE)
trs_length <= 3'b101; // added by mark July.20: why not 101 trs_length <= 3'b100;
else
trs_length <= 3'b100; // added by mark July.20: why not 100 trs_length <= 3'b011;
//hcnt is the horizontal counter used to generate video.
//It increments every clock and resets to 0 at the end of each video line(when h_last is asserted).
//When reload or reset are asserted, it will load with the value of the h_reset signal.
always @ (posedge clk or posedge rst)
if (rst)
hcnt <= h_reset;
else if (ce)
begin
if (reload)
hcnt <= h_reset;
else if (hcnt == h_last)
hcnt <= 0;
else
hcnt <= hcnt + 1;
end
//eav_next and sav_next
//These signals are asserted when the EAV or SAV signals will be generated on the next clock.
//They are generated by comparing the hcnt counter to the values of the eav_loc and sav_loc signals.
//Composite video only has one TRS symbol per lines as indicated by the eav_next signal.
//sav_next is never asserted during composite video.
assign eav_next = (hcnt == eav_loc);
always @ (hcnt or sav_loc or int_std)
if (int_std == NTSC_COMPOSITE || int_std == PAL_COMPOSITE)
sav_next <= 1'b0;
else
sav_next <= (hcnt == sav_loc);
//vcnt is the vertical video line counter.
//It increments every time the eav_next signal is asserted, marking the beginning of a new line.
//When the vcnt value equals v_last, the counter rolls over to a value of 1.
//When the reset or reload signals are asserted, the counter loads the v_reset value.
always @ (posedge clk or posedge rst)
if (rst)
vcnt <= v_reset;
else if (ce)
begin
if (reload)
vcnt <= v_reset;
else if (eav_next)
begin
if (vcnt == v_last)
vcnt <= 1; // added by mark July.20: why not 0
else
vcnt <= vcnt + 1;
end
end
//This trs_word counter keeps track of which word of the trs symbol is being output.
//It resets to zero when eav_next or sav_next are asserted and increments every clock cycle after that.
always @ (posedge clk or posedge rst)
if (rst)
trs_word <= 0;
else if (ce)
begin
if (eav_next | sav_next)
trs_word <= 0;
else
trs_word <= trs_word + 1;
end
//The trs signal is asserted during the four words of a component video TRS symbol
//or the five words of a composite video TRS symbol.
always @ (posedge clk or posedge rst)
if (rst)
trs <= 1'b0;
else if (ce)
begin
if (eav_next | sav_next)
trs <= 1'b1;
else if (trs & trs_word == trs_length)
trs <= 1'b0;
end
//The field counter is used to keep track of fields for composite video.
//The NTSC composite video standard has four fields, 000 to 011.
//The PAL composite video standard has eight fields, 000 to 111.
//The field count value is included in the composite video TRS ID word.
//The field counter increments when the eav_next is asserted and the vcnt value is at the end of a field.
//If reset or reload are asserted, the field counter loads with the fcount_reset value.
always @ (posedge clk or posedge rst)
if (rst)
field_count <= fcount_reset;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -