【【RTC实时时钟实验 -- 在HDMI上显示-FPGA 小实验】】
RTC实时时钟实验 – 在HDMI上显示
top.v
module RTS_TOP#(parameter TIME_INIT = 48'h24_01_06_11_08_00 ,parameter WAIT_TIME = 13'd8000 ,parameter SLAVE_ADDR = 7'b1010001 , // E2PROM 浠庢満鍦板潃parameter CLK_FREQ = 26'd50_000_000 , // 50MHz 鐨勬椂閽熼锟�?parameter I2C_FREQ = 18'd250_000 // SCL 鐨勬椂閽熼锟�?
)(input sys_clk ,input rst_n ,// to HDMI output tmds_clk_p , // TMDS 鏃堕挓閫氶亾output tmds_clk_n ,output [2:0] tmds_data_p , // TMDS 鏁版嵁閫氶亾output [2:0] tmds_data_n ,// I2C 閫氶亾output scl ,inout sda
);
//-----------------------------------------------------
//-----------------------------------------------------
// next is wire and reg define wire [15 : 0] i2c_addr ;
wire [7 : 0] i2c_data_w ;
wire i2c_rh_wl ;
wire i2c_exec ;
wire dri_clk ;
wire [7 : 0] i2c_data_r ;
wire i2c_ack ;
wire i2c_done ;wire [7 : 0 ] sec ;
wire [7 : 0 ] min ;
wire [7 : 0 ] hour ;
wire [7 : 0 ] day ;
wire [7 : 0 ] mon ;
wire [7 : 0 ] year ; //--------------------------------------------------------
//--------------------------------------------------------IIC_CONTROL#(.SLAVE_ADDR ( 7'b1010001 ),.CLK_FREQ ( 26'd50_000_000 ),.I2C_FREQ ( 18'd250_000 )
)u_IIC_CONTROL(.clk ( sys_clk ),.rst_n ( rst_n ),.i2c_addr ( i2c_addr ),.i2c_data_w ( i2c_data_w ),.i2c_rh_wl ( i2c_rh_wl ),.bit_control ( 0 ),.i2c_exec ( i2c_exec ),.dri_clk ( dri_clk ),.i2c_data_r ( i2c_data_r ),.i2c_ack ( i2c_ack ),.i2c_done ( i2c_done ),.scl ( scl ),.sda ( sda )
);PCF8563#(.TIME_INIT ( TIME_INIT ),.WAIT_TIME ( WAIT_TIME )
)u_PCF8563(.clk ( dri_clk ),.rst_n ( rst_n ),.i2c_done ( i2c_done ),.i2c_data_r ( i2c_data_r ),.i2c_rh_wl ( i2c_rh_wl ),.i2c_exec ( i2c_exec ),.i2c_addr ( i2c_addr ),.i2c_data_w ( i2c_data_w ),.sec ( sec ),.min ( min ),.hour ( hour ),.day ( day ),.mon ( mon ),.year ( year )
);hdmi_top u_hdmi_top(.sys_clk ( sys_clk ),.sys_rst_n ( rst_n ),.tmds_clk_p ( tmds_clk_p ),.tmds_clk_n ( tmds_clk_n ),.tmds_data_p ( tmds_data_p ),.tmds_data_n ( tmds_data_n ),.sec ( sec ),.min ( min ),.hour ( hour ),.day ( day ),.mon ( mon ),.year ( year )
);endmodule
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 ; // next is define
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") // I/O电平标准为TMDS
) TMDS0 (.I (tmds_data_serial[0]),.O (tmds_data_p[0]),.OB (tmds_data_n[0])
);OBUFDS #(.IOSTANDARD ("TMDS_33") // I/O电平标准为TMDS
) TMDS1 (.I (tmds_data_serial[1]),.O (tmds_data_p[1]),.OB (tmds_data_n[1])
);OBUFDS #(.IOSTANDARD ("TMDS_33") // I/O电平标准为TMDS
) TMDS2 (.I (tmds_data_serial[2]), .O (tmds_data_p[2]), .OB (tmds_data_n[2])
);OBUFDS #(.IOSTANDARD ("TMDS_33") // I/O电平标准为TMDS
) TMDS3 (.I (tmds_clk_serial), .O (tmds_clk_p),.OB (tmds_clk_n)
);
endmodule
encoder.v
module dvi_encoder (input clkin, // pixel clock inputinput rstin, // async. reset input (active high)input [7:0] din, // data inputs: expect registeredinput c0, // c0 inputinput c1, // c1 inputinput de, // de inputoutput reg [9:0] dout // data outputs
);// Counting number of 1s and 0s for each incoming pixel// component. Pipe line the result.// Register Data Input so it matches the pipe lined adder// outputreg [3:0] n1d; //number of 1s in dinreg [7:0] din_q;//计算像素数据中“1”的个数always @ (posedge clkin) beginn1d <=#1 din[0] + din[1] + din[2] + din[3] + din[4] + din[5] + din[6] + din[7];din_q <=#1 din;end///// Stage 1: 8 bit -> 9 bit// Refer to DVI 1.0 Specification, page 29, Figure 3-5///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;/// Stage 2: 9 bit -> 10 bit// Refer to DVI 1.0 Specification, page 29, Figure 3-5/reg [3:0] n1q_m, n0q_m; // number of 1s and 0s for q_malways @ (posedge clkin) beginn1q_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]);endparameter CTRLTOKEN0 = 10'b1101010100;parameter CTRLTOKEN1 = 10'b0010101011;parameter CTRLTOKEN2 = 10'b0101010100;parameter CTRLTOKEN3 = 10'b1010101011;reg [4:0] cnt; //disparity counter, MSB is the sign bitwire decision2, decision3;assign decision2 = (cnt == 5'h0) | (n1q_m == n0q_m);/// [(cnt > 0) and (N1q_m > N0q_m)] or [(cnt < 0) and (N0q_m > N1q_m)]/assign decision3 = (~cnt[4] & (n1q_m > n0q_m)) | (cnt[4] & (n0q_m > n1q_m));// pipe line alignmentreg de_q, de_reg;reg c0_q, c1_q;reg c0_reg, c1_reg;reg [8:0] q_m_reg;always @ (posedge clkin) beginde_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///// 10-bit out// disparity counter///always @ (posedge clkin or posedge rstin) beginif(rstin) begindout <= 10'h0;cnt <= 5'h0;end else beginif (de_reg) beginif(decision2) begindout[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 beginif(decision3) begindout[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 begindout[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);endendend else begincase ({c1_reg, c0_reg})2'b00: dout <=#1 CTRLTOKEN0;2'b01: dout <=#1 CTRLTOKEN1;2'b10: dout <=#1 CTRLTOKEN2;default: dout <=#1 CTRLTOKEN3;endcasecnt <=#1 5'h0;endendendendmodule
hdmi_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 ,// displayinput [ 7 : 0] sec ,input [ 7 : 0] min ,input [ 7 : 0] hour ,input [ 7 : 0] day ,input [ 7 : 0] mon ,input [ 7 : 0] year);// 我不想显示年月日?? 直接存起??wire [7 : 0] year1 ;wire [7 : 0] mon1 ;wire [7 : 0] day1 ;assign day1 = day ;assign year1 = year ;assign mon1 = mon ;// 暂存起来//parameter definelocalparam CHAR_X_START = 11'd50; //字符起始点横坐标localparam CHAR_Y_START = 11'd100; //字符起始点纵坐标localparam CHAR_WIDTH = 10'd88; //字符宽度 32*11 = 352localparam CHAR_HEIGHT = 10'd16; //字符高度//棰滆??localparam BACK_COLOR = 24'hE0FFFF; //背景色,浅蓝??localparam CHAR_COLOR = 24'hff0000; //字符颜色,红??reg [127:0] char[10:0]; //字符数组// 这里是字符的显示 我想做的??//----------------------// 09 : 20 00// 两个+空格+冒号+空格+两个+空格+空格+两个 11??//////----------------------always @(posedge pixel_clk)beginchar[0] = 128'h00000018244242424242424224180000;/*"0",0*/char[1] = 128'h000000083808080808080808083E0000;/*"1",1*/char[2] = 128'h0000003C4242420204081020427E0000;/*"2",2*/char[3] = 128'h0000003C4242020418040242423C0000;/*"3",3*/char[4] = 128'h000000040C0C142424447F04041F0000;/*"4",4*/char[5] = 128'h0000007E404040784402024244380000;/*"5",5*/char[6] = 128'h000000182440405C62424242221C0000;/*"6",6*/char[7] = 128'h0000007E420404080810101010100000;/*"7",7*/char[8] = 128'h0000003C4242422418244242423C0000;/*"8",8*/char[9] = 128'h0000003844424242463A020224180000;/*"9",9*/char[10] = 128'h00000000000018180000000018180000;/*":",10*/end// 准备显示always@( posedge pixel_clk or negedge sys_rst_n)beginif( sys_rst_n == 0)beginpixel_data_w <=BACK_COLOR ;endelse// //09 : 20 00// 两个+空格+冒号+空格+两个+空格+空格+两个 11??// 小时的十??if( (pixel_xpos_w >= CHAR_X_START + CHAR_WIDTH/11*0)&& (pixel_xpos_w < CHAR_X_START + CHAR_WIDTH/11*1)&& (pixel_ypos_w >= CHAR_Y_START)&& (pixel_ypos_w < CHAR_Y_START + CHAR_HEIGHT) )beginif( char[hour[7 : 4]][ (CHAR_HEIGHT + CHAR_Y_START - pixel_ypos_w) * 8-((pixel_xpos_w - (CHAR_X_START)) % 8) -1 ] )pixel_data_w <=CHAR_COLOR ;elsepixel_data_w <=BACK_COLOR ;end// 小时的个??else if( (pixel_xpos_w >= CHAR_X_START + CHAR_WIDTH/11*1)&& (pixel_xpos_w < CHAR_X_START + CHAR_WIDTH/11*2)&& (pixel_ypos_w >= CHAR_Y_START)&& (pixel_ypos_w < CHAR_Y_START + CHAR_HEIGHT) )beginif( char[hour[3 : 0]][ (CHAR_HEIGHT + CHAR_Y_START - pixel_ypos_w) * 8-((pixel_xpos_w - (CHAR_X_START)) % 8) -1 ] )pixel_data_w <=CHAR_COLOR ;elsepixel_data_w <=BACK_COLOR ;end// 空格else if( (pixel_xpos_w >= CHAR_X_START + CHAR_WIDTH/11*2)&& (pixel_xpos_w < CHAR_X_START + CHAR_WIDTH/11*3)&& (pixel_ypos_w >= CHAR_Y_START)&& (pixel_ypos_w < CHAR_Y_START + CHAR_HEIGHT) )beginpixel_data_w <=BACK_COLOR ;end// 冒号else if( (pixel_xpos_w >= CHAR_X_START + CHAR_WIDTH/11*3)&& (pixel_xpos_w < CHAR_X_START + CHAR_WIDTH/11*4)&& (pixel_ypos_w >= CHAR_Y_START)&& (pixel_ypos_w < CHAR_Y_START + CHAR_HEIGHT) )beginif( char[10][ (CHAR_HEIGHT + CHAR_Y_START - pixel_ypos_w) * 8-((pixel_xpos_w - (CHAR_X_START)) % 8) -1 ] )pixel_data_w <=CHAR_COLOR ;elsepixel_data_w <=BACK_COLOR ;end// 空格else if( (pixel_xpos_w >= CHAR_X_START + CHAR_WIDTH/11*4)&& (pixel_xpos_w < CHAR_X_START + CHAR_WIDTH/11*5)&& (pixel_ypos_w >= CHAR_Y_START)&& (pixel_ypos_w < CHAR_Y_START + CHAR_HEIGHT) )beginpixel_data_w <=BACK_COLOR ;end// 分钟的十??else if( (pixel_xpos_w >= CHAR_X_START + CHAR_WIDTH/11*5)&& (pixel_xpos_w < CHAR_X_START + CHAR_WIDTH/11*6)&& (pixel_ypos_w >= CHAR_Y_START)&& (pixel_ypos_w < CHAR_Y_START + CHAR_HEIGHT) )beginif( char[min[7 : 4]][ (CHAR_HEIGHT + CHAR_Y_START - pixel_ypos_w) * 8-((pixel_xpos_w - (CHAR_X_START)) % 8) -1 ] )pixel_data_w <=CHAR_COLOR ;elsepixel_data_w <=BACK_COLOR ;end// 分钟的个??else if( (pixel_xpos_w >= CHAR_X_START + CHAR_WIDTH/11*6)&& (pixel_xpos_w < CHAR_X_START + CHAR_WIDTH/11*7)&& (pixel_ypos_w >= CHAR_Y_START)&& (pixel_ypos_w < CHAR_Y_START + CHAR_HEIGHT) )beginif( char[min[3 : 0]][ (CHAR_HEIGHT + CHAR_Y_START - pixel_ypos_w) * 8-((pixel_xpos_w - (CHAR_X_START)) % 8) -1 ] )pixel_data_w <=CHAR_COLOR ;elsepixel_data_w <=BACK_COLOR ;end//空格// 空格else if( (pixel_xpos_w >= CHAR_X_START + CHAR_WIDTH/11*7)&& (pixel_xpos_w < CHAR_X_START + CHAR_WIDTH/11*8)&& (pixel_ypos_w >= CHAR_Y_START)&& (pixel_ypos_w < CHAR_Y_START + CHAR_HEIGHT) )beginpixel_data_w <=BACK_COLOR ;end// 空格else if( (pixel_xpos_w >= CHAR_X_START + CHAR_WIDTH/11*8)&& (pixel_xpos_w < CHAR_X_START + CHAR_WIDTH/11*9)&& (pixel_ypos_w >= CHAR_Y_START)&& (pixel_ypos_w < CHAR_Y_START + CHAR_HEIGHT) )beginpixel_data_w <=BACK_COLOR ;end// 秒的十位else if( (pixel_xpos_w >= CHAR_X_START + CHAR_WIDTH/11*9)&& (pixel_xpos_w < CHAR_X_START + CHAR_WIDTH/11*10)&& (pixel_ypos_w >= CHAR_Y_START)&& (pixel_ypos_w < CHAR_Y_START + CHAR_HEIGHT) )beginif( char[sec[7 : 4]][ (CHAR_HEIGHT + CHAR_Y_START - pixel_ypos_w) * 8-((pixel_xpos_w - (CHAR_X_START)) % 8) -1 ] )pixel_data_w <=CHAR_COLOR ;elsepixel_data_w <=BACK_COLOR ;end// 分钟的个??else if( (pixel_xpos_w >= CHAR_X_START + CHAR_WIDTH/11*10)&& (pixel_xpos_w < CHAR_X_START + CHAR_WIDTH/11*11)&& (pixel_ypos_w >= CHAR_Y_START)&& (pixel_ypos_w < CHAR_Y_START + CHAR_HEIGHT) )beginif( char[sec[3 : 0]][ (CHAR_HEIGHT + CHAR_Y_START - pixel_ypos_w) * 8-((pixel_xpos_w - (CHAR_X_START)) % 8) -1 ] )pixel_data_w <=CHAR_COLOR ;elsepixel_data_w <=BACK_COLOR ;endelsebeginpixel_data_w <= BACK_COLOR; //屏幕背景为白??endendendmodule
HDMI_top.v
module hdmi_top(input sys_clk,input sys_rst_n,output tmds_clk_p, // TMDS 时钟通道output tmds_clk_n,output [2:0] tmds_data_p, // TMDS 数据通道output [2:0] tmds_data_n ,// next is from PCF
input [ 7 : 0] sec ,
input [ 7 : 0] min ,
input [ 7 : 0] hour ,
input [ 7 : 0] day ,
input [ 7 : 0] mon ,
input [ 7 : 0] year);//wire definewire 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;// next is main codeclk_wiz_0 instance_name1(// Clock out ports.clk_out1(pixel_clk), // output clk_out1.clk_out2(pixel_clk_5x), // output clk_out2// Status and control signals.reset(~sys_rst_n), // input reset.locked(clk_locked), // output locked// Clock in ports.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 ),.sec ( sec ),.min ( min ),.hour ( hour ),.day ( day ),.mon ( mon ),.year ( year )
);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
I2c_dri.v
module IIC_CONTROL #(parameter SLAVE_ADDR = 7'b1010001 , // E2PROM 从机地址parameter CLK_FREQ = 26'd50_000_000 , // 50MHz 的时钟频率parameter I2C_FREQ = 18'd250_000 // SCL 的时钟频率)(input clk ,input rst_n ,// ---------------------------------------------- //input [15 : 0] i2c_addr , // 地址input [7 : 0] i2c_data_w , // 数据input i2c_rh_wl , // 判断 是 read or writeinput bit_control , // 1是 16位 0 是 8位input i2c_exec ,// ------------------------------------------------ //output reg dri_clk ,output reg [7 : 0] i2c_data_r ,output reg i2c_ack ,output reg i2c_done ,// -------------------------------------------------- //output reg scl ,inout sda);// --------------------------------------------------------//// next is define //// --------------------------------------------------------//reg [9 : 0] clk_cnt ;wire [8 : 0] dri_cnt ;reg [2 : 0] state ;reg [2 : 0] next_state ;reg st_done ; // 在 状态机里面用来提示数据完成可以跳转reg sda_dir ; // sda方向控制器reg sda_out ; // 选择FPGA输入模式之后赋予sda线上wire sda_in ; // sda输入信号reg [6 : 0] cnt ; // 我们为了第三部分状态机而准备的reg [15: 0] addr_save ; // 地址存储reg [7 : 0] data_w_save ; // 数据写的暂存reg wr_flag ; // 0 是 写 1 是 读// 这三个是 暂存的方便调度的reg [7 : 0] data_r_save ; // 读到的数据存储方便整合// --------------------------------------------------------- //// parameter define //parameter st_idle = 3'b000 ; // 空闲状态parameter st_sladdr = 3'b001 ; // 发送器件地址parameter st_addr16 = 3'b010 ; // 发送高八位地址parameter st_addr8 = 3'b011 ; // 发送低八位地址parameter st_data_wr = 3'b100 ; // 写数据parameter st_addr_rd = 3'b101 ; // 再次发送器件地址读parameter st_data_rd = 3'b110 ; // 读数据parameter st_stop = 3'b111 ; // 结束操作停止位// ---------------------------------------------------- //// next is main code //// -------------------------------------------------------//assign dri_cnt = (CLK_FREQ/I2C_FREQ ) >> 2 ;always@(posedge clk or negedge rst_n )beginif(rst_n == 0)begindri_clk <= 0 ;clk_cnt <= 0 ;endelse if( clk_cnt == dri_cnt[8:1] - 1)beginclk_cnt <= 0 ;dri_clk <= ~dri_clk ;endelsebegindri_clk <= dri_clk ;clk_cnt <= clk_cnt + 1 ;endend// 下面开始状态机的叙述// 同步时序描述状态转移always@(posedge dri_clk or negedge rst_n)beginif(rst_n == 0)beginstate <= st_idle ;end // 处于空闲状态elsebeginstate <= next_state ;endend// 组合逻辑判断状态转移条件always@(*)beginnext_state <= st_idle ;case(state)st_idle :beginif(i2c_exec == 1)beginnext_state <= st_sladdr ;endelsebeginnext_state <= st_idle ;endend// 当触发了i2c_exec 时候 可以由 空闲状态转移到st_sladdr :beginif(st_done == 1)beginif(bit_control == 1)next_state <= st_addr16 ;elsenext_state <= st_addr8 ;endelsebeginnext_state <= st_sladdr ;endend// 当 触发了 st_done 之后 通过 bit_control 选择是低八位 还是高八位的传输st_addr16 :beginif(st_done == 1)beginnext_state <= st_addr8 ;endelsebeginnext_state <= st_addr16 ;endend// 高位 用完 轮到 低位的 传输st_addr8 :beginif(st_done == 1)beginif(wr_flag == 0)next_state <= st_data_wr ;elsenext_state <= st_addr_rd ;endelsebeginnext_state <= st_addr8 ;endend// 先来判断 写数据的 st_data_wr 数据代号是 4st_data_wr :beginif(st_done == 1)beginnext_state <= st_stop ;endelsebeginnext_state <= st_data_wr ;endend//st_addr_rd :beginif(st_done == 1)beginnext_state <= st_data_rd ;endelsebeginnext_state <= st_addr_rd ;endend//st_data_rd :beginif(st_done == 1)beginnext_state <= st_stop ;endelsebeginnext_state <= st_data_rd ;endend//st_stop :beginif(st_done == 1)beginnext_state <= st_idle ;endelsebeginnext_state <= st_stop ;endenddefault:next_state <= st_idle ;endcaseend/ 下面来考虑另一个状态机的第三部分 --- 时序电路描述状态输出// 设置一个变量 来控制 SDA的朝向assign sda = sda_dir ? sda_out : 1'bz ; // sda_dir 为1 FPGA控制assign sda_in = sda ; // 把sda当成了输出always@(posedge dri_clk or negedge rst_n )beginif( rst_n == 0)begin//首先根据输入输出 来判断 SCL 与 SDA 必须都为高scl <= 1 ;sda_dir <= 1 ;sda_out <= 1 ;// 剩下的输出 i2c_data_r(输出) == data_r_savei2c_data_r <= 0 ;data_r_save <= 0 ;// 下面是端口的另外两个输出 i2c_ack 和 i2c_donei2c_ack <= 0 ;i2c_done <= 0 ;// 接下里是 内部信号的调节 这两个一个是内部后续的计数 还有一个本次case完成的结束信号cnt <= 0 ;st_done <= 0 ;// 下面是三个暂存信号一个是 读写标志位 还有 传入的地址暂存 传入的数据暂存wr_flag <= 0 ;addr_save <= 0 ;data_w_save <= 0 ;endelsebeginst_done <= 0 ; // 脉冲信号cnt <= cnt + 1 ;//这里写在了 case之前就代表了 不用刻意在内部去调配 st_done 或是cntcase(state)st_idle :beginscl <= 1 ;sda_dir <= 1 ;sda_out <= 1 ;//这两个写不写不所谓 因为根本没用到i2c_data_r <= 0 ;data_r_save <= 0 ;i2c_done <= 0 ;//cnt <= 0 ;st_done <= 0 ;// 开始if( i2c_exec == 1) beginwr_flag <= i2c_rh_wl ;addr_save <= i2c_addr ;data_w_save <= i2c_data_w ;i2c_ack <= 0 ;endend// 这里先传递的是st_sladdr :begincase(cnt)7'd1 :sda_out <= 0 ;7'd3 :scl <= 0 ;7'd4 :sda_out <= SLAVE_ADDR[6] ;7'd5 :scl <= 1'b1 ;7'd7 :scl <= 1'b0 ;7'd8 :sda_out <= SLAVE_ADDR[5] ;7'd9 :scl <= 1'b1 ;7'd11 :scl <= 1'b0 ;7'd12 :sda_out <= SLAVE_ADDR[4] ;7'd13 :scl <= 1'b1 ;7'd15 :scl <= 1'b0 ;7'd16 :sda_out <= SLAVE_ADDR[3] ;7'd17 :scl <= 1'b1 ;7'd19 :scl <= 1'b0 ;7'd20 :sda_out <= SLAVE_ADDR[2] ;7'd21 :scl <= 1'b1 ;7'd23 :scl <= 1'b0 ;7'd24 :sda_out <= SLAVE_ADDR[1] ;7'd25 :scl <= 1'b1 ;7'd27 :scl <= 1'b0 ;7'd28 :sda_out <= SLAVE_ADDR[0] ;7'd29 :scl <= 1'b1 ;7'd31 :scl <= 1'b0 ;7'd32 :sda_out <= 1'b0 ;// 此处完成了 数据的传递 接下来的任务是 反馈7'd33 :scl <= 1'b1 ;7'd35 :scl <= 1'b0 ;7'd36 :sda_dir <= 1'b0 ; // 下放控制权给从机端口7'd37 :scl <= 1'b1 ;// 下一时刻判断是否 有正确的反馈拉低 并确定 st_done = 17'd38 :beginst_done <= 1'b1 ;if( sda_in == 1)i2c_ack <= 1'b1 ;end7'd39 :beginscl <= 1'b0 ;cnt <= 7'b0 ;enddefault :;endcaseend//发送高8位字节st_addr16 :begincase(cnt)7'd0 :begin // 39之后移动一格就是0 0 此处即可以开始//把使能交还给FPGA端sda_dir <= 1'b1 ;sda_out <= addr_save[15] ;end// 第一个转换有点时序差距 后面都是 每隔4 sda变化一次7'd1 :scl <= 1'b1 ;7'd3 :scl <= 1'b0 ;7'd4 :sda_out <= addr_save[14] ;7'd5 :scl <= 1'b1 ;7'd7 :scl <= 1'b0 ;7'd8 :sda_out <= addr_save[13] ;7'd9 :scl <= 1'b1 ;7'd11 :scl <= 1'b0 ;7'd12 :sda_out <= addr_save[12] ;7'd13 :scl <= 1'b1 ;7'd15 :scl <= 1'b0 ;7'd16 :sda_out <= addr_save[11] ;7'd17 :scl <= 1'b1 ;7'd19 :scl <= 1'b0 ;7'd20 :sda_out <= addr_save[10] ;7'd21 :scl <= 1'b1 ;7'd23 :scl <= 1'b0 ;7'd24 :sda_out <= addr_save[9] ;7'd25 :scl <= 1'b1 ;7'd27 :scl <= 1'b0 ;7'd28 :sda_out <= addr_save[8] ;// 29 拉升 31下降 32放控制权 33拉升 34结束并作判断 35 拉低 cnt归零为下一状态准备7'd29 :scl <= 1'b1 ;7'd31 :scl <= 1'b0 ;7'd32 :sda_dir <= 1'b0 ;7'd33 :scl <= 1'b1 ;7'd34 :beginst_done <= 1'b1 ; //完成if(sda_in == 1)i2c_ack <= 1'b1 ; // scl拉高时 反馈 i2c_ack = 1 表示有错误end7'd35 :beginscl <= 1'b0 ;cnt <= 7'b0 ;enddefault :;endcaseend//发送低8位字节st_addr8 :begin// 和上面这个写法是一样的 对于cnt = 0 sda_dir 交回FPGA控制权 并立刻赋值case(cnt)7'd0:beginsda_dir <= 1'b1 ;sda_out <= addr_save[7]; //字地址end7'd1 :scl <= 1'b1;7'd3 :scl <= 1'b0;7'd4 :sda_out <= addr_save[6];7'd5 :scl <= 1'b1;7'd7 :scl <= 1'b0;7'd8 :sda_out <= addr_save[5];7'd9 :scl <= 1'b1;7'd11 :scl <= 1'b0;7'd12 :sda_out <= addr_save[4];7'd13 :scl <= 1'b1;7'd15 :scl <= 1'b0;7'd16 :sda_out <= addr_save[3];7'd17 :scl <= 1'b1;7'd19 :scl <= 1'b0;7'd20 :sda_out <= addr_save[2];7'd21 :scl <= 1'b1;7'd23 :scl <= 1'b0;7'd24 :sda_out <= addr_save[1];7'd25 :scl <= 1'b1;7'd27 :scl <= 1'b0;7'd28 :sda_out <= addr_save[0];7'd29 :scl <= 1'b1 ;7'd31 :scl <= 1'b0 ;7'd32 :sda_dir <= 1'b0 ;7'd33 :scl <= 1'b1 ;7'd34 :beginst_done <= 1'b1 ; //完成if(sda_in == 1)i2c_ack <= 1'b1 ; // scl拉高时 反馈 i2c_ack = 1 表示有错误end7'd35 :beginscl <= 1'b0 ;cnt <= 7'b0 ;enddefault :;endcaseend//st_data_wr :begin// 和上面这个写法是一样的 对于cnt = 0 sda_dir 交回FPGA控制权 并立刻赋值case(cnt)7'd0:beginsda_dir <= 1'b1 ;sda_out <= data_w_save[7]; //字地址end7'd1 :scl <= 1'b1;7'd3 :scl <= 1'b0;7'd4 :sda_out <= data_w_save[6];7'd5 :scl <= 1'b1;7'd7 :scl <= 1'b0;7'd8 :sda_out <= data_w_save[5];7'd9 :scl <= 1'b1;7'd11 :scl <= 1'b0;7'd12 :sda_out <= data_w_save[4];7'd13 :scl <= 1'b1;7'd15 :scl <= 1'b0;7'd16 :sda_out <= data_w_save[3];7'd17 :scl <= 1'b1;7'd19 :scl <= 1'b0;7'd20 :sda_out <= data_w_save[2];7'd21 :scl <= 1'b1;7'd23 :scl <= 1'b0;7'd24 :sda_out <= data_w_save[1];7'd25 :scl <= 1'b1;7'd27 :scl <= 1'b0;7'd28 :sda_out <= data_w_save[0];// 29 拉升 31下降 32放控制权 33拉升 34结束并作判断 35 拉低 cnt归零为下一状态准备7'd29 :scl <= 1'b1 ;7'd31 :scl <= 1'b0 ;7'd32 :sda_dir <= 1'b0 ;7'd33 :scl <= 1'b1 ;7'd34 :beginst_done <= 1'b1 ; //完成if(sda_in == 1)i2c_ack <= 1'b1 ; // scl拉高时 反馈 i2c_ack = 1 表示有错误end7'd35 :beginscl <= 1'b0 ;cnt <= 7'b0 ;enddefault :;endcaseend// 读控制信号 可以开始读了st_addr_rd :begin// 这里的过程应该和上面的那个 st_sladdr一样 先写地址// 一样又不太一样case(cnt)7'd0 :beginsda_dir <= 1'b1;sda_out <= 1'b1;end7'd1 :scl <= 1'b1;7'd2 :sda_out <= 1'b0; //重新开始7'd3 :scl <= 1'b0;7'd4 :sda_out <= SLAVE_ADDR[6]; //传送器件地址7'd5 :scl <= 1'b1;7'd7 :scl <= 1'b0;7'd8 :sda_out <= SLAVE_ADDR[5];7'd9 :scl <= 1'b1;7'd11:scl <= 1'b0;7'd12:sda_out <= SLAVE_ADDR[4];7'd13:scl <= 1'b1;7'd15:scl <= 1'b0;7'd16:sda_out <= SLAVE_ADDR[3];7'd17:scl <= 1'b1;7'd19:scl <= 1'b0;7'd20:sda_out <= SLAVE_ADDR[2];7'd21:scl <= 1'b1;7'd23:scl <= 1'b0;7'd24:sda_out <= SLAVE_ADDR[1];7'd25:scl <= 1'b1;7'd27:scl <= 1'b0;7'd28:sda_out <= SLAVE_ADDR[0];7'd29:scl <= 1'b1;7'd31:scl <= 1'b0;7'd32:sda_out <= 1'b1; //1:读7'd33:scl <= 1'b1;7'd35:scl <= 1'b0;7'd36:beginsda_dir <= 1'b0;sda_out <= 1'b1;end7'd37:scl <= 1'b1;7'd38:begin //从机应答st_done <= 1'b1;if(sda_in == 1'b1) //高电平表示未应答i2c_ack <= 1'b1; //拉高应答标志位end7'd39:beginscl <= 1'b0;cnt <= 7'b0;enddefault :;endcaseendst_data_rd :begin //读取数据(8 bit)case(cnt)7'd0:sda_dir <= 1'b0;7'd1:begindata_r_save[7] <= sda_in;scl <= 1'b1;end7'd3:scl <= 1'b0;7'd5:begindata_r_save[6] <= sda_in ;scl <= 1'b1 ;end7'd7:scl <= 1'b0;7'd9:begindata_r_save[5] <= sda_in;scl <= 1'b1 ;end7'd11:scl <= 1'b0;7'd13:begindata_r_save[4] <= sda_in;scl <= 1'b1 ;end7'd15:scl <= 1'b0;7'd17:begindata_r_save[3] <= sda_in;scl <= 1'b1 ;end7'd19:scl <= 1'b0;7'd21:begindata_r_save[2] <= sda_in;scl <= 1'b1 ;end7'd23:scl <= 1'b0;7'd25:begindata_r_save[1] <= sda_in;scl <= 1'b1 ;end7'd27:scl <= 1'b0;7'd29:begindata_r_save[0] <= sda_in;scl <= 1'b1 ;end7'd31:scl <= 1'b0;7'd32:beginsda_dir <= 1'b1;sda_out <= 1'b1;end7'd33:scl <= 1'b1;7'd34:st_done <= 1'b1; //非应答7'd35:beginscl <= 1'b0;cnt <= 7'b0;i2c_data_r <= data_r_save;enddefault :;endcaseendst_stop:begin //结束I2C操作case(cnt)7'd0:beginsda_dir <= 1'b1; //结束I2Csda_out <= 1'b0;end7'd1 :scl <= 1'b1;7'd3 :sda_out <= 1'b1;7'd15:st_done <= 1'b1;7'd16:begincnt <= 7'b0;i2c_done <= 1'b1; //向上层模块传递I2C结束信号enddefault :;endcaseendendcaseendendendmodule
PCF8563.v
module PCF8563#(parameter TIME_INIT = 48'h24_01_06_14_30_00 ,parameter WAIT_TIME = 13'd8000)(input clk ,input rst_n ,input i2c_done ,input [7 : 0] i2c_data_r , // this thing from i2c to HDMI//output reg i2c_rh_wl ,output reg i2c_exec ,output reg [15 : 0] i2c_addr ,output reg [ 7 : 0] i2c_data_w , // this is give to i2c//output reg [ 7 : 0] sec ,output reg [ 7 : 0] min ,output reg [ 7 : 0] hour ,output reg [ 7 : 0] day ,output reg [ 7 : 0] mon ,output reg [ 7 : 0] year);// parameter and definereg [3 : 0] reg_cnt ;reg [12 : 0] wait_cnt ;//always@(posedge clk or negedge rst_n)beginif(rst_n == 0 )begini2c_rh_wl <= 0 ;i2c_exec <= 0 ;i2c_addr <= 0 ;i2c_data_w <= 0 ;sec <= 0 ;min <= 0 ;hour <= 0 ;day <= 0 ;mon <= 0 ;year <= 0 ;reg_cnt <= 0 ;wait_cnt <= 0 ;endelsebegini2c_exec <= 0 ;case(reg_cnt)4'd0 :begin // ��???i2c_exec <= 0 ;if(wait_cnt == WAIT_TIME )beginwait_cnt <= 0 ;reg_cnt <= reg_cnt +1 ;endelsewait_cnt <= wait_cnt + 1 ;end//---------------------------------------------------------------------4'd1 :begin // ?? ??i2c_exec <= 1 ;i2c_addr <= 8'h02 ;reg_cnt <= reg_cnt + 1 ;i2c_data_w <= TIME_INIT[7 : 0] ;end4'd2 :begin // ?? ??if(i2c_done == 1)beginsec <= i2c_data_r[6 : 0] ;reg_cnt <= reg_cnt + 1 ;endend//--------------------------------------------------------------------------4'd3 : // ?? ����begini2c_exec <= 1 ;i2c_addr <= 8'h03 ;reg_cnt <= reg_cnt + 1 ;i2c_data_w <= TIME_INIT[15: 8] ;end4'd4 : // ?? ����begin //if(i2c_done == 1)beginmin <= i2c_data_r[6 : 0] ;reg_cnt <= reg_cnt + 1 ;endend//---------------------------------------------------------------4'd5 : // ?? Сʱbegini2c_exec <= 1 ;i2c_addr <= 8'h04 ;reg_cnt <= reg_cnt + 1 ;i2c_data_w <= TIME_INIT[23: 16] ;end4'd6 : // ?? Сʱbegin //if(i2c_done == 1)beginhour <= i2c_data_r[5 : 0] ;reg_cnt <= reg_cnt + 1 ;endend//---------------------------------------------------------------4'd7 : // ?? ??begini2c_exec <= 1 ;i2c_addr <= 8'h05 ;reg_cnt <= reg_cnt + 1 ;i2c_data_w <= TIME_INIT[31: 24] ;end4'd8 : // ?? ??begin //if(i2c_done == 1)beginday <= i2c_data_r[5 : 0] ;reg_cnt <= reg_cnt + 1 ;endend//----------------------------------------------------------------------4'd9 : // ?? ??begini2c_exec <= 1 ;i2c_addr <= 8'h07 ;reg_cnt <= reg_cnt + 1 ;i2c_data_w <= TIME_INIT[39: 32] ;end4'd10 : // ?? ??begin //if(i2c_done == 1)beginmon <= i2c_data_r[4 : 0] ;reg_cnt <= reg_cnt + 1 ;endend//------------------------------------------------------------------------4'd11 : // ?? ??begini2c_exec <= 1 ;i2c_addr <= 8'h08 ;reg_cnt <= reg_cnt + 1 ;i2c_data_w <= TIME_INIT[47: 40] ;end4'd12 : // ?? ??begin //if(i2c_done == 1)beginyear <= i2c_data_r[7 : 0] ;i2c_rh_wl <= 1 ;reg_cnt <= 1 ;endenddefault : reg_cnt <= 0 ;endcaseend
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)beginif( reset_n == 0)beginreset1 <= 1 ;endelsebeginreset1 <= 0 ;reset <= reset1 ;endend
endmodule
serializer.v
module serializer10 (input reset , // 复位,高有效input paralell_clk , // 输入并行数据时钟 input serial_clk_5x , // 输入串行数据时钟input [9 : 0] paralell_data , // 输入并行数据output serial_data_out // 输出串行数据
);//wire definewire cascade1 ; //用于两个 OSERDESE2 级联的信号wire cascade2 ;// 此处的代码 来自 vivado的 原语 和 正点原子的同时调配
// 这是 master接口 OSERDESE2 #(.DATA_RATE_OQ("DDR"), // 设置双倍数据速率.DATA_RATE_TQ("DDR"), // DDR, BUF, SDR.DATA_WIDTH(10), // 输入的并行数据宽度为 10bit// .INIT_OQ(1'b0), // Initial value of OQ output (1'b0,1'b1)// .INIT_TQ(1'b0), // Initial value of TQ output (1'b0,1'b1).SERDES_MODE("MASTER"), // MASTER, SLAVE//.SRVAL_OQ(1'b0), // OQ output value when SR is used (1'b0,1'b1)// .SRVAL_TQ(1'b0), // TQ output value when SR is used (1'b0,1'b1).TBYTE_CTL("FALSE"), // Enable tristate byte operation (FALSE, TRUE).TBYTE_SRC("FALSE"), // Tristate byte source (FALSE, TRUE).TRISTATE_WIDTH(1) // 3-state converter width (1,4))OSERDESE2_MASTER (.OFB(), // 未使用.OQ(serial_data_out), // 串行输出数据// SHIFTOUT1 / SHIFTOUT2: 1-bit (each) output: Data output expansion (1-bit each).SHIFTOUT1(), // SHIFTIN1 用于位宽扩展.SHIFTOUT2(), // SHIFTIN2 用于位宽扩展.TBYTEOUT(), // 未使用.TFB(), // 未使用.TQ(), // 未使用.CLK(serial_clk_5x), // 串行数据时钟,5 倍时钟频率.CLKDIV(paralell_clk), // 并行数据时钟// D1 - D8: 1-bit (each) input: Parallel data inputs (1-bit each).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), // 1-bit input: Output data clock enable.RST(reset), // 1-bit input: Reset// SHIFTIN1 / SHIFTIN2: 1-bit (each) input: Data input expansion (1-bit each).SHIFTIN1(cascade1), // SHIFTIN1 用于位宽扩展.SHIFTIN2(cascade2), // SHIFTIN2 用于位宽扩展// T1 - T4: 1-bit (each) input: Parallel 3-state inputs.T1(1'b0), // 未使用.T2(1'b0), // 未使用.T3(1'b0), // 未使用.T4(1'b0), // 未使用.TBYTEIN(1'b0), // 未使用.TCE(1'b0) // 未使用);// slave接口 OSERDESE2 #(.DATA_RATE_OQ("DDR"), // 设置双倍数据速率.DATA_RATE_TQ("DDR"), // DDR, BUF, SDR.DATA_WIDTH(10), // 输入的并行数据宽度为 10bit// .INIT_OQ(1'b0), // Initial value of OQ output (1'b0,1'b1)// .INIT_TQ(1'b0), // Initial value of TQ output (1'b0,1'b1).SERDES_MODE("SLAVE"), // MASTER, SLAVE//.SRVAL_OQ(1'b0), // OQ output value when SR is used (1'b0,1'b1)// .SRVAL_TQ(1'b0), // TQ output value when SR is used (1'b0,1'b1).TBYTE_CTL("FALSE"), // Enable tristate byte operation (FALSE, TRUE).TBYTE_SRC("FALSE"), // Tristate byte source (FALSE, TRUE).TRISTATE_WIDTH(1) // 3-state converter width (1,4))OSERDESE2_SLAVE (.OFB(), // 未使用.OQ(), // 串行输出数据// SHIFTOUT1 / SHIFTOUT2: 1-bit (each) output: Data output expansion (1-bit each).SHIFTOUT1(cascade1), // SHIFTIN1 用于位宽扩展.SHIFTOUT2(cascade2), // SHIFTIN2 用于位宽扩展.TBYTEOUT(), // 未使用.TFB(), // 未使用.TQ(), // 未使用.CLK(serial_clk_5x), // 串行数据时钟,5 倍时钟频率.CLKDIV(paralell_clk), // 并行数据时钟// D1 - D8: 1-bit (each) input: Parallel data inputs (1-bit each).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), // 1-bit input: Output data clock enable.RST(reset), // 1-bit input: Reset// SHIFTIN1 / SHIFTIN2: 1-bit (each) input: Data input expansion (1-bit each).SHIFTIN1(), // SHIFTIN1 用于位宽扩展.SHIFTIN2(), // SHIFTIN2 用于位宽扩展// T1 - T4: 1-bit (each) input: Parallel 3-state inputs.T1(1'b0), // 未使用.T2(1'b0), // 未使用.T3(1'b0), // 未使用.T4(1'b0), // 未使用.TBYTEIN(1'b0), // 未使用.TCE(1'b0) // 未使用);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 , // 像素点横坐标 1280output [ 11 : 0 ] pixel_ypos // 像素点横坐标 720
);//parameter define//1280*720 分辨率时序参数 时钟频率74.25parameter 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 definereg [11 : 0] cnt_h ;reg [11 : 0] cnt_v ;wire data_reg ; // define// next is main codealways@(posedge pixel_clk or negedge rst_n)beginif( rst_n == 0)begincnt_h <= 0 ;endelsebeginif(cnt_h == H_TOTAL - 1)begincnt_h <= 0 ;endelsecnt_h <= cnt_h + 1 ;endendalways@(posedge pixel_clk or negedge rst_n)beginif( rst_n == 0)begincnt_v = 0 ;endelsebeginif( cnt_h == H_TOTAL - 1)beginif(cnt_v == V_TOTAL - 1)begincnt_v <= 0 ;endelsebegincnt_v <= cnt_v + 1 ;endendendend// =======================main code============\\// video_rgb // video_hs // video_vs // video_de // pixel_xpos// pixel_ypos
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
README.md
## RTC实时时钟实验 -- 在HDMI上显示 ### 将整体设计分为3部分
( HDMI部分 中间模块 IIC 转接口
其实 HDMI的部分 只要在于修改 display 的显示
对于 IIC 转接口 直接使用上一个项目的 示例 )先了解难度最大的中间模块的书写
在第一次上电 将初始值赋予i2c_dri 这是写 部分 接下来都是进入循环的读
其实我觉得他这个思路挺好的 就是记录一个 i2c_done 如果没有接收到done 信号 就一直执行
接收到了这里有一个值得思考的地方为什么正点原子把 i2c_addr,明明是 16位 在赋值的时候只搞8位
难道不会出现问题嘛?可恶!!!在完成中间模块 和 IIC的模块之后
我们接下来考虑的是 HDMI的接口
HDMI 下属又分为几个小的模块 主要修改的
dvi_transmitter_top
encoder
reset_syn
serializer
top // 修改
video_display // 修改
video_driver
相关文章:
【【RTC实时时钟实验 -- 在HDMI上显示-FPGA 小实验】】
RTC实时时钟实验 – 在HDMI上显示 top.v module RTS_TOP#(parameter TIME_INIT 48h24_01_06_11_08_00 ,parameter WAIT_TIME 13d8000 ,parameter SLAVE_ADDR 7b1010001 , // E2PROM 浠庢満鍦板潃parameter CLK_FR…...
Flutter 图片和资源的高效使用指南
文章目录 指定资源什么是 [pubspec.yaml](https://dart.cn/tools/pub/pubspec) 文件 图片图片常用的配置属性加载本地图片通过 pubspec.yml 文件进行配置图片目录使用 Image.asset 小部件加载本地图片 加载网络图片通过 Image.network小部件加载网络图片:使用Image.…...
RedisTemplate 怎么获取到链接信息?怎么获取到所有key?怎么获取指定key?
获取Redis的链接信息: (RedisTemplate<String, ?> redisTemplate) {RedisConnectionFactory connectionFactory redisTemplate.getConnectionFactory();(!(connectionFactory LettuceConnectionFactory)) {System..println();;}LettuceConnectionFactory l…...
【Unity】动态申请权限
1、AndroidManifest.xml在<application></application>内添加一行: <meta-data android:name"unityplayer.SkipPermissionsDialog" android:value"true" /> 作用:屏蔽应用启动时弹出申请权限弹窗(危…...
tp8/6 插件PhpOffice\PhpSpreadsheet导入表格
一、安装 composer require phpoffice/phpspreadsheet 官网:phpoffice/phpspreadsheet - Packagist 二、代码 <?php namespace app\services\upload\model; use app\services\BaseServices; use \PhpOffice\PhpSpreadsheet\Spreadsheet; use \PhpOffice\Php…...
Android studio VideoView 应用设计
一、运行效果: 二、新建empty activity项目: 三、打开activity_main.xml布局文件,添加VideoView: <VideoViewandroid:id="@+id/videoView"android:layout_width="368dp"android:layout_height="573dp"app:layout_constraintBottom_toBot…...
Python基础(十八、文件操作读取)
文章目录 一、open方法二、read和readlines方法三、readline方法四、关闭操作五、with open语句总结 一、open方法 Python 中可以使用 open 方法来打开一个文件,该方法会返回一个文件对象。open 方法的语法如下: file_object open(file_name, mode)其…...
Mac 16g约等于Windows多少g?
Mac 16g 内存等于 Windows 320g 内存 何为“黄金内存”? Mac 的内存是用黄金做的,而 Windows 的内存是用铁做的。 黄金的密度是 19.32 g/cm,而铁的密度是 7.874 g/cm。 因此,16g 的黄金体积是 0.082 cm,而 16g 的铁…...
快麦ERP退货借助APPlink快速同步CRM
什么是APPlink? APPlink是RestCloud打造的一款简单易用的零代码自动化集成平台,为业务流程提供自动化的解决方案,将企业内部的核心系统以及第三方应用程序和云服务等进行集成。无论是开发人员还是业务人员,都可以使用APPlink轻松…...
springMVC获取请求参数的方式
文章目录 springmvc获取参数的方式1、ServletAPI获取参数(原生态)2、通过控制器的形参取值3、 RequestParam4、通过POJO获取请求参数 springmvc获取参数的方式 1、ServletAPI获取参数(原生态) 将HttpServletRequest作为控制器方…...
android常用方法
获取应用安装来源 private String getAppInstaller(Context context, String packageName) {return context.getPackageManager().getInstallerPackageName(packageName);}判断是否系统应用 在/system/app 或者 /system/priv-app目录下的应用。 public boolean isSystem(Conte…...
Linux内核--网络协议栈(一)Socket通信原理和实例讲解
目录 一、引言 二、Socket ------>2.1、socket编程 ------>2.2、Socket的创建 三、收发数据 四、断开连接 五、删除套接字 六、网络 IO 一、引言 本章开始进入linux内核中网络部分的学习,先简单介绍一下socket套接字 二、Socket 一个数据包经由应用程序产生…...
Spring事务(2):声明式事务管理案例-转账(xml、注解)
1 编写转账案例,引出事务管理问题 需求:账号转账,Tom账号取出1000元,存放到Jack账号上 1.1 建表脚本(MySQL) CREATE TABLE t_account (id INT(11) NOT NULL AUTO_INCREMENT,name VARCHAR(20) NOT NULL,m…...
NACHI机器人模拟示教器如何切换中文
前言 现在开始学习机器人的编程语言,那么要学习会用首先得用模拟示教器来学习,但是全是英文确实比较难受一些些,没有中文来的直观。所以摸透一下如何给示教器更换语言。 具体步骤 步骤一:将中文的汉化包下载下来。具体的下载链…...
用通俗易懂的方式讲解:使用 Mistral-7B 和 Langchain 搭建基于PDF文件的聊天机器人
在本文中,使用LangChain、HuggingFaceEmbeddings和HuggingFace的Mistral-7B LLM创建一个简单的Python程序,可以从任何pdf文件中回答问题。 一、LangChain简介 LangChain是一个在语言模型之上开发上下文感知应用程序的框架。LangChain使用带prompt和few…...
综合智慧能源监测管理平台,实现能源管理“透明”化
能源问题是全球面临的最大问题,在提高经济增长的同时,也引发了能源供应危机及环境严重等问题,降低能源管理、低碳环保是我们未来发展的必经之路。 为了解决这一问题,智慧能源管理平台应运而生。平台采用微服务架构,整…...
【大数据进阶第三阶段之Datax学习笔记】使用阿里云开源离线同步工具DataX 实现数据同步
【大数据进阶第三阶段之Datax学习笔记】阿里云开源离线同步工具Datax概述 【大数据进阶第三阶段之Datax学习笔记】阿里云开源离线同步工具Datax快速入门 【大数据进阶第三阶段之Datax学习笔记】阿里云开源离线同步工具Datax类图 【大数据进阶第三阶段之Datax学习笔记】使用…...
kotlin chunked 和 windowed
kotlin chunked的作用 将集合按照指定的数量分割成多个结合 val numbers listOf(0,1,2,3,4,5,6,7,8,9) //把集合按照一个结合3个元素分割 Log.d("chunked", numbers.chunked(3).toString()) // 打印结果 [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]] kotlin windowed…...
C语言光速入门笔记
C语言是一门面向过程的编译型语言,它的运行速度极快,仅次于汇编语言。C语言是计算机产业的核心语言,操作系统、硬件驱动、关键组件、数据库等都离不开C语言;不学习C语言,就不能了解计算机底层。 目录 C语言介绍C语言特…...
Flutter+Go_Router+Fluent_Ui仿阿里网盘桌面软件开发跨平台实战-买就送仿小米app开发
Flutter是谷歌公司开发的一款开源、免费的UI框架,可以让我们快速的在Android和iOS上构建高质量App。它最大的特点就是跨平台、以及高性能。 目前 Flutter 已经支持 iOS、Android、Web、Windows、macOS、Linux 的跨平台开发。 Flutter官方介绍,目前Flutte…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...
2024年赣州旅游投资集团社会招聘笔试真
2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...
STM32F4基本定时器使用和原理详解
STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...
2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...
相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...
React---day11
14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store: 我们在使用异步的时候理应是要使用中间件的,但是configureStore 已经自动集成了 redux-thunk,注意action里面要返回函数 import { configureS…...
七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...
Caliper 负载(Workload)详细解析
Caliper 负载(Workload)详细解析 负载(Workload)是 Caliper 性能测试的核心部分,它定义了测试期间要执行的具体合约调用行为和交易模式。下面我将全面深入地讲解负载的各个方面。 一、负载模块基本结构 一个典型的负载模块(如 workload.js)包含以下基本结构: use strict;/…...
高防服务器价格高原因分析
高防服务器的价格较高,主要是由于其特殊的防御机制、硬件配置、运营维护等多方面的综合成本。以下从技术、资源和服务三个维度详细解析高防服务器昂贵的原因: 一、硬件与技术投入 大带宽需求 DDoS攻击通过占用大量带宽资源瘫痪目标服务器,因此…...
用递归算法解锁「子集」问题 —— LeetCode 78题解析
文章目录 一、题目介绍二、递归思路详解:从决策树开始理解三、解法一:二叉决策树 DFS四、解法二:组合式回溯写法(推荐)五、解法对比 递归算法是编程中一种非常强大且常见的思想,它能够优雅地解决很多复杂的…...
