`timescale 1ns / 100ps
module uart (dout,data_ready,framing_error,parity_error,rxd,clk16x,rst,rdn,din,tbre,tsre,wrn,sdo);
output tbre ;
output tsre ;
output sdo ;
input [7:0] din ;
input rst ;
input clk16x ;
input wrn ;
input rxd ;
input rdn ;
output [7:0] dout ;
output data_ready ;
output framing_error ;
output parity_error ;
rcvr u1 (dout,data_ready,framing_error,parity_error,rxd,clk16x,rst,rdn) ;
txmit u2 (din,tbre,tsre,rst,clk16x,wrn,sdo) ;
endmodule
********************************************************************************************
`timescale 1 ns / 1 ns
module rcvr (dout,data_ready,framing_error,parity_error,rxd,clk16x,rst,rdn) ;
input rxd ;
input clk16x ;
input rst ;
input rdn ;
output [7:0] dout ;
output data_ready ;
output framing_error ;
output parity_error ;
reg rxd1 ;
reg rxd2 ;
reg clk1x_enable ;
reg [3:0] clkdiv ;
reg [7:0] rsr ;
reg [7:0] rbr ;
reg [3:0] no_bits_rcvd ;
reg data_ready ;
reg parity ;
reg parity_error ;
reg framing_error ;
wire clk1x ;
assign dout = !rdn ? rbr : 8'bz ;
always @(posedge clk16x or posedge rst)
begin
if (rst)
begin
rxd1 <= 1'b1 ;
rxd2 <= 1'b1 ;
end
else
begin
rxd1 <= rxd ;
rxd2 <= rxd1 ;
end
end
always @(posedge clk16x or posedge rst)
begin
if (rst)
clk1x_enable <= 1'b0;
else if (!rxd1 && rxd2)
clk1x_enable <= 1'b1 ;
else if (no_bits_rcvd == 4'b1100)
clk1x_enable <= 1'b0 ;
end
always @(posedge clk16x or posedge rst or negedge rdn)
begin
if (rst)
data_ready = 1'b0 ;
else if (!rdn)
data_ready = 1'b0 ;
else
if (no_bits_rcvd == 4'b1011)
data_ready = 1'b1 ;
end
always @(posedge clk16x or posedge rst)
begin
if (rst)
clkdiv = 4'b0000 ;
else if (clk1x_enable)
clkdiv = clkdiv +1 ;
end
assign clk1x = clkdiv[3] ;
always @(posedge clk1x or posedge rst)
if (rst)
begin
rsr <= 8'b0 ;
rbr <= 8'b0 ;
parity <= 1'b1 ;
framing_error = 1'b0 ;
parity_error = 1'b0 ;
end
else
begin
if (no_bits_rcvd >= 4'b0001 && no_bits_rcvd <= 4'b1001)
begin
rsr[0] <= rxd2 ;
rsr[7:1] <= rsr[6:0] ;
parity <= parity ^ rsr[7] ;
end
else if (no_bits_rcvd == 4'b1010)
begin
rbr <= rsr ;
end
else if (!parity)
parity_error = 1'b1 ;
else if ((no_bits_rcvd == 4'b1011) && (rxd2 != 1'b1))
framing_error = 1'b1 ;
else
framing_error = 1'b0 ;
end
always @(posedge clk1x or posedge rst or negedge clk1x_enable)
if (rst)
no_bits_rcvd = 4'b0000;
else
if (!clk1x_enable)
no_bits_rcvd = 4'b0000 ;
else
no_bits_rcvd = no_bits_rcvd + 1 ;
endmodule
********************************************************************************************
`timescale 1 ns / 1 ns
module txmit (din,tbre,tsre,rst,clk16x,wrn,sdo) ;
output tbre ;
output tsre ;
output sdo ;
input [7:0] din ;
input rst ;
input clk16x ;
input wrn ;
reg tbre ;
reg tsre ;
reg clk1x_enable ;
reg [7:0] tsr ;
reg [7:0] tbr ;
reg parity ;
reg[3:0] clkdiv ;
wire clk1x ;
reg sdo ;
reg [3:0] no_bits_sent ;
reg wrn1 ;
reg wrn2 ;
always @(posedge clk16x or posedge rst)
begin
if (rst)
begin
wrn1 <= 1'b1 ;
wrn2 <= 1'b1 ;
end
else
begin
wrn1 <= wrn ;
wrn2 <= wrn1 ;
end
end
always @(posedge clk16x or posedge rst)
begin
if (rst)
begin
tbre <= 1'b0 ;
clk1x_enable <= 1'b0 ;
end
else if (!wrn1 && wrn2)
begin
clk1x_enable <= 1'b1 ;
tbre <= 1'b1 ;
end
else if (no_bits_sent == 4'b0010)
tbre <= 1'b1 ;
else if (no_bits_sent == 4'b1101)
begin
clk1x_enable <= 1'b0 ;
tbre <= 1'b0 ;
end
end
always @(negedge wrn or posedge rst)
begin
if (rst)
tbr = 8'b0 ;
else
tbr = din ;
end
always @(posedge clk16x or posedge rst)
begin
if (rst)
clkdiv = 4'b0 ;
else if (clk1x_enable)
clkdiv = clkdiv + 1 ;
end
assign clk1x = clkdiv[3] ;
always @(negedge clk1x or posedge rst)
if (rst)
begin
sdo <= 1'b1 ;
tsre <= 1'b1 ;
parity <= 1'b1 ;
tsr <= 8'b0 ;
end
else
begin
if (no_bits_sent == 4'b0001)
begin
tsr <= tbr ;
tsre <= 1'b0 ;
end
else if (no_bits_sent == 4'b0010)
begin
sdo <= 1'b0 ;
end
else
if ((no_bits_sent >= 4'b0011) && (no_bits_sent <= 4'b1010))
begin
tsr[7:1] <= tsr[6:0] ;
tsr[0] <= 1'b0 ;
sdo <= tsr[7] ;
parity <= parity ^ tsr[7] ;
end
else if (no_bits_sent == 4'b1011)
begin
sdo <= parity ;
end
else if (no_bits_sent == 4'b1100)
begin
sdo <= 1'b1 ;
tsre <= 1'b1 ;
end
end
always @(posedge clk1x or posedge rst or negedge clk1x_enable)
if (rst)
no_bits_sent = 4'b0000 ;
else if (!clk1x_enable)
no_bits_sent = 4'b0000 ;
else
no_bits_sent = no_bits_sent + 1 ;
endmodule
*******************************************************************************************
module txmit_tb ;
// Inputs
reg [7:0] din;
reg rst;
reg clk16x;
reg wrn;
// Outputs
wire tbre;
wire tsre;
wire sdo;
// Bidirs
// Instantiate the UUT
txmit d (
.tbre(tbre),
.tsre(tsre),
.sdo(sdo),
.din(din),
.rst(rst),
.clk16x(clk16x),
.wrn(wrn)
);
// Initialize Inputs
// `ifdef auto_init
initial begin
din = 0;
rst = 0;
clk16x = 0;
wrn = 1;
end
// `endif
always #10 clk16x = ~clk16x ;
initial begin
#3 rst = 1'b1 ;
din = 8'b11110000 ;
#25 rst = 1'b0 ;
#30 wrn = 1'b0 ;
#150 wrn = 1'b1 ;
#4000 din = 8'b10101010 ;
#870 wrn = 1'b0 ;
#200 wrn = 1'b1 ;
#3000 rst = 1'b1 ;
end
endmodule
**********************************************************************************
module rcvr_tb ;
// Inputs
reg rxd;
reg clk16x;
reg rst;
reg rdn;
// Outputs
wire [7:0] dout;
wire data_ready;
wire framing_error;
wire parity_error;
// Bidirs
// Instantiate the UUT
rcvr d (
.rxd(rxd),
.clk16x(clk16x),
.rst(rst),
.rdn(rdn),
.dout(dout),
.data_ready(data_ready),
.framing_error(framing_error),
.parity_error(parity_error)
);
// Initialize Inputs
// `ifdef auto_init
initial begin
rxd = 1;
clk16x = 0;
rst = 0;
rdn = 1;
end
// `endif
always #10 clk16x = ~clk16x ;
initial begin
#1 rst = 1'b1 ;
#21 rst = 1'b0 ;
#350 rxd = 1'b0 ;
#1800 rxd = 1'b1 ;
#1800 rxd = 1'b0 ;
#1000 rdn = 1'b0 ;
#500 rdn = 1'b1 ;
end
endmodule