当前位置: 首页 > news >正文

【【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小部件加载网络图片&#xff1a;使用Image.…...

RedisTemplate 怎么获取到链接信息?怎么获取到所有key?怎么获取指定key?

获取Redis的链接信息&#xff1a; (RedisTemplate<String, ?> redisTemplate) {RedisConnectionFactory connectionFactory redisTemplate.getConnectionFactory();(!(connectionFactory LettuceConnectionFactory)) {System..println();;}LettuceConnectionFactory l…...

【Unity】动态申请权限

1、AndroidManifest.xml在<application></application>内添加一行&#xff1a; <meta-data android:name"unityplayer.SkipPermissionsDialog" android:value"true" /> 作用&#xff1a;屏蔽应用启动时弹出申请权限弹窗&#xff08;危…...

tp8/6 插件PhpOffice\PhpSpreadsheet导入表格

一、安装 composer require phpoffice/phpspreadsheet 官网&#xff1a;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 方法来打开一个文件&#xff0c;该方法会返回一个文件对象。open 方法的语法如下&#xff1a; file_object open(file_name, mode)其…...

Mac 16g约等于Windows多少g?

Mac 16g 内存等于 Windows 320g 内存 何为“黄金内存”&#xff1f; Mac 的内存是用黄金做的&#xff0c;而 Windows 的内存是用铁做的。 黄金的密度是 19.32 g/cm&#xff0c;而铁的密度是 7.874 g/cm。 因此&#xff0c;16g 的黄金体积是 0.082 cm&#xff0c;而 16g 的铁…...

快麦ERP退货借助APPlink快速同步CRM

什么是APPlink&#xff1f; APPlink是RestCloud打造的一款简单易用的零代码自动化集成平台&#xff0c;为业务流程提供自动化的解决方案&#xff0c;将企业内部的核心系统以及第三方应用程序和云服务等进行集成。无论是开发人员还是业务人员&#xff0c;都可以使用APPlink轻松…...

springMVC获取请求参数的方式

文章目录 springmvc获取参数的方式1、ServletAPI获取参数&#xff08;原生态&#xff09;2、通过控制器的形参取值3、 RequestParam4、通过POJO获取请求参数 springmvc获取参数的方式 1、ServletAPI获取参数&#xff08;原生态&#xff09; 将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 编写转账案例&#xff0c;引出事务管理问题 需求&#xff1a;账号转账&#xff0c;Tom账号取出1000元&#xff0c;存放到Jack账号上 1.1 建表脚本&#xff08;MySQL&#xff09; CREATE TABLE t_account (id INT(11) NOT NULL AUTO_INCREMENT,name VARCHAR(20) NOT NULL,m…...

NACHI机器人模拟示教器如何切换中文

前言 现在开始学习机器人的编程语言&#xff0c;那么要学习会用首先得用模拟示教器来学习&#xff0c;但是全是英文确实比较难受一些些&#xff0c;没有中文来的直观。所以摸透一下如何给示教器更换语言。 具体步骤 步骤一&#xff1a;将中文的汉化包下载下来。具体的下载链…...

用通俗易懂的方式讲解:使用 Mistral-7B 和 Langchain 搭建基于PDF文件的聊天机器人

在本文中&#xff0c;使用LangChain、HuggingFaceEmbeddings和HuggingFace的Mistral-7B LLM创建一个简单的Python程序&#xff0c;可以从任何pdf文件中回答问题。 一、LangChain简介 LangChain是一个在语言模型之上开发上下文感知应用程序的框架。LangChain使用带prompt和few…...

综合智慧能源监测管理平台,实现能源管理“透明”化

能源问题是全球面临的最大问题&#xff0c;在提高经济增长的同时&#xff0c;也引发了能源供应危机及环境严重等问题&#xff0c;降低能源管理、低碳环保是我们未来发展的必经之路。 为了解决这一问题&#xff0c;智慧能源管理平台应运而生。平台采用微服务架构&#xff0c;整…...

【大数据进阶第三阶段之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语言是一门面向过程的编译型语言&#xff0c;它的运行速度极快&#xff0c;仅次于汇编语言。C语言是计算机产业的核心语言&#xff0c;操作系统、硬件驱动、关键组件、数据库等都离不开C语言&#xff1b;不学习C语言&#xff0c;就不能了解计算机底层。 目录 C语言介绍C语言特…...

Flutter+Go_Router+Fluent_Ui仿阿里网盘桌面软件开发跨平台实战-买就送仿小米app开发

Flutter是谷歌公司开发的一款开源、免费的UI框架&#xff0c;可以让我们快速的在Android和iOS上构建高质量App。它最大的特点就是跨平台、以及高性能。 目前 Flutter 已经支持 iOS、Android、Web、Windows、macOS、Linux 的跨平台开发。 Flutter官方介绍&#xff0c;目前Flutte…...

内联函数的作用

目的 主要为了提升程序运行速度。 分析 当程序调用一个函数时&#xff0c;程序暂停执行当前指令&#xff0c;跳到函数体处执行&#xff0c;在函数执行完后&#xff0c;返回原来的位置继续执行。如果该函数为内联函数&#xff0c;则不需跳&#xff0c;是因为该内联函数直接插…...

Simpy简介:python仿真模拟库-02/5

一、说明 关于python下的仿真库&#xff0c;本篇为第二部分&#xff0c;是更进一步的物理模型讲解&#xff0c;由于这部分内容强依赖于第一部分的符号介绍&#xff0c;因此&#xff0c;有以下建议&#xff1a; 此文为第二部分&#xff0c;若看第一部分。建议查看本系列的第一部…...

