并转串——串转并
要求:并行输入1 byte,串行输出,无数据时输出高电平,输出格式1100+8bit+奇偶校验+0011(停止位)
串行输入,并行输出,检测是否奇偶校验错误,是否有帧传输错误
传输每bit数据占16个clock周期
//transmitter.v
module transmitter(in_clk,
in_resetn,
in_Data,
in_DataEnable,
out_NextData,
out_Bit
);
input in_clk;
input in_resetn;
input in_DataEnable;
input [7:0] in_Data;
output out_NextData;
output out_Bit;
parameter IDLE="16",STOP1=10,STOP2=11,STOP3=12,STOP4=13,START1=14,START2=15,START=1,D1=1,D2=2,D3=3,D4=4,D5=5,D6=6,D7=7,D8=8,PARITY=9;
reg [3:0] st, next_st;
reg [3:0] ClkCounter;
reg [8:0] StoredData;
reg out_NextData;
reg out_Bit;
reg oBit;
always @(posedge in_clk or negedge in_resetn)
if(!in_resetn)
st <= IDLE;
else
st <= next_st;
always @(posedge in_clk or negedge in_resetn)
if(!in_resetn)
ClkCounter <= 0;
else
ClkCounter <= ClkCounter + 1;
always @(ClkCounter or st or in_DataEnable)
if(ClkCounter != 0)
next_st =st;
else
case(st)
IDLE: if(in_DataEnable) next_st = STOP3;
STOP3: next_st = STOP4;
STOP4: next_st =START1;
START1: next_st = START2;
START2: next_st = D1;
D1: next_st = D2;
D2: next_st = D3;
D3: next_st =D4;
D4:next_st = D5;
D5: next_st =D6;
D6: next_st = D7;
D7: next_st =D8;
D8: next_st = PARITY;
PARITY: next_st = STOP1;
STOP1:next_st = STOP2;
STOP2: next_st = STOP3;
STOP3: next_st = STOP4;
default: next_st = STOP3;
endcase
always @(posedge in_clk or negedge in_resetn)
if(!in_resetn)
StoredData <= 0;
else if(in_DataEnable)
StoredData <= {in_Data,^in_Data};
always @(st or StoredData)
case(st)
IDLE: oBit="1";
STOP1,STOP2: oBit = 0;
STOP3,STOP4: oBit = 1;
START1,START2:oBit = 0;
D1:oBit = StoredData[8];
D2:oBit = StoredData[7];
D3:oBit = StoredData[6];
D4:oBit = StoredData[5];
D5:oBit = StoredData[4];
D6:oBit = StoredData[3];
D7:oBit = StoredData[2];
D8:oBit = StoredData[1];
PARITY:oBit = StoredData[0];
default: oBit = 1;
endcase
always @(posedge in_clk or negedge in_resetn)
if(!in_resetn)
out_Bit <= 1;
else
out_Bit <= oBit;
always @(st)
if(st==STOP4)
out_NextData =1;
else
out_NextData =0;
endmodule
//receiver.v
module receiver(in_clk,
in_resetn,
in_bit,
out_Data,
out_DataEnable,
out_ParityError,
out_FrameError
);
input in_clk;
input in_resetn;
input in_bit;
output [7:0] out_Data;
output out_DataEnable;
output out_ParityError;
output out_FrameError;
reg [63:0] DetectSequence;
reg [3:0] ClkCounter;
reg [3:0] st, next_st;
reg [7:0] out_Data;
reg [7:0] store_data;
reg Parity;
reg Frame;
reg out_DataEnable;
reg out_ParityError;
reg out_FrameError;
parameter IDLE="0", D1=1,D2=2,D3=3,D4=4,D5=5,D6=6,D7=7,D8=8,PARITY=9,STOP1=10,STOP2=11,STOP3=12,STOP4=13;
//detect
always @(posedge in_clk or negedge in_resetn)
if(!in_resetn)
DetectSequence <= 0;
else
DetectSequence <= { DetectSequence [62:0],in_bit};
assign DetectNewFrame = DetectSequence == 64'hFFFFFFFF00000000;
always @(posedge in_clk or negedge in_resetn)
if(!in_resetn)
ClkCounter <= 0;
else if (DetectNewFrame)
ClkCounter <= 0;
else
ClkCounter <= ClkCounter + 1'b1;
always @(posedge in_clk or negedge in_resetn)
if(!in_resetn)
st <= IDLE;
else
st <= next_st;
always @(ClkCounter or st or DetectNewFrame)
if(ClkCounter != 0)
next_st <= st;
else
case(st)
IDLE: if (DetectNewFrame) next_st = D1;
D1: next_st = D2;
D2: next_st = D3;
D3: next_st =D4;
D4:next_st = D5;
D5: next_st =D6;
D6: next_st = D7;
D7: next_st =D8;
D8: next_st = PARITY;
PARITY: next_st = STOP1;
STOP1:next_st = STOP2;
STOP2: next_st = STOP3;
STOP3: next_st = STOP4;
STOP4: next_st = IDLE;
default: next_st = IDLE;
endcase
always @(posedge in_clk or negedge in_resetn)
if(!in_resetn)
begin
out_Data=0;
Parity="0";
out_FrameError=0;
end
else if(ClkCounter ==8)
case(st)
D1: store_data[7]=in_bit;
D2: store_data[6]=in_bit;
D3: store_data[5]=in_bit;
D4: store_data[4]=in_bit;
D5: store_data[3]=in_bit;
D6: store_data[2]=in_bit;
D7: store_data[1]= in_bit;
D8:
begin
store_data[0]=in_bit;
out_Data[7:0] = store_data[7:0];
end
PARITY: Parity="in"_bit;
STOP1: if(!in_bit) out_FrameError =1;
else out_FrameError = 0;
STOP2: if(!in_bit) out_FrameError =1;
else out_FrameError = 0;
STOP3: if(in_bit) out_FrameError =1;
else out_FrameError = 0;
STOP4: if(in_bit) out_FrameError =1;
else out_FrameError = 0;
endcase
always @(st or in_bit or Parity or out_Data)
if((st == STOP4) & (in_bit))
begin
out_DataEnable = 1;
out_ParityError = (Parity != ^out_Data);
end
else
begin
out_DataEnable = 0;
out_ParityError = 0;
end
endmodule
//test.v
module testbench1();
reg Clk,Reset;
wire BitWire;
reg [3:0] ClkCounter;
reg in_DataEnable;
reg [7:0] in_Data;
wire [7:0] out_Data;
//connect transmitter and receiver
transmitter DUT1(.in_clk(Clk),
.in_resetn(Reset),
.in_Data(in_Data),
.in_DataEnable(in_DataEnable),
.out_NextData(NextData),
.out_Bit(BitWire)
);
receiver DUT2(.in_clk(Clk),
.in_resetn(Reset),
.in_bit(BitWire),
.out_Data(out_Data),
.out_DataEnable(out_DataEnable),
.out_ParityError(out_ParityError),
.out_FrameError(out_FrameErrror)
);
initial
begin
$dumpfile("uart.vcd");
$dumpvars;
$dumpon;
Clk = 1'b0;
Reset = 1'b0;
#100 Reset="1"'b1;
end
always #5
Clk <= !Clk;
always @(posedge Clk or negedge Reset)
if(!Reset)
ClkCounter <= 0;
else
ClkCounter <= ClkCounter + 1;
always @(posedge Clk or negedge Reset )
if(!Reset)
begin
in_Data=8'b0;
in_DataEnable =1'b0;
end
else
begin
if((NextData) & (ClkCounter == 0))
begin
in_Data=$random;
in_DataEnable =1'b1;
$display("Issue data %h", in_Data);
end
else
begin
//in_Data=8'b0;
in_DataEnable =1'b0;
end
end
always @(posedge Clk)
if(out_DataEnable)
begin
if(out_ParityError)
$display("Parity Error");
else if (out_FrameErrror)
$display("Frame Error");
else
$display("Receiver data %h", out_Data);
end
endmodule
文章评论(0条评论)
登录后参与讨论