📄 gen_itu.v
字号:
else
if (ce)
begin
if (reload)
field_count <= fcount_reset;
else if (eav_next)
begin
if (int_std == NTSC_COMPOSITE)
begin
if (vcnt == FLD1_LAST_ACTIVE_NTSC || vcnt == V_TOTAL_NTSC)
begin
if (field_count == 3'b011)
field_count <= 3'b000;
else
field_count <= field_count + 1;
end
end
if (int_std == PAL_COMPOSITE)
begin
if (vcnt == FLD2_START_PAL || vcnt == V_TOTAL_PAL)
field_count <= field_count + 1;
end
end
end
//The f bit is used to keep track of fields for component video.
//The f bit is included in the component video TRS XYZ word.
always @ (posedge clk or posedge rst)
if (rst)
f <= f_reset;
else if (ce)
begin
if (reload)
f <= f_reset;
else if (eav_next && vcnt == fld1_last)
f <= 1'b1;
else if (eav_next && vcnt == fld2_last)
f <= 1'b0;
end
//The h bit is used to indicate the horizontal blanking interval for component video.
//This bit is included in the component video TRS XYZ word.
always @ (posedge clk or posedge rst)
if (rst)
h <= 1'b0;
else if (ce)
begin
if (int_std == NTSC_COMPOSITE || int_std == PAL_COMPOSITE)
h <= 1'b0;
else
begin
if (reload)
h <= 1'b0;
else if (eav_next)
h <= 1'b1;
else if (sav_next)
h <= 1'b0;
end
end
//The v bit is used to indicate the vertical blanking interval.
//It is valid for both component and composite video, but is only included in the component video TRS XYZ word.
always @ (posedge clk or posedge rst)
if (rst)
v <= 1'b0;
else if (ce)
begin
if (reload)
v <= 1'b0;
else if (eav_next)
begin
if (vcnt == fld1_act_start || vcnt == fld2_act_start)
v <= 1'b0; // added by mark July.20: why not 1
else if (vcnt == fld1_act_end || vcnt == fld2_act_end)
v <= 1'b1; // added by mark July.20: why not 0
end
end
//horizontal and vertical constant generation
//This code generates the various horizontal and vertical constant values
//that are used to compare with the hcnt and vcnt to determine when lines end,
//when fields start and end, and when to generate TRS symbols.
always @ (int_std or vcnt)
case(int_std)
NTSC_422:
begin
h_last <= H_TOTAL_NTSC_422 - 1;
v_last <= V_TOTAL_NTSC;
eav_loc <= EAV_NTSC_422 - 1;
sav_loc <= SAV_NTSC_422 - 1;
fld1_act_start <= early_v ?
FLD1_FIRST_ACTIVE_NTSC - EARLY_V_OFFSET - 1 :
FLD1_FIRST_ACTIVE_NTSC - 1;
fld1_act_end <= FLD1_LAST_ACTIVE_NTSC;
fld2_act_start <= early_v ?
FLD2_FIRST_ACTIVE_NTSC - EARLY_V_OFFSET - 1 :
FLD2_FIRST_ACTIVE_NTSC - 1;
fld2_act_end <= FLD2_LAST_ACTIVE_NTSC;
fld1_last <= FLD2_START_NTSC - 1;
fld2_last <= FLD1_START_NTSC - 1;
end
NTSC_COMPOSITE:
begin
h_last <= H_TOTAL_NTSC_COMPOSITE - 1;
v_last <= V_TOTAL_NTSC;
eav_loc <= EAV_NTSC_COMPOSITE - 1;
sav_loc <= 0;
fld1_act_start <= FLD1_FIRST_ACTIVE_NTSC - 1;
fld1_act_end <= FLD1_LAST_ACTIVE_NTSC;
fld2_act_start <= FLD2_FIRST_ACTIVE_NTSC - 1;
fld2_act_end <= FLD2_LAST_ACTIVE_NTSC;
fld1_last <= FLD2_START_NTSC - 1;
fld2_last <= FLD1_START_NTSC - 1;
end
NTSC_422_WIDE:
begin
h_last <= H_TOTAL_NTSC_422_WIDE - 1;
v_last <= V_TOTAL_NTSC;
eav_loc <= EAV_NTSC_422_WIDE - 1;
sav_loc <= SAV_NTSC_422_WIDE - 1;
fld1_act_start <= FLD1_FIRST_ACTIVE_NTSC - 1;
fld1_act_end <= FLD1_LAST_ACTIVE_NTSC;
fld2_act_start <= FLD2_FIRST_ACTIVE_NTSC - 1;
fld2_act_end <= FLD2_LAST_ACTIVE_NTSC;
fld1_last <= FLD2_START_NTSC - 1;
fld2_last <= FLD1_START_NTSC - 1;
end
NTSC_4444:
begin
h_last <= H_TOTAL_NTSC_4444 - 1;
v_last <= V_TOTAL_NTSC;
eav_loc <= EAV_NTSC_4444 - 1;
sav_loc <= SAV_NTSC_4444 - 1;
fld1_act_start <= FLD1_FIRST_ACTIVE_NTSC - 1;
fld1_act_end <= FLD1_LAST_ACTIVE_NTSC;
fld2_act_start <= FLD2_FIRST_ACTIVE_NTSC - 1;
fld2_act_end <= FLD2_LAST_ACTIVE_NTSC;
fld1_last <= FLD2_START_NTSC - 1;
fld2_last <= FLD1_START_NTSC - 1;
end
PAL_422:
begin
h_last <= H_TOTAL_PAL_422 - 1;
v_last <= V_TOTAL_PAL;
eav_loc <= EAV_PAL_422 - 1;
sav_loc <= SAV_PAL_422 - 1;
fld1_act_start <= FLD1_FIRST_ACTIVE_PAL - 1;
fld1_act_end <= FLD1_LAST_ACTIVE_PAL;
fld2_act_start <= FLD2_FIRST_ACTIVE_PAL - 1;
fld2_act_end <= FLD2_LAST_ACTIVE_PAL;
fld1_last <= FLD2_START_PAL - 1;
fld2_last <= V_TOTAL_PAL;
end
PAL_COMPOSITE:
begin
if (vcnt == PAL_CMPST_FLD1_EXTRA ||
vcnt == PAL_CMPST_FLD2_EXTRA)
h_last <= H_TOTAL_PAL_CMPST_EXTRA - 1;
else
h_last <= H_TOTAL_PAL_COMPOSITE - 1;
v_last <= V_TOTAL_PAL;
eav_loc <= EAV_PAL_COMPOSITE - 1;
sav_loc <= 0;
fld1_act_start <= FLD1_FIRST_ACTIVE_PAL - 1;
fld1_act_end <= FLD1_LAST_ACTIVE_PAL;
fld2_act_start <= FLD2_FIRST_ACTIVE_PAL - 1;
fld2_act_end <= FLD2_LAST_ACTIVE_PAL;
fld1_last <= FLD2_START_PAL - 1;
fld2_last <= V_TOTAL_PAL;
end
PAL_422_WIDE:
begin
h_last <= H_TOTAL_PAL_422_WIDE - 1;
v_last <= V_TOTAL_PAL;
eav_loc <= EAV_PAL_422_WIDE - 1;
sav_loc <= SAV_PAL_422_WIDE - 1;
fld1_act_start <= FLD1_FIRST_ACTIVE_PAL - 1;
fld1_act_end <= FLD1_LAST_ACTIVE_PAL;
fld2_act_start <= FLD2_FIRST_ACTIVE_PAL - 1;
fld2_act_end <= FLD2_LAST_ACTIVE_PAL;
fld1_last <= FLD2_START_PAL - 1;
fld2_last <= V_TOTAL_PAL;
end
PAL_4444:
begin
h_last <= H_TOTAL_PAL_4444 - 1;
v_last <= V_TOTAL_PAL;
eav_loc <= EAV_PAL_4444 - 1;
sav_loc <= SAV_PAL_4444 - 1;
fld1_act_start <= FLD1_FIRST_ACTIVE_PAL - 1;
fld1_act_end <= FLD1_LAST_ACTIVE_PAL;
fld2_act_start <= FLD2_FIRST_ACTIVE_PAL - 1;
fld2_act_end <= FLD2_LAST_ACTIVE_PAL;
fld1_last <= FLD2_START_PAL - 1;
fld2_last <= V_TOTAL_PAL;
end
default:
begin
h_last <= H_TOTAL_NTSC_422 - 1;
v_last <= V_TOTAL_NTSC;
eav_loc <= EAV_NTSC_422 - 1;
sav_loc <= SAV_NTSC_422 - 1;
fld1_act_start <= FLD1_FIRST_ACTIVE_NTSC - 1;
fld1_act_end <= FLD1_LAST_ACTIVE_NTSC;
fld2_act_start <= FLD2_FIRST_ACTIVE_NTSC - 1;
fld2_act_end <= FLD2_LAST_ACTIVE_NTSC;
fld1_last <= FLD2_START_PAL - 1;
fld2_last <= V_TOTAL_PAL;
end
endcase
//q video output data, This code generates the output video values.
//When a TRS is being generated, the code generates the proper TRS word values.
//Otherwise it outputs a black level value appropriate for the selected video standard.
//Note that 4:2:2 component video black values are used when composite video is selected.
always @ (hcnt or xyz or trs_word or int_std or trs_id or trs or s)
begin
if (trs)
begin
if (trs_word == 3'b000)
q <= 10'h3ff;
else if (trs_word == 3'b001 || trs_word == 3'b010)
q <= 10'h000;
else if (trs_word == 3'b011)
q <= xyz;
else if (trs_word == 3'b100)
q <= trs_id;
end
else if (int_std == NTSC_4444 || int_std == PAL_4444)
begin
if (s)
case (hcnt[1:0])
2'b00: q <= YCBCR_4444_BLANK_CB;
2'b01: q <= YCBCR_4444_BLANK_Y;
2'b10: q <= YCBCR_4444_BLANK_CR;
2'b11: q <= YCBCR_4444_BLANK_A;
endcase
else
case (hcnt[1:0])
2'b00: q <= RGB_4444_BLANK_B;
2'b01: q <= RGB_4444_BLANK_G;
2'b10: q <= RGB_4444_BLANK_R;
2'b11: q <= RGB_4444_BLANK_A;
endcase
end
else
begin
if (hcnt[0] == 1'b1)
q <= YCBCR_422_BLANK_Y;
else
q <= YCBCR_422_BLANK_C;
end
end
//xyz word This code generates the TRS XYZ word for component video.
//The XYZ word includes the H, V, and F bits (and the S bit for the 4444 formats).
//It also includes some protection bits that are formed by xor'ing the F,V,H, and S bits in various combinations.
always @ (h or v or f or s or int_std)
begin
if (int_std == NTSC_4444 || int_std == PAL_4444)
begin
xyz[9] <= 1'b1;
xyz[8] <= f;
xyz[7] <= v;
xyz[6] <= h;
xyz[5] <= s;
xyz[4] <= f ^ v ^ h;
xyz[3] <= f ^ v ^ s;
xyz[2] <= v ^ h ^ s;
xyz[1] <= f ^ h ^ s;
xyz[0] <= 1'b0;
end
else if (int_std == NTSC_422 || int_std == NTSC_422_WIDE ||
int_std == PAL_422 || int_std == PAL_422_WIDE)
begin
xyz[9] <= 1'b1;
xyz[8] <= f;
xyz[7] <= v;
xyz[6] <= h;
xyz[5] <= v ^ h;
xyz[4] <= f ^ h;
xyz[3] <= f ^ v;
xyz[2] <= f ^ v ^ h;
xyz[1] <= 1'b0;
xyz[0] <= 1'b0;
end
else
xyz <= 0; // XYZ is always 000 for composite video
end
//trs_id word, This code generates the TRS ID word for composite video.
//The TRS ID word contains the three bits of the field_count and five bits the current vertical line.
//For the first 30 vertical lines of a field the five-bit line field contains the line count.
//After the 30th line of a field, the line count field is all ones.
//A line count of all zeros indicates the field is not used.
//Bit 8 of the TRS ID word is an event parity bit for bits 7 through 0 of the TRS ID word.
//Bit 9 is the complement of bit 8.
always @ (int_std or vcnt)
if (int_std == NTSC_COMPOSITE)
begin
if (vcnt < 31)
trs_id_line <= vcnt[4:0];
else if (vcnt > 263 && vcnt < 294)
trs_id_line <= vcnt - 263;
else
trs_id_line <= 5'b11111;
end
else if (int_std == PAL_COMPOSITE)
begin
if (vcnt < 31)
trs_id_line <= vcnt[4:0];
else if (vcnt > 313 && vcnt < 344)
trs_id_line <= vcnt - 313;
else
trs_id_line <= 5'b11111;
end
else
trs_id_line <= 5'b00000;
always @ (field_count or trs_id_line or trs_id)
begin
trs_id[2:0] <= field_count;
trs_id[7:3] <= trs_id_line;
trs_id[8] <= trs_id_line[4] ^ trs_id_line[3] ^ trs_id_line[2] ^
trs_id_line[1] ^ trs_id_line[0] ^ field_count[2] ^
field_count[1] ^ field_count[0];
trs_id[9] <= ~trs_id[8];
end
// The field port is a 3-bit output indicating the current field. For
// component video, the F bit is in bit 0 and the other two bits are zeros.
// For composite video, field is assigned the value of field_count.
always @ (field_count or f or int_std)
if (int_std == NTSC_COMPOSITE || int_std == PAL_COMPOSITE)
field <= field_count;
else
field <= {2'b00, f};
// h_blank output indicates the horizontal blanking interval.
// For component video it is asserted from the start of the EAV symbol through the end of the SAV symbol.
// It is mostly equal to the internal h signal, except that h_blank is asserted during the SAV and h is not.
// For composite video, h is asserted only during the TRS symbol.
assign h_blank = trs | h;
// The v_blank output signal indicates the vertical blanking interval.
assign v_blank = v;
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -