HDMI 方块移动实验
dvi_transmitter_top.v
module dvi_transmitter_top(
input pclk ,
input sys_rst_n ,
input pclk_x5 ,
input video_hsync ,
input video_vsync ,
input video_de ,
input [23 : 0] video_din ,
output tmds_clk_p ,
output tmds_clk_n ,
output [2 : 0] tmds_data_p ,
output [2 : 0] tmds_data_n ,
output tmds_oen
);
assign tmds_oen = 1 ;
wire reset ;
wire [9:0] blue_10bit ;
wire [9:0] green_10bit ;
wire [9:0] red_10bit ;
wire [2:0] tmds_data_serial ;
wire tmds_clk_serial ;
reset_syn u_reset_syn(
.pclk ( pclk ),
.reset_n ( sys_rst_n ),
.reset ( reset )
);
dvi_encoder u_dvi_encoder_blue(
.clkin ( pclk ),
.rstin ( reset ),
.din ( video_din[7:0] ),
.c0 ( video_hsync ),
.c1 ( video_vsync ),
.de ( video_de ),
.dout ( blue_10bit )
);
dvi_encoder u_dvi_encoder_green(
.clkin ( pclk ),
.rstin ( reset ),
.din ( video_din[15:8] ),
.c0 ( 1'b0 ),
.c1 ( 1'b0 ),
.de ( video_de ),
.dout ( green_10bit )
);
dvi_encoder u_dvi_encoder_red(
.clkin ( pclk ),
.rstin ( reset ),
.din ( video_din[23:16] ),
.c0 ( 1'b0 ),
.c1 ( 1'b0 ),
.de ( video_de ),
.dout ( red_10bit )
);
serializer10 u_serializer10_blue(
.reset ( reset ),
.paralell_clk ( pclk ),
.serial_clk_5x ( pclk_x5 ),
.paralell_data ( blue_10bit ),
.serial_data_out ( tmds_data_serial[0] )
);
serializer10 u_serializer10_green(
.reset ( reset ),
.paralell_clk ( pclk ),
.serial_clk_5x ( pclk_x5 ),
.paralell_data ( green_10bit ),
.serial_data_out ( tmds_data_serial[1] )
);
serializer10 u_serializer10_red(
.reset ( reset ),
.paralell_clk ( pclk ),
.serial_clk_5x ( pclk_x5 ),
.paralell_data ( red_10bit ),
.serial_data_out ( tmds_data_serial[2] )
);
serializer10 u_serializer10_clk(
.reset ( reset ),
.paralell_clk ( pclk ),
.serial_clk_5x ( pclk_x5 ),
.paralell_data ( 10'b1111100000 ),
.serial_data_out ( tmds_clk_serial )
);
OBUFDS #(
.IOSTANDARD ("TMDS_33")
) TMDS0 (
.I (tmds_data_serial[0]),
.O (tmds_data_p[0]),
.OB (tmds_data_n[0])
);
OBUFDS #(
.IOSTANDARD ("TMDS_33")
) TMDS1 (
.I (tmds_data_serial[1]),
.O (tmds_data_p[1]),
.OB (tmds_data_n[1])
);
OBUFDS #(
.IOSTANDARD ("TMDS_33")
) TMDS2 (
.I (tmds_data_serial[2]),
.O (tmds_data_p[2]),
.OB (tmds_data_n[2])
);
OBUFDS #(
.IOSTANDARD ("TMDS_33")
) TMDS3 (
.I (tmds_clk_serial),
.O (tmds_clk_p),
.OB (tmds_clk_n)
);
endmodule
encoder.v
module dvi_encoder (
input clkin,
input rstin,
input [7:0] din,
input c0,
input c1,
input de,
output reg [9:0] dout
);
reg [3:0] n1d;
reg [7:0] din_q;
always @ (posedge clkin) begin
n1d <=#1 din[0] + din[1] + din[2] + din[3] + din[4] + din[5] + din[6] + din[7];
din_q <=#1 din;
end
wire decision1;
assign decision1 = (n1d > 4'h4) | ((n1d == 4'h4) & (din_q[0] == 1'b0));
wire [8:0] q_m;
assign q_m[0] = din_q[0];
assign q_m[1] = (decision1) ? (q_m[0] ^~ din_q[1]) : (q_m[0] ^ din_q[1]);
assign q_m[2] = (decision1) ? (q_m[1] ^~ din_q[2]) : (q_m[1] ^ din_q[2]);
assign q_m[3] = (decision1) ? (q_m[2] ^~ din_q[3]) : (q_m[2] ^ din_q[3]);
assign q_m[4] = (decision1) ? (q_m[3] ^~ din_q[4]) : (q_m[3] ^ din_q[4]);
assign q_m[5] = (decision1) ? (q_m[4] ^~ din_q[5]) : (q_m[4] ^ din_q[5]);
assign q_m[6] = (decision1) ? (q_m[5] ^~ din_q[6]) : (q_m[5] ^ din_q[6]);
assign q_m[7] = (decision1) ? (q_m[6] ^~ din_q[7]) : (q_m[6] ^ din_q[7]);
assign q_m[8] = (decision1) ? 1'b0 : 1'b1;
reg [3:0] n1q_m, n0q_m;
always @ (posedge clkin) begin
n1q_m <=#1 q_m[0] + q_m[1] + q_m[2] + q_m[3] + q_m[4] + q_m[5] + q_m[6] + q_m[7];
n0q_m <=#1 4'h8 - (q_m[0] + q_m[1] + q_m[2] + q_m[3] + q_m[4] + q_m[5] + q_m[6] + q_m[7]);
end
parameter CTRLTOKEN0 = 10'b1101010100;
parameter CTRLTOKEN1 = 10'b0010101011;
parameter CTRLTOKEN2 = 10'b0101010100;
parameter CTRLTOKEN3 = 10'b1010101011;
reg [4:0] cnt;
wire decision2, decision3;
assign decision2 = (cnt == 5'h0) | (n1q_m == n0q_m);
assign decision3 = (~cnt[4] & (n1q_m > n0q_m)) | (cnt[4] & (n0q_m > n1q_m));
reg de_q, de_reg;
reg c0_q, c1_q;
reg c0_reg, c1_reg;
reg [8:0] q_m_reg;
always @ (posedge clkin) begin
de_q <=#1 de;
de_reg <=#1 de_q;
c0_q <=#1 c0;
c0_reg <=#1 c0_q;
c1_q <=#1 c1;
c1_reg <=#1 c1_q;
q_m_reg <=#1 q_m;
end
always @ (posedge clkin or posedge rstin) begin
if(rstin) begin
dout <= 10'h0;
cnt <= 5'h0;
end else begin
if (de_reg) begin
if(decision2) begin
dout[9] <=#1 ~q_m_reg[8];
dout[8] <=#1 q_m_reg[8];
dout[7:0] <=#1 (q_m_reg[8]) ? q_m_reg[7:0] : ~q_m_reg[7:0];
cnt <=#1 (~q_m_reg[8]) ? (cnt + n0q_m - n1q_m) : (cnt + n1q_m - n0q_m);
end else begin
if(decision3) begin
dout[9] <=#1 1'b1;
dout[8] <=#1 q_m_reg[8];
dout[7:0] <=#1 ~q_m_reg[7:0];
cnt <=#1 cnt + {q_m_reg[8], 1'b0} + (n0q_m - n1q_m);
end else begin
dout[9] <=#1 1'b0;
dout[8] <=#1 q_m_reg[8];
dout[7:0] <=#1 q_m_reg[7:0];
cnt <=#1 cnt - {~q_m_reg[8], 1'b0} + (n1q_m - n0q_m);
end
end
end else begin
case ({c1_reg, c0_reg})
2'b00: dout <=#1 CTRLTOKEN0;
2'b01: dout <=#1 CTRLTOKEN1;
2'b10: dout <=#1 CTRLTOKEN2;
default: dout <=#1 CTRLTOKEN3;
endcase
cnt <=#1 5'h0;
end
end
end
endmodule
reset_syn.v
module reset_syn(
input pclk ,
input reset_n ,
output reg reset
);
reg reset1 ;
always@( posedge pclk or negedge reset_n)
begin
if( reset_n == 0)
begin
reset1 <= 1 ;
end
else
begin
reset1 <= 0 ;
reset <= reset1 ;
end
end
endmodule
serializer.v
module serializer10 (
input reset ,
input paralell_clk ,
input serial_clk_5x ,
input [9 : 0] paralell_data ,
output serial_data_out
);
wire cascade1 ;
wire cascade2 ;
OSERDESE2 #(
.DATA_RATE_OQ("DDR"),
.DATA_RATE_TQ("DDR"),
.DATA_WIDTH(10),
.SERDES_MODE("MASTER"),
.TBYTE_CTL("FALSE"),
.TBYTE_SRC("FALSE"),
.TRISTATE_WIDTH(1)
)
OSERDESE2_MASTER (
.OFB(),
.OQ(serial_data_out),
.SHIFTOUT1(),
.SHIFTOUT2(),
.TBYTEOUT(),
.TFB(),
.TQ(),
.CLK(serial_clk_5x),
.CLKDIV(paralell_clk),
.D1(paralell_data[0]),
.D2(paralell_data[1]),
.D3(paralell_data[2]),
.D4(paralell_data[3]),
.D5(paralell_data[4]),
.D6(paralell_data[5]),
.D7(paralell_data[6]),
.D8(paralell_data[7]),
.OCE(1'b1),
.RST(reset),
.SHIFTIN1(cascade1),
.SHIFTIN2(cascade2),
.T1(1'b0),
.T2(1'b0),
.T3(1'b0),
.T4(1'b0),
.TBYTEIN(1'b0),
.TCE(1'b0)
);
OSERDESE2 #(
.DATA_RATE_OQ("DDR"),
.DATA_RATE_TQ("DDR"),
.DATA_WIDTH(10),
.SERDES_MODE("SLAVE"),
.TBYTE_CTL("FALSE"),
.TBYTE_SRC("FALSE"),
.TRISTATE_WIDTH(1)
)
OSERDESE2_SLAVE (
.OFB(),
.OQ(),
.SHIFTOUT1(cascade1),
.SHIFTOUT2(cascade2),
.TBYTEOUT(),
.TFB(),
.TQ(),
.CLK(serial_clk_5x),
.CLKDIV(paralell_clk),
.D1(1'b0),
.D2(1'b0),
.D3(paralell_data[8]),
.D4(paralell_data[9]),
.D5(1'b0),
.D6(1'b0),
.D7(1'b0),
.D8(1'b0),
.OCE(1'b1),
.RST(reset),
.SHIFTIN1(),
.SHIFTIN2(),
.T1(1'b0),
.T2(1'b0),
.T3(1'b0),
.T4(1'b0),
.TBYTEIN(1'b0),
.TCE(1'b0)
);
endmodule
top.v
module hdmi_top(
input sys_clk,
input sys_rst_n,
output tmds_clk_p,
output tmds_clk_n,
output [2:0] tmds_data_p,
output [2:0] tmds_data_n
);
wire pixel_clk;
wire pixel_clk_5x;
wire clk_locked;
wire [10:0] pixel_xpos_w;
wire [10:0] pixel_ypos_w;
wire [23:0] pixel_data_w;
wire video_hs;
wire video_vs;
wire video_de;
wire [23:0] video_rgb;
clk_wiz_0 instance_name
(
.clk_out1(pixel_clk),
.clk_out2(pixel_clk_5x),
.reset(~sys_rst_n),
.locked(clk_locked),
.clk_in1(sys_clk)
);
video_driver u_video_driver(
.pixel_clk ( pixel_clk ),
.rst_n ( sys_rst_n ),
.pixel_data ( pixel_data_w ),
.video_rgb ( video_rgb ),
.video_hs ( video_hs ),
.video_vs ( video_vs ),
.video_de ( video_de ),
.pixel_xpos ( pixel_xpos_w ),
.pixel_ypos ( pixel_ypos_w )
);
video_display u_video_display(
.pixel_clk ( pixel_clk ),
.sys_rst_n ( sys_rst_n ),
.pixel_xpos_w ( pixel_xpos_w ),
.pixel_ypos_w ( pixel_ypos_w ),
.pixel_data_w ( pixel_data_w )
);
dvi_transmitter_top u_dvi_transmitter_top(
.pclk ( pixel_clk ),
.sys_rst_n ( sys_rst_n & clk_locked ),
.pclk_x5 ( pixel_clk_5x ),
.video_hsync ( video_hs ),
.video_vsync ( video_vs ),
.video_de ( video_de ),
.video_din ( video_rgb ),
.tmds_clk_p ( tmds_clk_p ),
.tmds_clk_n ( tmds_clk_n ),
.tmds_data_p ( tmds_data_p ),
.tmds_data_n ( tmds_data_n ),
.tmds_oen ( )
);
endmodule
video_display.v
module video_display(
input pixel_clk ,
input sys_rst_n ,
input [ 11 : 0 ] pixel_xpos_w ,
input [ 11 : 0 ] pixel_ypos_w ,
output reg [ 23 : 0 ] pixel_data_w
);
parameter WIDTH = 12'd40 ;
parameter pixelx = 12'd1280 ;
parameter pixely = 12'd720 ;
reg [11 :0] blockx ;
reg [11 :0] blocky ;
reg [21 : 0] cnt ;
wire moveon ;
reg move_down ;
reg move_right ;
parameter CLK10 = 22'd750000 ;
parameter WHITE = 24'hFFFFFF ;
parameter BLACK = 24'h000000 ;
parameter BLUE = 24'h0000FF ;
always@(posedge pixel_clk or negedge sys_rst_n)
begin
if(sys_rst_n == 0)
begin
cnt <= 0 ;
end
else if(cnt < CLK10)
cnt <= cnt + 1 ;
else
cnt <= 0 ;
end
assign moveon = (cnt == CLK10 - 1'b1 ) ? 1 : 0 ;
always@(posedge pixel_clk or negedge sys_rst_n)
begin
if(sys_rst_n == 0)
begin
move_right <= 1 ;
move_down <= 1 ;
end
else
begin
if(blockx == WIDTH)
move_right <= 1 ;
else if(blockx == pixelx - WIDTH -WIDTH)
begin
move_right <= 0 ;
end
else
move_right <= move_right ;
if(blocky == WIDTH)
move_down <= 1;
else if(blocky == pixely - WIDTH -WIDTH)
begin
move_down <= 0 ;
end
else
move_down <= move_down ;
end
end
always @(posedge pixel_clk or negedge sys_rst_n ) begin
if (sys_rst_n == 0) begin
blockx <= WIDTH;
blocky <= WIDTH;
end
else if(moveon) begin
if(move_right)
blockx <= blockx + 1'b1;
else
blockx <= blockx - 1'b1;
if(move_down)
blocky <= blocky + 1'b1;
else
blocky <= blocky - 1'b1;
end
else begin
blockx <= blockx;
blocky <= blocky;
end
end
always@(posedge pixel_clk or negedge sys_rst_n) begin
if( sys_rst_n == 0) begin
pixel_data_w <= BLACK ; end
else begin
if( (pixel_xpos_w < WIDTH) || (pixel_xpos_w >= pixelx - WIDTH)
|| (pixel_ypos_w < WIDTH) || (pixel_ypos_w >= pixely - WIDTH))
pixel_data_w <= BLUE;
else
if( (pixel_xpos_w >= blockx) && (pixel_xpos_w < blockx + WIDTH)
&& (pixel_ypos_w >= blocky) && (pixel_ypos_w < blocky + WIDTH))
pixel_data_w <= BLACK;
else
pixel_data_w <= WHITE;
end
end
endmodule
video_driver.v
module video_driver
(
input pixel_clk ,
input rst_n ,
input [ 23 : 0 ] pixel_data ,
output [ 23 : 0 ] video_rgb ,
output video_hs ,
output video_vs ,
output video_de ,
output [ 11 : 0 ] pixel_xpos ,
output [ 11 : 0 ] pixel_ypos
);
parameter H_SYNC = 12'd40;
parameter H_BACK = 12'd220;
parameter H_DISP = 12'd1280;
parameter H_FRONT = 12'd110;
parameter H_TOTAL = 12'd1650;
parameter V_SYNC = 12'd5;
parameter V_BACK = 12'd20;
parameter V_DISP = 12'd720;
parameter V_FRONT = 12'd5;
parameter V_TOTAL = 12'd750;
reg [11 : 0] cnt_h ;
reg [11 : 0] cnt_v ;
wire data_reg ;
always@(posedge pixel_clk or negedge rst_n)
begin
if( rst_n == 0)
begin
cnt_h <= 0 ;
end
else
begin
if(cnt_h == H_TOTAL - 1)
begin
cnt_h <= 0 ;
end
else
cnt_h <= cnt_h + 1 ;
end
end
always@(posedge pixel_clk or negedge rst_n)
begin
if( rst_n == 0)
begin
cnt_v = 0 ;
end
else
begin
if( cnt_h == H_TOTAL - 1)
begin
if(cnt_v == V_TOTAL - 1)
begin
cnt_v <= 0 ;
end
else
begin
cnt_v <= cnt_v + 1 ;
end
end
end
end
assign video_hs = 1 ;
assign video_vs = 1 ;
assign video_rgb = video_de ? pixel_data : 24'b0 ;
assign video_de = (((cnt_h >= H_SYNC+H_BACK) && (cnt_h < H_SYNC+H_BACK+H_DISP))
&&((cnt_v >= V_SYNC+V_BACK) && (cnt_v < V_SYNC+V_BACK+V_DISP)))
? 1'b1 : 1'b0;
assign data_reg = (((cnt_h >= H_SYNC+H_BACK - 1) && (cnt_h < H_SYNC+H_BACK+H_DISP - 1))
&&((cnt_v >= V_SYNC+V_BACK) && (cnt_v < V_SYNC+V_BACK+V_DISP)))
? 1'b1 : 1'b0;
assign pixel_xpos = data_reg ? (cnt_h - (H_SYNC + H_BACK - 1'b1)) : 0;
assign pixel_ypos = data_reg ? (cnt_v - (V_SYNC + V_BACK - 1'b1)) : 0;
endmodule