Kafka高级应用:如何配置处理MQ百万级消息队列?

在大数据时代&#xff0c;Apache Kafka作为一款高性能的分布式消息队列系统&#xff0c;广泛应用于处理大规模数据流。本文将深入探讨在Kafka环境中处理百万级消息队列的高级应用技巧。 本文&#xff0c;已收录于&#xff0c;我的技术网站 ddkk.com&#xff0c;有大厂完整面经…...

LIN总线学习笔记(1)-总线传输规范

关注菲益科公众号—>对话窗口发送 “CANoe ”或“INCA”&#xff0c;即可获得canoe入门到精通电子书和INCA软件安装包&#xff08;不带授权码&#xff09;下载地址。 接触LIN是从最近负责项目中开始的。项目已经快要量产了&#xff0c;因为中间遇到的大大小小的问题&#xf…...

Qt界面篇:Qt停靠控件QDockWidget、树控件QTreeWidget及属性控件QtTreePropertyBrowser的使用

1、功能介绍 本篇主要使用Qt停靠控件QDockWidget、树控件QTreeWidget及Qt属性控件QtTreePropertyBrowser来搭建一个简单实用的主界面布局。效果如下所示。 2、控件使用详解 2.1 停靠控件QDockWidget QDockWidget可以停靠在 QMainWindow 内或作为桌面上的顶级窗口浮动。默认值…...

H266/VVC网络适配层概述

视频编码标准的分层结构 视频数据分层的必要性&#xff1a;网络类型的多样性、不同的应用场景对视频有不同的需求。 编码标准的分层结构&#xff1a;为了适应不同网络和应用需求&#xff0c;视频编码数据根据其内容特性被分成若干NAL单元&#xff08;NAL Unit&#xff0c;NALU…...

new FormData 同时发送表单 json 以及文件二进制流

需要新增时同时发送表单 json 以及对应的文件即可使用以下方法传参 let formDataParams new FormData(); 首先通过 new FormData&#xff08;&#xff09; 创建你需要最后发送的表单 接着将你的对象 json 存储&#xff0c;注意使用 new Blob 创建大表单转换成 json 格式。以…...

计算机环境安全

操作系统安全----比如windows,linux 安全标识--实体唯一性 windows---主体&#xff1a;账户&#xff0c;计算机&#xff0c;服务 安全标识符SID-Security Identifier 普通用户SID是1000&#xff0c;管理用SID是500 linux---主体&#xff1a;用户&#xff0c;用户组&#xf…...

Activiti7工作流引擎:多租户

一&#xff1a;多租户 表示每个租户之间数据隔离互不影响&#xff0c;互不可见。通常一个租户表示一个系统应用&#xff08;类似于appid的作用&#xff09;或者一家公司。 通过数据库级别进行隔离&#xff0c;每个租户对应一个数据库&#xff1b;通过表记录级别进行隔离&…...

Postman实现压力测试

从事软件开发对于压力测试并不陌生,常见的一些压测软件有Apache JMeter LoadRunner Gatling Tsung 等,这些都是一些比较专业的测试软件,对于我的工作来说一般情况下用不到这么专业的测试,有时候需要对一些接口进行压力测试又不想再安装新软件,那么可以使用Postman来实现对…...

企业网站建设基本流程图/沈阳网站优化

这种情况一般发生在使用代理的情况下 解决办法 将https://asdasd.com 替换为 http://sdadas.com附上stackoverflow链接...

网站开发毕业论文结论/百度推广的四种收费形式

转载自&#xff1a;http://xylvhp.blog.163.com/blog/static/31123614201101104644542/ 首先是&#xff0c;头文件必须包含以下两个&#xff1a;#include <winable.h>#include <atlconv.h> 前者是SendInput函数要用到&#xff0c;后者是字符串转换的时候要用到。 v…...

网站空间哪家做的好/今天国际新闻

<script setup> 是在单文件组件 (SFC) 中使用组合式 API 的编译时语法糖。相比于普通的 <script> 语法&#xff0c;它具有更多优势&#xff1a; 更少的样板内容&#xff0c;更简洁的代码。能够使用纯 Typescript 声明 props 和抛出事件。更好的运行时性能 (其模板…...

阜宁企业做网站多少钱/网络推广网络营销和网站推广的区别

国内“双一流”大学硬实力排名&#xff0c;北航荣登榜首虽说国内高校数量繁多&#xff0c;但若说起最受欢迎的高校&#xff0c;那无疑985/211这类的名牌大学&#xff0c;还有双一流高校也很受青睐&#xff0c;不仅教育资源丰厚&#xff0c;学科实力也是可圈可点的。本次排名之所…...

两学一做纪实评价系统登陆网站/电商网站怎样优化

python3 turtle 画国际象棋棋盘 #!/usr/bin/env python # -*- coding:utf-8 -*- # Author:Hiuhung Wan import turtle n 60 # 每行间隔 x -300 # x初始值 y -300 # x初始值 turtle.speed(11) turtle.pensize(2) # 先画8*8的正方形&#xff0c;并按要求涂黑 for i in range(8…...

广告公司怎么做/重庆高端网站seo

场景: ArrayList 的 subList 强转成 ArrayList1、首先我们看下面代码测试结果&#xff1a;2、为什么会产生上述异常&#xff1f;下面 subList方法的源码(1) SubList 继承 AbstractList &#xff0c;所以具有List接口的所有方法。(2) SubList 是ArrayList 的一个内部类。SubList…...