碼字轉換器能夠將數據流變換成一種已編碼的格式,使接受機能夠恢復數據。接下來介紹四種常用的串行編碼方法。
如果非歸零碼(NRZ)格式的數據流中,沒有1或0的長序列,那么采用鎖相環電路PLL就可以從該線數據中恢復出時鍾(即將其自身與數據時鍾同步);如果非歸零反轉碼(NRZI)或者歸零碼(RZ)格式的數據流中不存在0的長序列,時鍾就可以從數據流中恢復出來。由於曼徹斯特(Manchester)碼從數據中恢復時鍾時與數據無關,因而很有吸引力,不過它需要更大的帶寬。
首先給出Mealy型狀態機表示的轉換器代碼及其測試代碼
/*Mealy型狀態機輸出不僅與當前狀態有關,還與輸入有關*/ module NRZ_to_Manchester_Mealy( output reg B_out, input B_in, clk, reset_b ); parameter S_0=2'd0, S_1=2'd1, S_2=2'd2, dont_care_state=2'bx, dont_care_out=1'bx; reg[1:0] state, next_state; always@(posedge clk or negedge reset_b) if(!reset_b) state<=S_0; else state<=next_state; always @(state, B_in)begin //這里的敏感列表最好不要包含B_in,否則會有無效輸出 //Mealy型狀態機輸出雖然與輸入有關,但不一定因輸入而變化,只會 //因輸入有不同的變化 B_out=0; case(state) S_0:if(B_in)begin B_out=1; next_state=S_1; end else next_state=S_2; S_1: next_state=S_0; S_2:begin next_state=S_0; B_out=1; end default:begin next_state=dont_care_state; B_out=dont_care_out; end endcase end endmodule
測試代碼:
module NRZ_to_Manchester_Mealy_tb; reg clk, reset_b; reg B_in; wire B_out; reg count; initial begin clk=0; reset_b=1; B_in=0; count=0; #20 reset_b=0; #10 reset_b=1; #10000 $finish; end initial begin $dumpfile("dump.lxt"); $dumpvars(0,NRZ_to_Manchester_Mealy_tb); end initial forever #10 clk=!clk; always @(posedge clk) count=count+1; always @(negedge clk) if(count) B_in={$random}%2; NRZ_to_Manchester_Mealy uut( .B_out(B_out), .B_in(B_in), .clk(clk), .reset_b(reset_b) ); endmodule
對於Moore型狀態機所表示的轉換器,輸出只與狀態有關,而與輸入無關。在下面的代碼中B_out只受next_state影響,如果由state確定B_out,輸出會增加一個時鍾周期的延時。
同時Moore型狀態機必須為每一種情況定義一個狀態,以便輸出能夠完全依靠狀態決定。轉換器代碼如下:
module NRZ_to_Manchester_Moore( output reg B_out, input B_in, input clk,reset_b ); parameter S_0=2'b00, S_1=2'b01, S_2=2'b10, S_3=2'b11, dont_care_state=2'bxx, dont_care_out=1'bx; reg[1:0] state, next_state; always @(posedge clk or negedge reset_b) if(!reset_b) state<=S_0; else state<=next_state; always @(state)begin case(state) S_0:if(B_in) next_state=S_1; else next_state=S_2; S_1: next_state=S_3; S_2: next_state=S_0; S_3:if(B_in) next_state=S_1; else next_state=S_2; endcase end always @(next_state)begin B_out=0; case(next_state) S_0:B_out=1; S_1:B_out=1; S_2:B_out=0; S_3:B_out=0; endcase end endmodule
測試代碼同Mealy型轉換器相同,不再贅述。