zoukankan      html  css  js  c++  java
  • TMDS代码

    module dvi_encoder(
    clkin,
    rstin,
    din,
    c0,
    c1,
    de,
    dout
    );
    input clkin;   //像素时钟输入
    input rstin;   //同步复位输入
    input[7:0]din; //数据输入
    input c0,c1;    //控制信号输入
    input de;       //数据使能信号输入
    output reg[9:0]dout;//数据输出
    //首先计算输入数据中1的个数
    //同时对输入数据进行寄存
    reg[7:0]din_q;
    reg[3:0]n1d;
    always@(posedge clkin)begin
     n1d<=din[0]+din[1]+din[2]+din[3]+din[4]+din[5]+din[6]+din[7];
     din_q<=din;
    end 
    /*
    第一阶段:减少跳变沿
     将8bit数据转换为9bit:减少跳变沿
    */
    wire decision1;
    
     assign decision1=(n1d>4'd4)|((n1d==4'd4)&(din_q[0]==1'b0));  //当1的个数大于4或者1个数为4但是位0为0时,采用方案1
    wire[8:0]q_m;  //第一级阶段数据寄存
    assign q_m[0]=din_q[0];
    assign q_m[1]=decision1?(din_q[1]^~q_m[0]):(din_q[1]^q_m[0]);
    assign q_m[2]=decision1?(din_q[2]^~q_m[1]):(din_q[2]^q_m[1]);
    assign q_m[3]=decision1?(din_q[3]^~q_m[2]):(din_q[3]^q_m[2]);
    assign q_m[4]=decision1?(din_q[4]^~q_m[3]):(din_q[4]^q_m[3]);
    assign q_m[5]=decision1?(din_q[5]^~q_m[4]):(din_q[5]^q_m[4]);
    assign q_m[6]=decision1?(din_q[6]^~q_m[5]):(din_q[6]^q_m[5]);
    assign q_m[7]=decision1?(din_q[7]^~q_m[6]):(din_q[7]^q_m[6]);
    assign q_m[8]=decision1? 1 : 0 ;
    /*
    第二阶段:保持直流平衡
        对改善跳变次数的数据进行二次处理,跟踪传输过程中的01个数差异,以及当前码字中的01个数决定是否翻转字符,
        第10位表示是否进行了数据翻转
        该10位数据共460种组合,原始输入数据8位共256种组合,但是但考虑到到数据翻转以及bit8、bit9的规则约束,一共460种字符
    */
    reg [3:0] n1q_m;
    reg [3:0] n0q_m;  //计算q_m[8:0]中0和1的个数
    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]+q_m[8]; 
     n0q_m<=#1 9-(q_m[0]+q_m[1]+q_m[2]+q_m[3]+q_m[4]+q_m[5]+q_m[6]+q_m[7]+q_m[8]); 
    end 
    
    //控制字符参数定义
    parameter CTRLTOKEN0=10'b1101010100;
    parameter CTRLTOKEN1=10'b0010101011;
    parameter CTRLTOKEN2=10'b0101010100;
    parameter CTRLTOKEN3=10'b1010101011;
    /* 这个cnt在协议中专门强调:
        1、cnt=0时表示上次传输无数据流极性差异
        2、cnt>0,即cnt[4]=0表示上次数据流中传输了更多的1
        3、cnt<0,即cnt[4]=1表示上次数据流中传输了更多的0
    */
    reg [4:0]cnt;  //第二阶段类似于一个mealy型状态机,追踪传输流中的01个数差异,MSB为正负标志位置
    wire decision2,decision3;  //进而做出决断
    //cnt==0表示上次传输没有数据流极性差异
    //本次传输没有极性差异
    //所以运行无极性差异的流程
    assign decision2=(cnt==5'd0)|(n1q_m==n0q_m);
    //上次就传输的1多没本次数据中又是1多
    //
    assign decision3=((~cnt[4])&(n1q_m>n0q_m))|((cnt[4])&(n0q_m>n1q_m));
    /*
    流水线对齐   因为data经过了一个像素时钟的同步,此处控制信号还需要2次同步寄存,流水线时钟对齐
    */
    reg[9:0]q_m_reg;
    reg de_q,de_reg;
    reg c0_q,c0_reg;
    reg c1_q,c1_reg;
    
    always@(posedge clkin)begin
     q_m_reg<=q_m;
     de_q<=de;
     de_reg<=de_q;
     c0_q<=c0;
     c0_reg<=c0_q;
     c1_q<=c1;
     c1_reg<=c1_q;
    end 
    //10bit输出
    always@(posedge clkin)begin
     if(rstin)begin
      dout<=0;
      cnt<=0;
     end 
     else begin
      if(de_reg)begin  //数据使能
       if(decision2)begin
        dout[9]<=#1 ~q_m_reg[8];  //bit9是数据翻转标志位
        dout[8]<=#1 q_m_reg[8];  //符号位不变
        /*
        n0q_m-n1q_m=1时,0多,将数据直接发出去,0多
        n0q_m-n1q_m=0时,1多,将数据取反发出去,0多
        */
        dout[7:0]<=(q_m_reg[8])?q_m_reg[7:0]:~q_m_reg[7:0];
    
    /*
        在之前直流平衡状态时,q_m_reg[8]=0表示原始数据中1多,然后将数据取反发送出去,取反之后0多,所以用0个数-1个数
        若n0q_m=n1q_m,皆可
        该语句的变形
        if(cnt==0)begin
         if(1'b1==q_m_reg[8])  //即原始数据经过处理后0多
          cnt<=n1q_m-n0q_m;  //得到一个负值~~表示直流偏移负极性
         else                 //原始数据中1多,取反后0多
          cnt<=n0q_m-n1q_m;  //得到一个负值,表示多发了0,直流偏向负极性
        end 
        else begin 
             cnt<=cnt;  //不变
        end 
        */
        cnt<=#1 (~q_m_reg[8])?(cnt+(n0q_m-n1q_m)):(cnt-(n0q_m-n1q_m));
       end else begin
        if(decision3)begin
         dout[9]<=#1 1;  //极性必须翻转,因为不反转的话加重直流偏移
         dout[8]<=#1 q_m_reg[8];
         dout[7:0]<=#1 ~q_m_reg[7:0];
         cnt<=#1 cnt+{q_m_reg,1'b0}+(n0q_m-n1q_m);
       end 
       else begin
        dout[9]  <=#1 1'b0;
        dout[8]  <=#1 q_m_reg[8];
        dout[7:0]<=#1 q_m_reg[7:0];
        cnt<=#1 cnt-{~q_m_reg[8],1'b0}+(n1q_m-n0q_m);
       end 
    
      end 
      end else begin
       case({c1_reg,c0_reg})   //
       2'b00: dout<=#1 CTRLTOKEN0;
       2'b01: dout<=#1 CTRLTOKEN1; 
       2'b10: dout<=#1 CTRLTOKEN2;
       2'b11: dout<=#1 CTRLTOKEN3;  
       endcase
       cnt<=#1 0;  //每次数据使能结束清零计数器
      end 
     end 
    end  
    
    endmodule
  • 相关阅读:
    配置Xmanager远程登录
    如何为ubuntu等Linux系统扩容(LVM)
    CentOS7配置iptables防火墙
    Cetnos搭建vsftp服务器
    vim设置
    zabbix 问题汇总
    转:常用验证正则表达式
    C#对象序列化成XML,以及自定义标签名
    改变FileUpload文件上传控件的显示方式,确认后上传
    改变FileUpload文件上传控件的显示方式,选择文件后自动上传
  • 原文地址:https://www.cnblogs.com/luxinshuo/p/13685499.html
Copyright © 2011-2022 走看看