Verilog 代码编写 FPGA 数字CMI编码

题目:

        试用 FPGA 实现如下 32bit 数据 32‘hCA535A7E CMI 码,FPGA 输入时钟 30M,码流输出时钟为 5M,给出代码并仿真。
分析:
       为了提高通信系统的有效性,一般需要对将要发送的数据进行 信源编码 ,通信信号信源编码的主要任务有两个:一是将信源送出的模拟信号数字化,即 A/D变换,用一定的数字脉冲组合来表示信号的一定幅度。通常将这种过程称为脉冲编码调制(PCM),简称为编码。二是提高信号传输的有效性,进行压缩编码。
         编码信号反转码(CMI 码) :编码信号反转码(CMI 码)是由 CCITT 建议、适合于光信道传输的码型之一。其具体的编码规则是:二进制代码中的“1”码交替 地用 “11”和“00”表示;“0”码则固定地用“01”表示 。CMI 码是一种二元码。CMI 码的特点是电平随二进制数码依次跳变,因而便于恢复定时信号,尤其当用负跳变直接提取定时信号时,不会产生相位不确定问题。其具有检测错误的能力,因为在这种传输码中,只有 00、11、01 这三种码组,而没有 10 这一码组。编码规则如图所示:

       为实现题目所需功能,需要设计一个编码模块,对输入数据进行编码,转换规则按照 CMI 的编码规则来编写,注意转码时钟的处理。由上图可知,一位的输入码字将编码为两位的码字,速率为原来的两倍。按照一位一位的转换,还需要一个将并行输入数据转为串行 的处理方法,这样就可以对每一位进行转换,完成编码过程。
       主要设计框图如下所示:

        设计代码如下:

//CMI 编码:
//二进制代码中的"1"码交替地用 "11"和"00"表示;"0"码则固定地用"01"表 示
module CMIcode(
 input clk,
 input rst,
 input [31:0]data,
 output [1:0]cmicode,
 output signal
);
parameter clkfreq=30000000, //系统时钟 30MHz
 datafreq=5000000,
 freqcnt=clkfreq/datafreq;
reg dataclk; //码流时钟
reg [3:0] cnt;
reg [7:0] N;
reg [1:0] cmicode;
reg signal;
reg DATA;
reg [4:0] i;
reg [4:0] bitcnt;
//分频产生 5MHz 时钟
always @(posedge clk or negedge rst) begin
 if(!rst) begin
 cnt<=1'b0;
 dataclk<=1'b0;
 end
 else if(cnt==(freqcnt>>1)-1'b1) begin
 dataclk<=~dataclk;
 cnt<=1'b0;
 end
 else
 cnt<=cnt+1'b1;
end
always@(posedge dataclk or negedge rst) begin 
 if(!rst) begin
 i<=5'd31;
 end
 else begin
 i<=i-1'b1;
 if(i==1'b0) begin
 i<=5'd31;
 end
 end
end
always@(posedge clk or negedge rst) begin 
 if(!rst) begin
 DATA<=1'b0;
 end
 else begin
 DATA<=data[i];
 end
end
always@(posedge dataclk or negedge rst) begin
 if(!rst) begin
 N<=0;
 cmicode<=0;
 end
 else begin
 if(DATA==1'b0) begin
 cmicode<=2'b01;
 end
 else begin
 N<=N+1'b1;
 if(N[0]==1'b0) begin
 cmicode<=2'b11;
 end
 else begin
 cmicode<=2'b00;
 end 
 if(N==32) begin
 N<=1'b0;
 end
 end 
 end
end
always@(posedge dataclk or negedge rst) begin
 if(!rst) begin
 signal<=1'b0;
 bitcnt<=1'b0;
 end
 else begin
 bitcnt<=bitcnt+1'b1;
 if(bitcnt==5'd31) begin
 signal<=1'b1;
 bitcnt<=1'b0;
 end
 else begin
 signal<=1'b0;
 end
 end
end
endmodule
       仿真的部分结果如下所示:
        由图可知,输入数值 32‘hCA535A7E 写成二进制形式后,被编码为 64 位的新二进制数,编码规则满足 CMI 编码,且在最后一位编码完毕后产生了脉冲,与理论结果一致,仿真正确。如按照一定速率传入所需要的输入数据,则可实现串行的 CMI 编码输出。
        仿真代码如下:
`timescale 1ns / 1ps
module CMIcode_tb();
reg clk;
reg rst;
reg [31:0] data;
wire [1:0] cmicode;
wire signal;
always #16.67 clk<=~clk;
initial begin
 clk<=1'b0;
 rst<=1'b0;
 data<=32'b0;
 #20 rst<=1'b1;
 #20 data<=32'hCA535A7E;
 
end
CMIcode code(
 .clk(clk),
 .rst(rst),
 .data(data),
 .cmicode(cmicode),
 .signal(signal)
);
endmodule

  • 1
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值