whole VHDL program for baud rate generator
module baudrate(sysclk,rst_b, sel, bclkx8,bclk);
input sysclk,rst_b;
input [2:0] sel;
output bclkx8,bclk;
reg [3:0] ctr1;
reg [7:0] ctr2;
reg [2:0] ctr3;
wire clkdiv13;
initial
begin
ctr1=4'd0;
end
initial
begin
ctr2=8'd0;
end
initial
begin
ctr3=3'd0;
end
always@(posedge sysclk or negedge rst_b)
begin
if(!rst_b)
ctr1=4'd0;
else if(ctr1==4'b1100)
ctr1=4'd0;
else
ctr1=ctr1+4'd1;
end
assign clkdiv13=ctr1[3];
always@(posedge clkdiv13)
ctr2=ctr2+8'd1;
assign bclkx8=ctr2[sel];
always@(posedge bclkx8)
begin
ctr3=ctr3+3'd1;
end
assign bclk=ctr3[2];
endmodule
module baudtransmitter(bclk,sysclk,rst,tdre,loadtdr,dbus,settdre,txd);
input bclk,sysclk,rst,tdre,loadtdr;
input [7:0]dbus;
output settdre,txd;
parameter idle=2'b00,synch=2'b01,tdata=2'b10;
reg [8:0]tsr;
reg [7:0]tdr;
reg [3:0]bct;
reg [1:0] state, nextstate;
reg inc, clr,loadtsr,shfttsr,start ,bclkdelayed;
wire bclkrising;
assign txd=tsr[0];
assign settdre=loadtsr;
assign bclkrising = bclk & (! bclkdelayed);
always@(state,tdre,bct,bclkrising)
begin
inc=1'b0; clr=1'b0; loadtsr=1'b0; shfttsr=1'b0; start=1'b0;
case(state)
idle: if(tdre==1'b0)
begin
loadtsr=1'b1;
nextstate=synch;
end
else nextstate=idle;
synch: if( bclkrising==1'b1 ) begin
start=1'b1;nextstate=tdata;
end
else nextstate=synch;
tdata: if( bclkrising==1'b0 ) nextstate=tdata;
else if(bct != 4'b1001)begin shfttsr=1'b1; inc=1'b1; nextstate=tdata; end
else begin clr=1'b1; nextstate=idle;end
endcase
end
always@( posedge sysclk or negedge rst)
begin
if(!rst)
begin
tsr=8'b11111111; state=idle; bct=1'b0; bclkdelayed=1'b0;
end
else
begin
state=nextstate;
if(clr==1'b1) bct=4'b0000;
else if (inc==1'b1) bct=bct+4'b0001;
if(loadtdr==1'b1) tdr=dbus;
if(loadtsr==1'b1) tsr={tdr,1'b1};
if(start==1'b1) tsr[0]=1'b0;
if(shfttsr==1'b1) tsr={1'b1 , tsr[8:1]};
bclkdelayed=bclk;
end
end
endmodule
module uart(sel,dbus,sysclk,rst,loadtdr,tdre,settdre,txd);
input sysclk,rst,loadtdr,tdre;
input[2:0]sel;
input[7:0]dbus;
output settdre,txd;
wire tclk;
baudrate b1(sysclk, rst, sel, bclkx8, tclk);
tx b2(tclk, sysclk, rst, tdre, loadtdr, dbus, settdre, txd);
endmodule
module rx(rxd, bclkx8, sysclk, rst, rdrf, rdr, setrdrf, setoe, setfe);
input rxd;
input bclkx8;
input sysclk;
input rst;
input rdrf;
output [7:0] rdr;
output setrdrf;
output setoe;
output setfe;
reg [1:0]state,nextstate;
reg [7:0] rsr,rdr;
reg [2:0]ct1;
reg[3:0]ct2;
reg clr1,clr2,inc1,inc2,loadrdr,shftrsr;
reg bclkx8dlayed;
reg setrdrf,setoe,setfe;
wire bclkrising;
assign bclkx8rising= bclkx8 & (~bclkx8dlayed);
always@(state,rxd,rdrf,ct1,ct2,bclkx8rising)
begin
inc1=1'b0;
inc2=1'b0;
clr1=1'b0;
clr2=1'b0;
shftrsr=1'b0;
loadrdr=1'b0;
setrdrf=1'b0;
setoe=1'b0;
setfe=1'b0;
case(state)
2'b00:begin
if(rxd==1'b0)
nextstate=2'b01;
else
nextstate=2'b00;
end
2'b01:begin
if(bclkrising==1'b0)
nextstate=2'b01;
else if(rxd==1'b1)
begin
clr1=1'b1;nextstate=2'b00;
end
else if(3'b011)
begin
clr1=1'b0;nextstate=2'b10;
end
else
begin
inc1=1'b1;nextstate=2'b01;
end
end
2'b10:begin
if(bclkrising==1'b0)
nextstate=2'b10;
else
begin
inc1=1'b1;
if(ct1!=3'b111)
nextstate=2'b10;
else if(ct2!=4'b1000)
begin
shftrsr=1'b1;inc2=1'b1;clr1=1'b1;
nextstate=2'b10;
end
else
begin
nextstate=2'b00;setrdrf=1'b1;
clr1=1'b1;
clr2=1'b1;
if(rdrf==1'b1)
setoe=1'b1;
else if(rxd==1'b0)
setfe=1'b1;
else
loadrdr=1'b1;
end
end
end
endcase
end
always@(posedge sysclk or negedge rst)
begin
if(!rst)
begin
state=2'b00; bclkx8dlayed=1'b0;
clr1=1'b0;
clr2=1'b0;
end
else
begin
state=nextstate;
if(clr1==1'b1)
ct1=1'b0;
else if(inc1==1'b1)
ct1=ct1+1'b1;
if(clr2==1'b1)
ct2=1'b0;
else if(inc2==1'b1)
ct2=ct2+1'b1;
if(shftrsr==1'b1)
rsr={rxd,rsr[7:1]};
if(loadrdr==1'b1)
rdr=rsr;
bclkx8dlayed=bclkx8;
end
end
endmodule
No comments:
Post a Comment