NRZ与CMI编码及FPGA代码的实现


NRZ

NRZ指的是不归零码(NRZ,Non-Return to Zero)

CMI

CMI(Coded Mark Inversion)码是传号反转码的简称,与双相码类似,它也是一种双极性二电平码。其编码规则是“1”码交替用“11”和“00”两位码表示;“0”码固定地用“01”表示。

不确定代码的正确性,只是提供一个思路

 1 ///////////////////////////////////////////////////////////
 2 //  module test(clk,out1,out2,out3,clk_1,clk_2,clk_3);
 3 module test(clk,out1,out2,out3);
 4 input clk ;//声明输入硬件的时钟信号
 5 
 6 output out1,out2,out3;//声明三个输出
 7 
 8 reg out1=1'b0,out2=1'b0,out3=1'b0;//三个输出初始化
 9 
10 reg [4:0] counter1 =4'd0 ;//初始化学号输出时序计数器
11 reg [4:0] counter2 =2'd0 ;//初始化cmi码计数器
12 reg [4:0] counter3 =4'd0 ;
13 
14 reg [1:0] t1= 2'b00;
15 reg t0 = 1'b0;   //编码中间量
16 reg r0 = 1'b0,r1 = 1'b0,r11 = 1'b0//译码中间量
17 
18 reg clk_1= 1'b0;
19 reg clk_2= 1'b0;
20 ////////////////////////////////////////////////////////////
21 always @(posedge clk)  //产生240k时钟
22     if(counter1 == 3'd7 )
23         begin
24             counter1 <= 3'd0;
25             clk_1 <= ~clk_1;
26         end 
27     else 
28         counter1 <= counter1 + 1'd1;            
29 //////////////////////////////////////////////////////
30 always @(posedge clk)   //产生480k时钟
31     if(counter2 == 2'd3 )
32         begin
33             counter2 <= 2'd0;
34             clk_2 <= ~clk_2;
35         end 
36     else 
37          counter2 <= counter2 + 1'd1;
38 /////////////////////////////////////////////////////////    
39 always @(posedge clk_1)  // 产生NRZ码 , 学号0072
40     if(counter3 == 4'd14)  
41         begin
42             counter3 <= 4'd0;
43             out1 <= 1'b0;
44         end    
45     else 
46         begin 
47             casez (counter3)
48                 4'd1011 : out1 <= 1'b1;
49                 4'b1000 : out1 <= 1'b1;
50                 default : out1 <= 1'b0;
51             endcase
52             counter3 <= counter3 + 1'd1;
53         end      
54 //////////////////////////////////////////////////
55 always @(posedge clk_2)//  CMI编码
56     if(out1 == 1'b0)//当学号输出为0时
57         begin
58             if(t0 == 0)//因为cmi编码0为01,为两位,所以取一个标志位t0,当t0为0时,输出01的第一位,t0为1时,输出01的第二位。
59                 out2 <= 0;
60             else
61                 out2 <= 1;
62             t0 <=~t0;
63         end
64     else
65         begin
66             if(t1[1] == 0)
67 //这里与上面类似,因为1为00和11,交替变换,所以标志位t1为两位,当学号为1时,一开始想输出为11,输出为1,后面00加01,为01,输出为0,
68 //再后面学号再次为1时,01加01为10,这时输出为1,后面10加01为11,输出为1,之后再if结束后加01为00
69                 out2 <= 1;
70             else
71                 out2 <= 0;
72             t1 <= t1+2'b01;
73         end
74 ///////////////////////////////////////////////////
75 always @(posedge clk_2)   //  CMI译码
76     if(r11 == 1'b0)//将out2的输出即cmi编码的值赋给r0和r1,二者取与,结果为0则编码结果为0,结果为1则编码结果为1
77         begin
78             out3 <= (r0 ^ r1);//r11这里相当于一个分配out2的标志位,因为out2的输出只能一位一位输出,所以r11为0时,将out2的值给r0,r11为1时,将out2的值给r1
79             r0 <= out2;
80             r11 <= ~r11;
81         end
82     else
83         begin
84             r1 <= out2;
85             r11 <= ~r11;    
86         end
87 
88 endmodule