chuanshaoke的个人空间 https://blog.eetop.cn/82559 [收藏] [复制] [分享] [RSS]

空间首页 动态 记录 日志 相册 主题 分享 留言板 个人资料

日志

转一个 UART verilog代码

热度 1已有 4104 次阅读| 2009-8-19 09:09

UART verilog程序
 

 

`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


点赞

发表评论 评论 (2 个评论)

回复 yrf828917 2012-7-30 16:03
求问大神这个代码编译后应该怎么加激励进行仿真呢?我随便加的激励貌似仿不出结果来,求指点。ps:我是菜鸟级小师妹,师兄交给我任务就不管我了:'( :'(
回复 weizqsocool 2021-4-7 22:06
代码是不是有问题,parity <= parity ^ rsr[7]  是不是应该改为 parity <= parity ^ rsr[0]

facelist

您需要登录后才可以评论 登录 | 注册

  • 关注TA
  • 加好友
  • 联系TA
  • 0

    周排名
  • 0

    月排名
  • 0

    总排名
  • 0

    关注
  • 1

    粉丝
  • 0

    好友
  • 3

    获赞
  • 47

    评论
  • 1113

    访问数
关闭

站长推荐 上一条 /1 下一条

小黑屋| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-4-26 02:02 , Processed in 0.023496 second(s), 14 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
返回顶部