[精品]曼彻斯特码
曼彻斯特码
1、 将10111001换成曼彻斯特编码.
解:根据基本曼彻斯特编码原理和差分曼彻斯特编码原理将10111001换成曼彻斯特编码
如下
:
原码 基本曼彻斯特编码 差分曼彻斯特编码
10111001 1001101010010110 1010011001010110
2、 曼彻斯特码的编码原理是:由每位的中间为采样时间,如果电平由
高电平跳变为低电平,则为“1”;反之则为“0”;
3、 差分曼彻斯特码的编码原理是:由每位的开始是否存在电压跳变,
如果有,则为“0”,反之为“1”。
今天看了一下从fpga上下的曼彻斯特编解码的程序,感觉不是很清楚,仿真了一下,更迷茫了,大家看看为啥这程序要这么编呢,
程序比较长,不过写的应该还是不错的,看了后应该有收获。
总的思路是这样:
1 通过一个高频的时钟检测wrn信号,如果检测到上升沿,则表明开始编码,将输入的8位数据转为串行,并编码,然后输出。
2 定时信号是从高频时钟16分频后得到的,在wrn上升沿后16分频使能,在编码结束后禁止分频输出。
3 no_bits_sent记录串行输出的位数,应该是从0010到1001输出串行信号,到1010时编码结束,输出tbre表明编码完成。
问题是no_bits_sent在到了1010后还是会继续增加,直到1111,然后clk1x_enable 就为0,无法分频,clk1x就为一直流信号。这样当clk1x_enable再次为1的时候,no_bits_sent也不会增加,在1111上不变,clk1x_enable又会回到0了。
//*****************************************************************************
*
*
* File Name: me.v
* Version: 1.0
* Date: January 22, 2000
* Model: Manchester Encoder Chip
*
* Company: Xilinx
*
*
* Disclaimer: THESE DESIGNS ARE PROVIDED "AS IS" WITH NO WARRANTY
* WHATSOEVER AND XILINX SPECIFICALLY DISCLAIMS ANY * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR * A PARTICULAR PURPOSE, OR AGAINST INFRINGEMENT. *
* Copyright (c) 2000 Xilinx, Inc.
* All rights reserved
*
******************************************************************************/
module me (rst,clk16x,wrn,din,tbre,mdo) ; input rst ;
input clk16x ;
input wrn ;
input [7:0] din ;
output tbre ;
output mdo ;
wire clk1x ;
reg clk1x_enable ;
wire clk1x_disable ;
reg [3:0] clkdiv ;
reg [3:0] no_bits_sent ;
wire mdo ;
reg tbre ;
reg [7:0] tsr ;
reg [7:0] tbr ;
reg parity ;
reg wrn1 ;
reg wrn2 ;
// form 2 FF register for write pulse detection
always @(posedge rst or posedge clk16x) if (rst)
begin
wrn2 <= 1'b1 ;
wrn1 <= 1'b1 ;
end
else
begin
wrn2 <= wrn1 ;
wrn1 <= wrn ;
end
// Enable clock when detect edge on write pulse
always @(posedge rst or posedge clk16x) begin
if (rst)
clk1x_enable <= 1'b0 ;
else if (wrn1 == 1'b1 && wrn2 == 1'b0) clk1x_enable <= 1'b1 ;
else if (no_bits_sent == 4'b1111) clk1x_enable <= 1'b0 ;
end
// Generate Transmit Buffer Register Empty signal
always @(posedge rst or posedge clk16x) begin
if (rst)
tbre <= 1'b1 ;
else if (wrn1 == 1'b1 && wrn2 == 1'b0) tbre <= 1'b0 ;
else if (no_bits_sent == 4'b1010) tbre <= 1'b1 ;
else
tbre <= 1'b0 ;
end
// Detect edge on write pulse to load transmit buffer
always @(posedge rst or posedge clk16x) begin
if (rst)
tbr <= 8'h0 ;
else if (wrn1 == 1'b1 && wrn2 == 1'b0) tbr <= din ;
end
// Increment clock
always @(posedge rst or posedge clk16x) begin
if (rst)
clkdiv <= 4'b0000 ;
else if (clk1x_enable == 1'b1)
clkdiv <= clkdiv + 1 ;
end
assign clk1x = clkdiv[3] ;
// Load TSR from TBR, shift TSR always @(posedge rst or posedge clk1x) begin
if (rst)
tsr <= 8'h0 ;
else if (no_bits_sent == 4'b0001) tsr <= tbr ;
else if (no_bits_sent >= 4'b0010 && no_bits_sent < 4'b1010)
begin
tsr[7:1] <= tsr[6:0] ;
tsr[0] <= 1'b0 ;
end
end
// Generate Manchester data from NRZ assign mdo = tsr[7] ^ clk1x ; // Generate parity
always @(posedge rst or posedge clk1x) begin
if (rst)
parity <= 1'b0 ;
else
parity <= parity ^ tsr[7] ; end
// Calculate number of bits sent always @(posedge rst or posedge clk1x) begin
if (rst)
no_bits_sent <= 4'b0000 ;
else if (clk1x_enable)
no_bits_sent <= no_bits_sent + 1 ; // else if (no_bits_sent == 4'b1111) else if (clk1x_disable)
no_bits_sent <= 4'b0000 ;
end
assign clk1x_disable = !clk1x_enable ; endmodule
测试程序:
(其中的系统
编译有问题,可以删去)
`timescale 1 ns / 1 ns
module me_tf ;
reg [7:0] din ;
reg rst ;
reg clk ;
reg wr ;
wire mdo ;
wire ready ;
me u1 (rst,clk,wr,din,ready,mdo) ; initial begin
rst = 1'b0 ;
clk = 1'b0 ;
din = 8'h0 ;
wr = 1'b0 ;
me.clk1 = 1'b0 ;
me.count = 3'b0 ;
end
integer me_chann ;
initial begin
me_chann = $fopen("me.rpt") ; $timeformat(-9,,,5) ;
end
parameter clock_period = 10 ; setup_time = clock_period/4 ; always #(clock_period/2) clk = ~clk ; initial begin
$fdisplay(me_chann, "Verilog simulation of Manchester encoder\n\n:);
$shm_open("me.shm") ;
$shm_probe("AS") ;
$fmonitor(me_chann,"%ime=%t,rst=%b,wr=%b,me.clk=%b,din=%h,me.count=%b
,mdo=%b,ready=%b",$time,rst,wr,clk,me.clk1,din,me.count,mdo,ready) ;
#5 rst = 1'b1;
#15 rst = 1'b0 ;
#(3 * clock_period - setup_time) din = 8'hff ;
#(1 * clock_period) wr = 1'b1 ; #(1 * clock_period) wr = 1'b0 ; #(20 * clock_period) din = 8'haa ; #(1 * clock_period) wr = 1'b1 ; #(1 * clock_period) wr = 1'b0 ; #(20 * clock_period) din = 8'h00 ; #(1 * clock_period) wr = 1'b1 ; #(1 * clock_period) wr = 1'b0 ; #(20 * clock_period) din = 8'hf0 ; #(1 * clock_period) wr = 1'b1 ; #(1 * clock_period) wr = 1'b0 ; #(20 * clock_period) din = 8'h0f ; #(1 * clock_period) wr = 1'b1 ; #(1 * clock_period) wr = 1'b0 ; #(100 * clock_period) ;
$fdisplay (me_chann,"\nSimulation of Manchester encoder complete.");
$finish ;
end
endmodule