当前位置:   article > 正文

UART设计1——发送器:并转串

uart设计

1.顶层设计

UART:通用异步收发器
接收和发送串行数据,发送和接收单元不同步

顶层框图
设计实例:以ASIC码传输
ASCI码传输格式
“协议约定”:
1.起始位为0表示传输开始
2.停止位为1表示传输结束
3.数据传输从LSB开始

2.发送器顶层框图

在这里插入图片描述
输入端口:
data_in[7:0]:主机输入UART_XMTR的数据,位宽为8=7bit data+1bit 奇偶校验
byte_ready:主机向发送器声明数据已经准备好
t_ready:主机向发送器声明可以开始传递数据,即起始位变低
输出端口:
serial_out:串行输出数据

3.设计流程

设计流程图

4.设计代码

1.uart_xmt_controller

`timescale  1ns/1ns
module  uart_xmt_controller(
    input       wire                        sclk,
    input       wire                        rst_n,
    input       wire                        byte_ready,
    input       wire                        t_ready,
    input       wire                        bc_lt_bcmax,
    output      reg                         load_shiftreg,
    output      reg                         start,
    output      reg                         send,
    output      reg                         inc_bc_counter,
    output      reg                         clc_bc_counter
);


parameter   S_idle=3'b001,
            S_wait=3'b010,
            S_send=3'b100;

reg [2:0]   state,next_state;

always  @(posedge   sclk or negedge rst_n)begin
    if(rst_n==1'b0) next_state<=3'd0;
    else    next_state<=state;
end

always  @(*)begin
    load_shiftreg=0;start=0;send=0;
    inc_bc_counter=0;clc_bc_counter=0;
    next_state=S_idle;
    case(state)
        S_idle:begin
            if(byte_ready==1'b1)    begin
                next_state=S_wait;
                load_shiftreg=1;
            end
            else    next_state=S_idle;
        end
        S_wait:begin
            if(t_ready==1'b1)   begin
                next_state=S_send;
                start=1;
            end
            else    next_state=S_wait;
        end
        S_send:begin
            send=1;
            if(bc_lt_bcmax==1'b1)begin
                next_state=S_send;
                inc_bc_counter=1;
            end
            else    begin
                next_state=S_idle;
                clc_bc_counter=1;
            end
        end
        default:next_state=S_idle;
    endcase
end
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60

2.uart_xmt_datapath

`timescale  1ns/1ns
module  uart_xmt_datapath #(
parameter   WORD_SIZE=8,
parameter   BC_SIZE=4,
parameter   BC_MAX=9
)(
    input       wire                        sclk,
    input       wire                        rst_n,
    input       wire                        load_shiftreg,
    input       wire                        start,
    input       wire                        send,
    input       wire                        inc_bc_counter,
    input       wire                        clc_bc_counter,
    input       wire   [WORD_SIZE-1:0]      data_in,                     
    output      wire                        bc_lt_bcmax,
    output      wire                        serial_out
);

reg [WORD_SIZE:0]   data_shift;
reg [BC_SIZE-1:0]   bit_counter;

assign  serial_out=data_shift[0];
assign  bc_lt_bcmax=(bit_counter<9)? 1'b1:1'b0;

always  @(posedge   sclk or negedge rst_n)begin
    if(rst_n==1'b0) data_shift<=9'b1_1111_1111;
    else    if(load_shiftreg==1'b1)
        data_shift<={data_in,1'b1};
    else    if(start==1'b1)
        data_shift<={data_shift[WORD_SIZE:1],1'b0};
    else    if(send==1'b1)
        data_shift<={1'b1,data_shift[WORD_SIZE:1]};
    else
        data_shift<=data_shift;
end

always  @(posedge   sclk or negedge rst_n)begin
    if(rst_n==1'b0) bit_counter<=0;
    else    if(inc_bc_counter==1'b1)
        bit_counter<=bit_counter+1'b1;
    else    if(clc_bc_counter==1'b1)
        bit_counter<=0;
    else
        bit_counter<=bit_counter;
end
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46

3.uart_xmt

`timescale  1ns/1ns
module  uart_xmt #(
parameter   WORD_SIZE=8,
parameter   BC_SIZE=4,
parameter   BC_MAX=9
)(
    input       wire                        sclk,
    input       wire                        rst_n,
    input       wire                        byte_ready,
    input       wire                        t_ready,
    input       wire [WORD_SIZE-1:0]        data_in,
    output      wire                        serial_out
);

wire    bc_lt_bcmax;
wire    load_shiftreg;
wire    start;
wire    send;
wire    inc_bc_counter;
wire    clc_bc_counter;

uart_xmt_controller uart_xmt_controller_inst(
    . sclk             (sclk               ),
    . rst_n            (rst_n              ),
    . byte_ready       (byte_ready         ),
    . t_ready          (t_ready            ),
    . bc_lt_bcmax      (bc_lt_bcmax        ),
    . load_shiftreg    (load_shiftreg      ),
    . start            (start              ),
    . send             (send               ),
    . inc_bc_counter   (inc_bc_counter     ),
    . clc_bc_counter   (clc_bc_counter     )
);

uart_xmt_datapath   uart_xmt_datapath_inst(
 .sclk            ( sclk              ) ,
 .rst_n           ( rst_n             ) ,
 .load_shiftreg   ( load_shiftreg     ) ,
 .start           ( start             ) ,
 .send            ( send              ) ,
 .inc_bc_counter  ( inc_bc_counter    ) ,
 .clc_bc_counter  ( clc_bc_counter    ) ,
 .data_in         ( data_in           ) ,                     
 .bc_lt_bcmax     ( bc_lt_bcmax       ) ,
 .serial_out      ( serial_out        ) 
);

endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48

4.tb_uart_xmt

tb文件中
1.forever使用
2.task调用

`timescale  1ns/1ns
module    tb_uart_xmt #(parameter   WORD_SIZE=8)();

reg                 sclk;
reg                 rst_n;
reg                 byte_ready;
reg                 t_ready;
reg [WORD_SIZE-1:0] data_in;
wire                serial_out;

reg [WORD_SIZE+1:0] serial_test;
wire[WORD_SIZE-1:0] test_word;

initial begin
    sclk=0;
    forever #10 sclk=~sclk;
end

initial begin
    rst_n=0;
    #200    rst_n=1;
end

initial begin
    byte_ready=0;t_ready=0;
    data_in=0;serial_test=0;
    #210
    gen_test_data();//调用task
    rec_test_data();
end

initial begin
    serial_test=0;
    rec_test_data();
end



uart_xmt    uart_xmt_inst(
   . sclk          (sclk          ),
   . rst_n         (rst_n         ),
   . byte_ready    (byte_ready    ),
   . t_ready       (t_ready       ),
   . data_in       (data_in       ),
   . serial_out    (serial_out    )
);

//产生测试数据
task    gen_test_data();
    integer i;
    begin
        for(i=0;i<10;i=i+1)begin
            data_in=8'ha7+i;
            #10 byte_ready=1;
            #20 byte_ready=0;
            #60 t_ready=1;
            #20 t_ready=0;
            #350;
        end
    end
endtask

//测试数据回收是否正确
assign  test_word=serial_test[WORD_SIZE:1];

task    rec_test_data();
    integer i,j;
    begin
        for(i=0;i<350;i=i+1)begin
            for(j=0;j<10;j=j+1)begin
                @(posedge   sclk)
                serial_test={serial_out,serial_test[WORD_SIZE+1:1]};//向LSB移动
            end
        end
    end
endtask

endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78

5.仿真结果

在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/467838
推荐阅读
相关标签
  

闽ICP备14008679号