實(shí)驗(yàn)簡述
將輸入的數(shù)據(jù)流經(jīng)過曼徹斯特編碼器編碼后經(jīng)過解碼器恢復(fù)為原來的輸入序列。
一、曼徹斯特碼簡介
曼徹斯特碼(Manchester code),又稱數(shù)字雙向碼、分相碼或相位編碼(PE),是一種常用的二源碼線路編碼方式之一,被物理層使用來編碼一個(gè)同步位流的時(shí)鐘和數(shù)據(jù)。在通信技術(shù)中,用來表示所要發(fā)送比特流中的數(shù)據(jù)宇定時(shí)信號(hào)所結(jié)合起來的代碼。常用在以太網(wǎng)通信,列車總線控制,工業(yè)總線等領(lǐng)域。
二、編碼規(guī)則
有兩個(gè)輸入時(shí)鐘,一個(gè)是基帶時(shí)鐘(起同步信號(hào)作用),一個(gè)是頻帶時(shí)鐘。輸入的數(shù)據(jù)流是基帶時(shí)鐘域信號(hào),經(jīng)過編碼后變成頻帶時(shí)鐘域信號(hào)輸出。曼徹斯特編碼是將輸入為1的變成輸出前半拍為1,后半拍為0,輸入為0的變成前半拍為0,后半拍為1的頻帶信號(hào)。
三、時(shí)序圖
輸入序列以101為例,經(jīng)過編碼后應(yīng)為100110
四、FPGA實(shí)現(xiàn)
1、頂層架構(gòu)
2、信號(hào)說明
信號(hào) | 功能 | 說明 |
clk_b | 基帶時(shí)鐘,作為同步信號(hào)使用 | 外部輸入 |
clk_f | 頻帶時(shí)鐘,系統(tǒng)工作時(shí)鐘 | 外部輸入 |
rst_n | 系統(tǒng)復(fù)位 | 外部輸入 |
enc_in | 輸入數(shù)據(jù)流 | 外部輸入 |
enc_en | 編碼使能 | 外部輸入 |
enc_out | 數(shù)據(jù)流經(jīng)編碼后的輸出,輸入到解碼模塊 | 編碼輸出,解碼輸入 |
dec_en | 解碼使能 | 外部輸入 |
dec_out | 解碼輸出 | 輸出 |
3、頂層代碼
module manchester(clk_b, clk_f, rst_n, enc_in, enc_en, dec_out, dec_en); input clk_b, clk_f, rst_n; input enc_in; input enc_en; output dec_out; input dec_en;
wire enc_out;
manchester_enc ENC( .clk_f(clk_f), .clk_b(clk_b), .rst_n(rst_n), .enc_en(enc_en), .enc_in(enc_in), .enc_out(enc_out) );
manchester_dec DEC( .clk_f(clk_f), .clk_b(clk_b), .rst_n(rst_n), .dec_en(dec_en), .enc_out(enc_out), .dec_out(dec_out) );
endmodule |
4、編碼模塊
采用狀態(tài)機(jī)來實(shí)現(xiàn)編碼模塊。
當(dāng)檢測(cè)到編碼使能為高時(shí),狀態(tài)機(jī)開始執(zhí)行,判斷clk_b的值為1時(shí),在S1狀態(tài)等待,當(dāng)clk_b的值為0時(shí),判斷輸入的值是1還是0。(clk_b主要起基頻同步作用)如果是1,跳轉(zhuǎn)到S2狀態(tài),并將enc_out賦值為1。到S2狀態(tài)后,無條件跳回S1狀態(tài),并將enc_out賦值為0。如果是0,跳轉(zhuǎn)到S3狀態(tài),并將enc_out賦值為0。到S3狀態(tài)后,無條件跳回S1狀態(tài),并將enc_out賦值為1。
狀態(tài)轉(zhuǎn)移圖如下:
說明:圓圈代表狀態(tài),→ 代表轉(zhuǎn)移,轉(zhuǎn)移下面的文本框代表轉(zhuǎn)移時(shí)的動(dòng)作。以后文章的狀態(tài)轉(zhuǎn)移圖均按此繪制。
module manchester_enc(clk_f, clk_b, rst_n, enc_en, enc_in, enc_out); input clk_f, clk_b, rst_n; input enc_en; input enc_in; output reg enc_out;
reg [2:0] state_c, state_n;
localparam S1 = 3'b001; localparam S2 = 3'b010; localparam S3 = 3'b100;
wire S12S2_start ; wire S12S3_start ; wire S22S1_start ; wire S33S1_start ;
//四段式狀態(tài)機(jī) //第一段:同步時(shí)序always模塊,格式化描述次態(tài)寄存器遷移到現(xiàn)態(tài)寄存器(不需更改- always@(posedge clk_f or negedge rst_n)begin if(!rst_n)begin state_c <= S1; end else begin state_c <= state_n; end end //第二段:組合邏輯always模塊,描述狀態(tài)轉(zhuǎn)移條件判斍 always@(*)begin if(enc_en) case(state_c) S1:begin if(S12S2_start)begin state_n = S2; end else if(S12S3_start)begin state_n = S3; end else begin state_n = state_c; end end S2:begin if(S22S1_start)begin state_n = S1; end else begin state_n = state_c; end end S3:begin if(S33S1_start)begin state_n = S1; end else begin state_n = state_c; end end default:begin state_n = S1; end endcase else state_n = S1; end //第三段:設(shè)計(jì)轉(zhuǎn)移條件 assign S12S2_start = state_c==S1 && clk_b && !enc_in; assign S12S3_start = state_c==S1 && clk_b && enc_in; assign S22S1_start = state_c==S2 && 1; assign S33S1_start = state_c==S3 && 1; //第四段:同步時(shí)序always模塊,格式化描述寄存器輸出(可有多個(gè)輸出- always @(posedge clk_f or negedge rst_n)begin if(!rst_n)begin enc_out <=1'b0; //初始匍 end else if(enc_en) if((state_c==S1 && !enc_in) || (state_c==S3))begin enc_out <= 1'b0; end else if((state_c==S1 && enc_in) || (state_c==S2))begin enc_out <= 1'b1; end else begin enc_out <= 1'b0; end else enc_out <=1'b0; end endmodule |
5、解碼模塊
解碼模塊也采用狀態(tài)機(jī)實(shí)現(xiàn),當(dāng)檢測(cè)到dec_en為高時(shí),狀態(tài)機(jī)才執(zhí)行,判斷clk_b的值,當(dāng)clk_b為0時(shí),在S1上等待,當(dāng)clk_b為1時(shí),判斷enc_out的值,為1時(shí)跳轉(zhuǎn)到S2狀態(tài),并將dec_out賦值為。S2狀態(tài)無條件跳轉(zhuǎn)到S1狀態(tài)。為0時(shí),跳轉(zhuǎn)到S3狀態(tài)并將dec_out賦值為0。S3狀態(tài)無條件跳轉(zhuǎn)到S1狀態(tài)。
狀態(tài)轉(zhuǎn)移圖如下:
解碼模塊代碼
module manchester_dec(clk_f, clk_b, rst_n, dec_en, enc_out, dec_out); input clk_f, clk_b, rst_n; input dec_en; input enc_out; output reg dec_out;
reg [2:0] state_c, state_n;
localparam S1 = 3'b001; localparam S2 = 3'b010; localparam S3 = 3'b100;
wire S12S2_start ; wire S12S3_start ; wire S22S1_start ; wire S33S1_start ;
always@(posedge clk_f or negedge rst_n)begin if(!rst_n)begin state_c <= S1; end else begin state_c <= state_n; end end //第二段:組合邏輯always模塊,描述狀態(tài)轉(zhuǎn)移條件判斍 always@(*)begin if(dec_en) case(state_c) S1:begin if(S12S2_start)begin state_n = S2; end else if(S12S3_start)begin state_n = S3; end else begin state_n = state_c; end end S2:begin if(S22S1_start)begin state_n = S1; end else begin state_n = state_c; end end S3:begin if(S33S1_start)begin state_n = S1; end else begin state_n = state_c; end end default:begin state_n = S1; end endcase else state_n = S1; end //第三段:設(shè)計(jì)轉(zhuǎn)移條件 assign S12S2_start = state_c==S1 && (!clk_b) && enc_out; assign S12S3_start = state_c==S1 && (!clk_b) && (!enc_out); assign S22S1_start = state_c==S2 && 1; assign S33S1_start = state_c==S3 && 1; //第四段:同步時(shí)序always模塊,格式化描述寄存器輸出(可有多個(gè)輸出- always @(posedge clk_f or negedge rst_n)begin if(!rst_n)begin dec_out <=1'b0; //初始匍 end else if(dec_en) if(state_c==S1 && (!clk_b) && enc_out)begin dec_out <= 1'b1; end else if((state_c==S1 && (!clk_b) && (!enc_out)))begin dec_out <= 1'b0; end else begin dec_out <= dec_out; end else dec_out <=1'b0; end endmodule |
6、仿真驗(yàn)證
tb文件參考工程文件夾中的sim文件夾
輸入的數(shù)據(jù)流enc_in為1011,對(duì)應(yīng)的曼徹斯特碼應(yīng)為10011010
我們看到輸入到編碼模塊的enc_in與解碼模塊的dec_out的輸出是一樣的
再來看編碼之后的數(shù)據(jù)流
enc_out為10011010與結(jié)果一致
解碼模塊圖形
溫馨提示:明德?lián)P2023推出了全新課程——邏輯設(shè)計(jì)基本功修煉課,降低學(xué)習(xí)FPGA門檻的同時(shí),增加了學(xué)習(xí)的趣味性,并組織了考試贏積分活動(dòng)
http://m.cqqtmy.cn/ffkc/415.html
(點(diǎn)擊→了解課程詳情?)感興趣請(qǐng)聯(lián)系易老師:13112063618(微信同步)