FPGA开发之HDMI Transmitter接口设计

news2025/1/25 4:46:33

HDMI简介:

 High Definition Multimedia 高清多媒体接口,一种全数字化视频和声音发送接口,可以发送未压缩的音频及视频信号

物理接口:

电气介绍:

TMDS(Transition Minimized Differential Signaling,最小化传输差分信号)是美国Silicon Image公司开发的一项高速数据传输技术。如下图,由三组TMDS通道和一组TMDS clock通道组成,TMDS clock的运行频率是video信号的pixel频率,在每个cycle,每个TMDS data通道发送10bit数据。

 协议起源于DVI协议,并在许多方面与DVI协议相同,包括物理TMDS链路、活动视频编码算法和控制令牌定义。HDMI通过传输辅助数据(InfoFrames)和音频,承载了比DVI多得多的数据视频消隐期间的数据。下图显示了视频的HDMI编码方案和音频数据相对于VDE和辅助/音频数据启用(ADE)。

 下面根据HDMI的协议内容开始进行设计:

首先大致分为三部分:编码,并转串,时钟生成。

 

 top.v

`timescale 1 ps / 1ps

module hdmi_top# (
  parameter SDATAINVERT = "FALSE" //Invert SDATA before serilize it
)(
input         clkin,            // system clock
input         clkx5in,          // system clock x5
input         clkx5notin,       // system clock x5 not
input         rstin,            // reset
input    [7:0]   blue_din,         // Blue data in
input    [7:0]   green_din,        // Green data in
input    [7:0]   red_din,          // Red data in
input [3:0]   aux0_din,
input [3:0]   aux1_din,
input [3:0]   aux2_din,
input         hsync,            // hsync data
input         vsync,            // vsync data
input         vde,              // video data enable
input         ade,              // audio/aux data enable
output    [7:0]    tmds_data);            // data outputs to ddr in IOB, bit 3(and 7) is clock
    
wire     [9:0]   red;
wire     [9:0]   green;
wire     [9:0]   blue;
wire     [29:0]    s_data ;

reg  ctl0, ctl1, ctl2, ctl3;

parameter DILNDPREAM = 4'b1010;
parameter VIDEOPREAM = 4'b1000;
parameter NULLCONTRL = 4'b0000;

always @ (posedge clkin) begin
  if(vde)
    {ctl0, ctl1, ctl2, ctl3} <=#1 VIDEOPREAM;
  else if(ade)
    {ctl0, ctl1, ctl2, ctl3} <=#1 DILNDPREAM;
  else
    {ctl0, ctl1, ctl2, ctl3} <=#1 NULLCONTRL;
end

wire [7:0] blue_dly, green_dly, red_dly;
wire [3:0] aux0_dly, aux1_dly, aux2_dly;
wire       hsync_dly, vsync_dly, vde_dly, ade_dly;

srldelay # (
  .WIDTH(40),
  .TAPS(4'b1010)
) srldly_0 (
  .data_i({blue_din, green_din, red_din, aux0_din, aux1_din, aux2_din, hsync, vsync, vde, ade}),
  .data_o({blue_dly, green_dly, red_dly, aux0_dly, aux1_dly, aux2_dly, hsync_dly, vsync_dly, vde_dly, ade_dly}),
  .clk(clkin)
);

encode # (
  .CHANNEL("BLUE")
)encb (
    .clkin    (clkin),
    .rstin    (rstin),
    .vdin        (blue_dly),
  .adin   (aux0_dly),
    .c0     (hsync_dly),
    .c1     (vsync_dly),
    .vde        (vde_dly),
    .ade        (ade_dly),
    .dout        (blue)) ;

encode # (
  .CHANNEL("GREEN")
) encg (
    .clkin    (clkin),
    .rstin    (rstin),
    .vdin        (green_dly),
  .adin   (aux1_dly),
    .c0     (ctl0),
    .c1     (ctl1),
    .vde        (vde_dly),
    .ade        (ade_dly),
    .dout        (green)) ;

encode # (
  .CHANNEL("RED")
) encr (
    .clkin    (clkin),
    .rstin    (rstin),
    .vdin        (red_dly),
  .adin   (aux2_dly),
    .c0     (ctl2),
    .c1     (ctl3),
    .vde        (vde_dly),
    .ade        (ade_dly),
    .dout        (red)) ;

assign s_data = {red[9], green[9], blue[9], red[8], green[8], blue[8],
            red[7], green[7], blue[7], red[6], green[6], blue[6],
            red[5], green[5], blue[5], red[4], green[4], blue[4],
            red[3], green[3], blue[3], red[2], green[2], blue[2],
            red[1], green[1], blue[1], red[0], green[0], blue[0]} ;

reg [29:0] s_data_q;

always @ (posedge clkin) begin
  if(SDATAINVERT == "TRUE")
    s_data_q <= ~s_data;
  else
    s_data_q <= s_data;
end

serdes_4b_10to1 serialise (
    .clk            (clkin),
    .clkx5        (clkx5in),
    .clkx5not    (clkx5notin),
    .datain        (s_data_q),
    .rst            (rstin),
    .dataout    (tmds_data)) ;
        
endmodule
 

编码部分:

module encode # (
  parameter CHANNEL="BLUE"
)(
  input  wire       clkin,    // pixel clock input
  input  wire       rstin,    // async. reset input (active high)
  input  wire [7:0] vdin,     // video data inputs: expect registered
  input  wire [3:0] adin,     // audio/aux data inputs: expect registered
  input  wire       c0,       //
  input  wire       c1,       //
  input  wire       vde,      // video de input
  input  wire       ade,      // audio/aux de input
  output reg [9:0]  dout      // data outputs
);


  localparam VIDEOGBND = (CHANNEL == "BLUE") ?  10'b1011001100 : 
                         (CHANNEL == "GREEN") ? 10'b0100110011 : 10'b1011001100;

  localparam DILNDGBND = (CHANNEL == "GREEN") ? 10'b0100110011 :
                         (CHANNEL == "RED") ?   10'b0100110011 : 10'bxxxxxxxxxx; 

 
  // 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
  // output
 
  reg [3:0] n1d; //number of 1s in video din
  reg [7:0] vdin_q;

  always @ (posedge clkin) begin
    n1d <=#1 vdin[0] + vdin[1] + vdin[2] + vdin[3] + vdin[4] + vdin[5] + vdin[6] + vdin[7];

    vdin_q <=#1 vdin;
  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) & (vdin_q[0] == 1'b0));

  wire [8:0] q_m;
  assign q_m[0] = vdin_q[0];
  assign q_m[1] = (decision1) ? (q_m[0] ^~ vdin_q[1]) : (q_m[0] ^ vdin_q[1]);
  assign q_m[2] = (decision1) ? (q_m[1] ^~ vdin_q[2]) : (q_m[1] ^ vdin_q[2]);
  assign q_m[3] = (decision1) ? (q_m[2] ^~ vdin_q[3]) : (q_m[2] ^ vdin_q[3]);
  assign q_m[4] = (decision1) ? (q_m[3] ^~ vdin_q[4]) : (q_m[3] ^ vdin_q[4]);
  assign q_m[5] = (decision1) ? (q_m[4] ^~ vdin_q[5]) : (q_m[4] ^ vdin_q[5]);
  assign q_m[6] = (decision1) ? (q_m[5] ^~ vdin_q[6]) : (q_m[5] ^ vdin_q[6]);
  assign q_m[7] = (decision1) ? (q_m[6] ^~ vdin_q[7]) : (q_m[6] ^ vdin_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_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; //disparity counter, MSB is the sign bit
  wire 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 alignment
 
  reg       vde_q, vde_reg;
  reg       ade_q, ade_reg;
  reg       ade_reg_q, ade_reg_qq;
  reg       c0_q, c1_q;
  reg       c0_reg, c1_reg;
  reg [3:0] adin_q, adin_reg;
  reg [8:0] q_m_reg;

  always @ (posedge clkin) begin
    vde_q      <=#1 vde;
    vde_reg    <=#1 vde_q;

    ade_q      <=#1 ade;
    ade_reg    <=#1 ade_q;
    ade_reg_q  <=#1 ade_reg;
    ade_reg_qq <=#1 ade_reg_q;

    c0_q    <=#1 c0;
    c0_reg  <=#1 c0_q;
    c1_q    <=#1 c1;
    c1_reg  <=#1 c1_q;

    adin_q     <=#1 adin;
    adin_reg   <=#1 adin_q;

    q_m_reg    <=#1 q_m;
  end

  wire digbnd; //data island guard band period
  assign digbnd = (ade & !ade_reg) | (!ade_reg & ade_reg_qq);

  wire ade_vld;
  wire [3:0] adin_vld;

  generate
    if(CHANNEL == "BLUE") begin
      assign ade_vld = ade | ade_reg | ade_reg_qq;
      assign adin_vld = (digbnd) ? {1'b1, 1'b1, c1_reg, c0_reg} : {adin_reg[3], adin_reg[2], c1_reg, c0_reg};
    end else begin
      assign ade_vld = ade_reg;
      assign adin_vld = adin_reg;
    end
  endgenerate


  ///
  // 10-bit out
  // disparity counter
  ///
  always @ (posedge clkin or posedge rstin) begin
    if(rstin) begin
      dout <= 10'h0;
      cnt <= 5'h0;
    end else begin //TMDS
      if (vde_reg) begin //Video Data Period
        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;

            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
        if(vde)          //video guard band period
          dout <=#1 VIDEOGBND;
        else if(ade_vld) //Aux/Audio Data Period
          case (adin_vld) //TERC4
            4'b0000: dout <=#1 10'b1010011100;
            4'b0001: dout <=#1 10'b1001100011;
            4'b0010: dout <=#1 10'b1011100100;
            4'b0011: dout <=#1 10'b1011100010;
            4'b0100: dout <=#1 10'b0101110001;
            4'b0101: dout <=#1 10'b0100011110;
            4'b0110: dout <=#1 10'b0110001110;
            4'b0111: dout <=#1 10'b0100111100;
            4'b1000: dout <=#1 10'b1011001100;
            4'b1001: dout <=#1 10'b0100111001;
            4'b1010: dout <=#1 10'b0110011100;
            4'b1011: dout <=#1 10'b1011000110;
            4'b1100: dout <=#1 10'b1010001110;
            4'b1101: dout <=#1 10'b1001110001;
            4'b1110: dout <=#1 10'b0101100011;
            default: dout <=#1 10'b1011000011;
          endcase
        else if((ade | ade_reg_qq) && (CHANNEL != "BLUE")) //data island guard band period
          dout <=#1 DILNDGBND;
        else            //preample period
          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

并串转化:

module serdes_4b_10to1 (
  input          clk,         // clock input
  input          clkx5,       // 5x clock input
  input          clkx5not,
  input [29:0]   datain,      // input data for serialisation
  input          rst,         // reset
  output [7:0]   dataout) ;   // out DDR data and clock

  wire [4:0] syncp; // internal sync signals for rising edges
  wire [4:0] syncn; // internal sync signals for falling edges

  reg [3:0] p_mux;      // muxes (+ve)
  reg [3:0] n_mux;      // muxes (-ve)
  wire [29:0] dataint;
  wire [29:0] db;

  wire  [3:0]   wa;       // RAM read address
  reg   [3:0]   wa_d;     // RAM read address
  wire  [3:0]   ra;       // RAM read address
  reg   [3:0]   ra_d;     // RAM read address

 
  // Here we instantiate a 16x30 Dual Port RAM
  // and fill first it with data aligned to
  // clk domain
 

  parameter ADDR0  = 4'b0000;
  parameter ADDR1  = 4'b0001;
  parameter ADDR2  = 4'b0010;
  parameter ADDR3  = 4'b0011;
  parameter ADDR4  = 4'b0100;
  parameter ADDR5  = 4'b0101;
  parameter ADDR6  = 4'b0110;
  parameter ADDR7  = 4'b0111;
  parameter ADDR8  = 4'b1000;
  parameter ADDR9  = 4'b1001;
  parameter ADDR10 = 4'b1010;
  parameter ADDR11 = 4'b1011;
  parameter ADDR12 = 4'b1100;
  parameter ADDR13 = 4'b1101;
  parameter ADDR14 = 4'b1110;
  parameter ADDR15 = 4'b1111;

  always@(wa) begin
    case (wa)
      ADDR0   : wa_d = ADDR1 ;
      ADDR1   : wa_d = ADDR2 ;
      ADDR2   : wa_d = ADDR3 ;
      ADDR3   : wa_d = ADDR4 ;
      ADDR4   : wa_d = ADDR5 ;
      ADDR5   : wa_d = ADDR6 ;
      ADDR6   : wa_d = ADDR7 ;
      ADDR7   : wa_d = ADDR8 ;
      ADDR8   : wa_d = ADDR9 ;
      ADDR9   : wa_d = ADDR10;
      ADDR10  : wa_d = ADDR11;
      ADDR11  : wa_d = ADDR12;
      ADDR12  : wa_d = ADDR13;
      ADDR13  : wa_d = ADDR14;
      ADDR14  : wa_d = ADDR15;
      default : wa_d = ADDR0;
    endcase
  end

  FDC fdc_wa0 (.C(clk),  .D(wa_d[0]), .CLR(rst), .Q(wa[0]));
  FDC fdc_wa1 (.C(clk),  .D(wa_d[1]), .CLR(rst), .Q(wa[1]));
  FDC fdc_wa2 (.C(clk),  .D(wa_d[2]), .CLR(rst), .Q(wa[2]));
  FDC fdc_wa3 (.C(clk),  .D(wa_d[3]), .CLR(rst), .Q(wa[3]));

  //Dual Port fifo to bridge data through
  DRAM16XN #(.data_width(30))
  fifo_u (
         .DATA_IN(datain),
         .ADDRESS(wa),
         .ADDRESS_DP(ra),
         .WRITE_EN(1'b1),
         .CLK(clk),
         .O_DATA_OUT(),
         .O_DATA_OUT_DP(dataint));

  /
  // Here starts clk5x domain for fifo read out 
  // FIFO read is set to be once every 5 cycles of clk5x in order
  // to keep up pace with the fifo write speed
  // Also FIFO read reset is delayed a bit in order to avoid
  // underflow.
  /

  always@(ra) begin
    case (ra)
      ADDR0   : ra_d = ADDR1 ;
      ADDR1   : ra_d = ADDR2 ;
      ADDR2   : ra_d = ADDR3 ;
      ADDR3   : ra_d = ADDR4 ;
      ADDR4   : ra_d = ADDR5 ;
      ADDR5   : ra_d = ADDR6 ;
      ADDR6   : ra_d = ADDR7 ;
      ADDR7   : ra_d = ADDR8 ;
      ADDR8   : ra_d = ADDR9 ;
      ADDR9   : ra_d = ADDR10;
      ADDR10  : ra_d = ADDR11;
      ADDR11  : ra_d = ADDR12;
      ADDR12  : ra_d = ADDR13;
      ADDR13  : ra_d = ADDR14;
      ADDR14  : ra_d = ADDR15;
      default : ra_d = ADDR0;
    endcase
  end

  wire rstsync, rstsync_q, rstp, rstn;
  (* ASYNC_REG = "TRUE" *) FDP fdp_rst  (.C(clkx5),  .D(rst), .PRE(rst), .Q(rstsync));

  FD fd_rstsync (.C(clkx5),  .D(rstsync), .Q(rstsync_q));
  FD fd_rstp    (.C(clkx5),  .D(rstsync_q), .Q(rstp));

  FDRE fdc_ra0 (.C(clkx5),  .D(ra_d[0]), .R(rstp), .CE(syncp[4]), .Q(ra[0]));
  FDRE fdc_ra1 (.C(clkx5),  .D(ra_d[1]), .R(rstp), .CE(syncp[4]), .Q(ra[1]));
  FDRE fdc_ra2 (.C(clkx5),  .D(ra_d[2]), .R(rstp), .CE(syncp[4]), .Q(ra[2]));
  FDRE fdc_ra3 (.C(clkx5),  .D(ra_d[3]), .R(rstp), .CE(syncp[4]), .Q(ra[3]));

  //
  // 5 Cycle Counter for clkx5
  // Generate data latch and bit mux timing
  //
  wire [2:0] statep, staten;
  reg [2:0] statep_d, staten_d;

  parameter ST0 = 3'b000;
  parameter ST1 = 3'b001;
  parameter ST2 = 3'b011;
  parameter ST3 = 3'b111;
  parameter ST4 = 3'b110;

  always@(statep) begin
    case (statep)
      ST0     : statep_d = ST1 ;
      ST1     : statep_d = ST2 ;
      ST2     : statep_d = ST3 ;
      ST3     : statep_d = ST4 ;
      default : statep_d = ST0;
    endcase
  end

  FDR fdc_stp0 (.C(clkx5),  .D(statep_d[0]), .R(rstp), .Q(statep[0]));
  FDR fdc_stp1 (.C(clkx5),  .D(statep_d[1]), .R(rstp), .Q(statep[1]));
  FDR fdc_stp2 (.C(clkx5),  .D(statep_d[2]), .R(rstp), .Q(statep[2]));

  wire [4:0] syncp_d;

  assign syncp_d[0] = (statep == ST0);
  assign syncp_d[1] = (statep == ST1);
  assign syncp_d[2] = (statep == ST2);
  assign syncp_d[3] = (statep == ST3);
  assign syncp_d[4] = (statep == ST4);

  FD fd_syncp0 (.C(clkx5), .D(syncp_d[0]), .Q(syncp[0]));
  FD fd_syncp1 (.C(clkx5), .D(syncp_d[1]), .Q(syncp[1]));
  FD fd_syncp2 (.C(clkx5), .D(syncp_d[2]), .Q(syncp[2]));
  FD fd_syncp3 (.C(clkx5), .D(syncp_d[3]), .Q(syncp[3]));
  FD fd_syncp4 (.C(clkx5), .D(syncp_d[4]), .Q(syncp[4]));

  //
  // 5 Cycle Counter for clkx5not
  // Generate data latch and bit mux timing
  //
  FD  fd_rstn (.C(clkx5not),  .D(rstsync_q), .Q(rstn));

  always@(staten) begin
    case (staten)
      ST0     : staten_d = ST1 ;
      ST1     : staten_d = ST2 ;
      ST2     : staten_d = ST3 ;
      ST3     : staten_d = ST4 ;
      default : staten_d = ST0;
    endcase
  end

  FDR fdc_stn0 (.C(clkx5not),  .D(staten_d[0]), .R(rstn), .Q(staten[0]));
  FDR fdc_stn1 (.C(clkx5not),  .D(staten_d[1]), .R(rstn), .Q(staten[1]));
  FDR fdc_stn2 (.C(clkx5not),  .D(staten_d[2]), .R(rstn), .Q(staten[2]));

  wire [4:0] syncn_d;

  assign syncn_d[0] = (staten == ST0);
  assign syncn_d[1] = (staten == ST1);
  assign syncn_d[2] = (staten == ST2);
  assign syncn_d[3] = (staten == ST3);
  assign syncn_d[4] = (staten == ST4);

  FD fd_syncn0 (.C(clkx5not), .D(syncn_d[0]), .Q(syncn[0]));
  FD fd_syncn1 (.C(clkx5not), .D(syncn_d[1]), .Q(syncn[1]));
  FD fd_syncn2 (.C(clkx5not), .D(syncn_d[2]), .Q(syncn[2]));
  FD fd_syncn3 (.C(clkx5not), .D(syncn_d[3]), .Q(syncn[3]));
  FD fd_syncn4 (.C(clkx5not), .D(syncn_d[4]), .Q(syncn[4]));

 
  // Latch data out of FIFO
  // clkx5 setup time: 5 cycles since syncp[4] is used as CE
  // clkx5not setup time: 4.5 cycles since syncn[4] is used as CE
  // syncn[4] is set to be 0.5 cycle earlier than syncp[4]
 
  FDE fd_db0 (.C(clkx5not), .D(dataint[0]),  .CE(syncn[4]), .Q(db[0]));
  FDE fd_db1 (.C(clkx5not), .D(dataint[1]),  .CE(syncn[4]), .Q(db[1]));
  FDE fd_db2 (.C(clkx5not), .D(dataint[2]),  .CE(syncn[4]), .Q(db[2]));

  FDE fd_db3 (.C(clkx5),    .D(dataint[3]),  .CE(syncp[4]), .Q(db[3]));
  FDE fd_db4 (.C(clkx5),    .D(dataint[4]),  .CE(syncp[4]), .Q(db[4]));
  FDE fd_db5 (.C(clkx5),    .D(dataint[5]),  .CE(syncp[4]), .Q(db[5]));

  FDE fd_db6 (.C(clkx5not), .D(dataint[6]),  .CE(syncn[4]), .Q(db[6]));
  FDE fd_db7 (.C(clkx5not), .D(dataint[7]),  .CE(syncn[4]), .Q(db[7]));
  FDE fd_db8 (.C(clkx5not), .D(dataint[8]),  .CE(syncn[4]), .Q(db[8]));

  FDE fd_db9 (.C(clkx5),    .D(dataint[9]),  .CE(syncp[4]), .Q(db[9]));
  FDE fd_db10(.C(clkx5),    .D(dataint[10]), .CE(syncp[4]), .Q(db[10]));
  FDE fd_db11(.C(clkx5),    .D(dataint[11]), .CE(syncp[4]), .Q(db[11]));

  FDE fd_db12(.C(clkx5not), .D(dataint[12]), .CE(syncn[4]), .Q(db[12]));
  FDE fd_db13(.C(clkx5not), .D(dataint[13]), .CE(syncn[4]), .Q(db[13]));
  FDE fd_db14(.C(clkx5not), .D(dataint[14]), .CE(syncn[4]), .Q(db[14]));

  FDE fd_db15(.C(clkx5),    .D(dataint[15]), .CE(syncp[4]), .Q(db[15]));
  FDE fd_db16(.C(clkx5),    .D(dataint[16]), .CE(syncp[4]), .Q(db[16]));
  FDE fd_db17(.C(clkx5),    .D(dataint[17]), .CE(syncp[4]), .Q(db[17]));

  FDE fd_db18(.C(clkx5not), .D(dataint[18]), .CE(syncn[4]), .Q(db[18]));
  FDE fd_db19(.C(clkx5not), .D(dataint[19]), .CE(syncn[4]), .Q(db[19]));
  FDE fd_db20(.C(clkx5not), .D(dataint[20]), .CE(syncn[4]), .Q(db[20]));

  FDE fd_db21(.C(clkx5),    .D(dataint[21]), .CE(syncp[4]), .Q(db[21]));
  FDE fd_db22(.C(clkx5),    .D(dataint[22]), .CE(syncp[4]), .Q(db[22]));
  FDE fd_db23(.C(clkx5),    .D(dataint[23]), .CE(syncp[4]), .Q(db[23]));

  FDE fd_db24(.C(clkx5not), .D(dataint[24]), .CE(syncn[4]), .Q(db[24]));
  FDE fd_db25(.C(clkx5not), .D(dataint[25]), .CE(syncn[4]), .Q(db[25]));
  FDE fd_db26(.C(clkx5not), .D(dataint[26]), .CE(syncn[4]), .Q(db[26]));

  FDE fd_db27(.C(clkx5),    .D(dataint[27]), .CE(syncp[4]), .Q(db[27]));
  FDE fd_db28(.C(clkx5),    .D(dataint[28]), .CE(syncp[4]), .Q(db[28]));
  FDE fd_db29(.C(clkx5),    .D(dataint[29]), .CE(syncp[4]), .Q(db[29]));

  //
  // Data OUT Multiplexers: clk5x and clk5xnot
  //
  always @ (*)
  begin
    casex (1'b1) // synthesis parallel_case full_case
      syncn[0]: begin
        n_mux[0] = db[0];
        n_mux[1] = db[1];
        n_mux[2] = db[2];
        n_mux[3] = 1'b0;
      end

      syncn[1]: begin
        n_mux[0] = db[6];
        n_mux[1] = db[7];
        n_mux[2] = db[8];
        n_mux[3] = 1'b0;
      end

      syncn[2]: begin
        n_mux[0] = db[12];
        n_mux[1] = db[13];
        n_mux[2] = db[14];
        n_mux[3] = 1'b0;
      end

      syncn[3]: begin
        n_mux[0] = db[18];
        n_mux[1] = db[19];
        n_mux[2] = db[20];
        n_mux[3] = 1'b1;
      end

      syncn[4]: begin
        n_mux[0] = db[24];
        n_mux[1] = db[25];
        n_mux[2] = db[26];
        n_mux[3] = 1'b1;
      end
    endcase
  end

  FD muxn0(.D(n_mux[0]), .C(clkx5not), .Q(dataout[4])) ;
  FD muxn1(.D(n_mux[1]), .C(clkx5not), .Q(dataout[5])) ;
  FD muxn2(.D(n_mux[2]), .C(clkx5not), .Q(dataout[6])) ;
  FD muxn3(.D(n_mux[3]), .C(clkx5not), .Q(dataout[7])) ;

  always @ (*)
  begin
    casex (1'b1) // synthesis parallel_case full_case
      syncp[0]: begin
        p_mux[0] = db[3];
        p_mux[1] = db[4];
        p_mux[2] = db[5];
        p_mux[3] = 1'b0;
      end

      syncp[1]: begin
        p_mux[0] = db[9];
        p_mux[1] = db[10];
        p_mux[2] = db[11];
        p_mux[3] = 1'b0;
      end

      syncp[2]: begin
        p_mux[0] = db[15];
        p_mux[1] = db[16];
        p_mux[2] = db[17];
        p_mux[3] = 1'b1;
      end

      syncp[3]: begin
        p_mux[0] = db[21];
        p_mux[1] = db[22];
        p_mux[2] = db[23];
        p_mux[3] = 1'b1;
      end

      syncp[4]: begin
        p_mux[0] = db[27];
        p_mux[1] = db[28];
        p_mux[2] = db[29];
        p_mux[3] = 1'b1;
      end
    endcase
  end

  FD muxp0(.D(p_mux[0]), .C(clkx5), .Q(dataout[0])) ;
  FD muxp1(.D(p_mux[1]), .C(clkx5), .Q(dataout[1])) ;
  FD muxp2(.D(p_mux[2]), .C(clkx5), .Q(dataout[2])) ;
  FD muxp3(.D(p_mux[3]), .C(clkx5), .Q(dataout[3])) ;

endmodule

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/433734.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

自定义类型——位段

什么是位段&#xff1f; 位段又叫做位域&#xff0c;具体是一种可以把数据以位的形式紧凑的存储&#xff0c;并允许程序员对此结构位进行操作的数据结构 当结构体的成员变量定义之后浪费了较大的空间 &#xff08;比如int a 2&#xff0c;则浪费了30个比特位的空间&#xff0…

Mail 服务器

Mail 服务器 1. 概念及协议2. 工具2.1 Postfix2.2 dovecot2.3 bind 3. 搭建3.1 DNS服务设置3.2 安装配置 postfix3.3 安装配置 dovecot 4. foxmail验证 1. 概念及协议 邮件服务器也采用的是C/S工作模式&#xff0c;通过SMTP,POP,IMAP协议来是实现邮件的发送和接收的。 SMTP 的…

Java入坑之IO操作

目录 一、IO流的概念 二、字节流 2.1InputStream的方法 2.2Outputstream的方法 2.3资源对象的关闭&#xff1a; 2.4transferTo()方法 2.5readAllBytes() 方法 2.6BufferedReader 和 InputStreamReader 2.7BufferedWriter 和 OutputStreamWriter 三、路径&#xff1a;…

Qt5 编译QtXlsx并添加为模块[Windows]

00.QtXlsx是什么&#xff1f;能干什么&#xff1f; QtXlsx是一个可以读写Excel文件的库。它不需要Microsoft Excel&#xff0c;可以在Qt5支持的任何平台上使用。 可以创建、读取、编辑.xlsx文件。 01.如何编译&#xff1f; 1.1编译环境&#xff1a; Windows10平台&#xff1b;…

es6笔记-let、const、var的区别

let、const、var的区别 变量提升 var 声明的变量存在变量提升,在声明前可以调用&#xff0c;直为undefindconsole.log(a); var a 1;相当于&#xff1a;var a; console.log(a); a 1;let和const不存在变量提升&#xff0c;变量要在声明前调用&#xff0c;否则报错console.log(a…

DNS服务器配置

一&#xff0c;正向解析 1>安装软件bind 提供DNS服务的软件叫bind&#xff0c;服务名是named [rootserver ~]# yum install bind -y 2>对三个配置文件进行修改 - /etc/named.conf : 主配置文件&#xff0c;共59行&#xff0c;去除注释和空行之和有效行数仅30行左右&…

Golang程序报错:fatal error: all goroutines are asleep - deadlock

文章目录 1.原始代码2.错误原因分析3. 解决方案4. 经验总结5. 练习 完整的报错信息如下&#xff1a; fatal error: all goroutines are asleep - deadlock!goroutine 1 [chan receive]: main.(*WorkerManager).KeepAlive(0xc000088f60)/root/go_workspace/studygoup/05.go:66 0…

Doris(7):数据导入(Load)之Routine Load

例行导入功能为用户提供了义中自动从指定数据源进行数据导入的功能 1 适用场景 当前仅支持kafka系统进行例行导入。 2 使用限制 支持无认证的 Kafka 访问&#xff0c;以及通过 SSL 方式认证的 Kafka 集群。支持的消息格式为 csv 文本格式。每一个 message 为一行&#xff0c;…

【Cpp】手撕搜索二叉树(K模型)

文章目录 二叉搜索树概念详解二叉搜索树的概念二叉搜索树的操作(大致思路)二叉搜索树的查找二叉搜索树的插入二叉搜索树的删除(最重点) 手撕搜索二叉树代码结点定义(以key型为例,KV型将在下一篇博客中介绍)树结构定义深拷贝构造函数与构造函数赋值重载析构函数遍历(结果按从小到…

软件测试的当下分析

在没有清晰能见度的情况下驾驶汽车不仅非常危险&#xff0c;也十分鲁莽。这会让我们和我们周边的人随时面临着碰撞、受伤、甚至死亡的风险。如果不能看到前方的道路&#xff0c;我们就无法预测潜在的危险或障碍&#xff0c;从而无法做出明智的决定并采取适当的行动。 同样&…

什么是ddos攻击?ddos攻击有哪些危害?

一、什么是 DDoS 攻击&#xff1f; DDoS 是 Distributed Denial of Service 的缩写&#xff0c;翻译成中文就是 “分布式拒绝服务”。DDoS 攻击将处于不同位置的多个计算机联合起来作为攻击平台&#xff0c;对一个和多个目标发动 DDoS 攻击&#xff0c;从而成倍提高攻击威力。…

分布式系统概念和设计-进程通信中的(网络API设计)

分布式系统概念和设计 进程间通信 中间件层 请求-应答协议 编码和外部数据表示 因特网协议的API 进程间通信的特征 一对进程间进行消息传递需要两个消息通信操作的支持&#xff08;send和receive&#xff09;&#xff0c;用于定义目的地和消息的定义。 为了能够使一个进程能…

煤化工废水除总氮除硬度,矿井水除砷除氟解决方案

随着环保标准的提升&#xff0c;大部分煤矿企业对矿井水要求执行地表三类水标准&#xff0c;氟化物要求小于1mg/l&#xff0c;这类项目存在体量大、氟含量低、水质偏差等特点。 RO工艺制备纯水是煤化工行业生产的一个辅助环节&#xff0c;会产生大量的浓盐水&#xff0c;由于浓…

十五分钟带你学会 Electron

文章目录 什么是 Electron为什么要选择 Electron安装 Electron桌面CSDN实战Electron 基础配置Electron 进程主进程渲染进程主进程与渲染进程的区别主进程与渲染进程的通信 Electron 跨平台问题Electron 部署打包应用程序发布应用程序 Electron 跨端原理总结 什么是 Electron E…

NE555 Motor LED Chaser

文章目录 1.前言2.资料下载 1.前言 这个是从YouTube上搬运来的&#xff0c;如图所示 2.资料下载 所需材料 #1# 10k resistor 1 #2# 10k variable resistor 1 #3# 10uf capacitor 1 #4# 3mm blue led 4 #5# 3mm yellow led 4 #6# 3mm red led 4 #7# 3mm green led 4 #8# 3mm…

【Linux网络】网络基础(TCP/IP协议栈、局域网通信原理、封装与解包、有效载荷分用)

文章目录 1、认识网络1.1 重新看待计算机结构1.2 网络的问题1.3 初识网络协议1.4 TCP/IP五层结构 2、网络与操作系统2.1 网络和OS的关系2.2 局域网&#xff08;以太网&#xff09;通信原理和MAC地址2.3 主机的跨网络2.4 有效载荷的分用 1、认识网络 在早年计算机之间是相互独立…

关于自身存在的严重问题总结_4/19

今早二次面试喜马拉雅&#xff0c;面试官给我的评价是&#xff1a; 1.经验不足&#xff1b; 2.实用方面生疏、理解不到位&#xff1b; 原因很正常&#xff0c;我项目自己亲手实操的太少了&#xff0c;一直在背&#xff0c;但是背 不是去读源码 去理解&#xff1b; 项目也大…

基于springboot的班级综合测评管理系统源码数据库论文

目录 1 绪论 1.1课题研究的背景 1.2 课题研究的内容 1.3 系统开发的意义 1.4初步设计方法与实施方案 1.5 本文研究内容 2相关技术介绍 2.1 Java技术 2.2B/S架构 2.3 MySQL介绍 2.4 Springboot框架 3系统需求分析 3.1 可行性分析 3.1.1 经济可行性分…

AI大模型在各行业肆虐,打工人该如何保住自己的饭碗?

开篇我先下个结论&#xff0c;那就是&#xff1a;人类在科技领域的高效率竞争&#xff0c;正在把我们生活的这个商业世界一步步地数字化。而数字化&#xff0c;不单单是AI智能的发展成果&#xff0c;更会成为它所热衷的生长温床&#xff0c;为后续人工智能的一路狂飙奠定了绝佳…

2、picodet转onnx裁剪及python onnxruntime推理

文章目录 1 对picodet xs1.1 动态图转静态图1.2 静态图转onnx1.3 paddle 含后处理 all 版本的推理1.4 onnx 含后处理 all 进行推理1.5 onnx 不含后处量 base模型推理1.5.1 获取onnx模型任一节点的输出1.5.2 base模型的推理 1.6、对picodet-xs模型进行优化1.6.1 picodet-xs base…