FPGA project: uart_rs485

复制代码
module ctrl(
    input       wire                sys_clk     ,
    input       wire                sys_rst_n   ,
    input       wire                key_w       ,
    input       wire                key_b       ,

    output      wire        [7:0]   po_data     , // 由于w_en 与b_en 使能信号是reg型,虽然po_data是时序逻辑,但是相对于按键按下信号,仍然要延后一个时钟周期。
    output      reg                 po_flag       // 所以po_data 应该用reg
);
    reg  w_en ;
    reg  b_en ;
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) begin
            w_en <= 1'b0 ;
        end else begin
            if(key_w == 1'b1) begin
                w_en <= ~w_en ;
            end else begin
                if(key_b == 1'b1) begin
                    w_en <= 1'b0 ;
                end else begin
                    w_en <= w_en ;
                end
            end
        end 
    end
    // b_en
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) begin
            b_en <= 1'b0 ;
        end else begin
            if(key_b == 1'b1) begin
                b_en <= ~b_en ;
            end else begin
                if(key_w == 1'b1) begin
                    b_en <= 1'b0 ;
                end else begin
                    b_en <= b_en ;
                end
            end
        end 
    end

    // [7:0]   po_data     ,
    assign po_data = {6'd0,w_en,b_en} ;
    //         po_flag   
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) begin
            po_flag <= 1'b0 ;
        end else begin
            po_flag <= key_b || key_w ;
        end
    end 
endmodule

`timescale 1ns/1ns
module test_ctrl();
    reg                   sys_clk     ;
    reg                   sys_rst_n   ;
    reg                   key_w       ;
    reg                   key_b       ;

    wire        [7:0]     po_data     ;
    wire                  po_flag     ;

ctrl ctrl_insert(
    .sys_clk            ( sys_clk   )   ,
    .sys_rst_n          ( sys_rst_n )   ,
    .key_w              ( key_w     )   ,
    .key_b              ( key_b     )   ,

    .po_data            ( po_data   )   ,
    .po_flag            ( po_flag   )     
);
    parameter CYCLE = 20 ;

    initial begin
        sys_clk    = 1'b1 ;
        sys_rst_n <= 1'b0 ;
        key_w     <= 1'b0 ;
        key_b     <= 1'b0 ;
        #( CYCLE * 10 )   ;
        sys_rst_n <= 1'b1 ;
        #( 210 )          ;
        sys_rst_n <= 1'b0 ;
        #( 10 )           ;
        #( CYCLE * 10 )   ;
        sys_rst_n <= 1'b1 ;
        #( CYCLE * 100  ) ;

        key_w     <= 1'b1 ;
        #( CYCLE )        ;
        key_w     <= 1'b0 ;
        #( CYCLE * 500)   ;

        key_b     <= 1'b1 ;
        #( CYCLE )        ;
        key_b     <= 1'b0 ;
        #( CYCLE * 500)   ;

        key_w     <= 1'b1 ;
        #( CYCLE )        ;
        key_w     <= 1'b0 ;
        #( CYCLE * 500)   ;

        key_b     <= 1'b1 ;
        #( CYCLE )        ;
        key_b     <= 1'b0 ;
        #( CYCLE * 500)   ;
        
        key_w     <= 1'b1 ;
        #( CYCLE )        ;
        key_w     <= 1'b0 ;
        #( CYCLE * 500)   ;

        key_w     <= 1'b1 ;
        #( CYCLE )        ;
        key_w     <= 1'b0 ;
        #( CYCLE * 500)   ;

        $stop             ;
    end

    always #( CYCLE / 2 ) sys_clk = ~sys_clk ;


endmodule

module be_ctrl(
    input       wire                sys_clk     ,
    input       wire                sys_rst_n   ,
    // input       wire                key_w       , // 作为被控制板模块的ctrl 一些端口信号用不到的。
    // input       wire                key_b       ,
    input       wire        [7:0]   pi_data     , 
    input       wire                pi_flag     , 
    input       wire        [3:0]   led_w       , 
    input       wire        [3:0]   led_b       , 

    // output      wire        [7:0]   po_data     ,
    // output      wire                po_flag     
    output      reg         [3:0]   led_out       // 也可以用组合逻辑
);
    reg  w_en ;
    reg  b_en ;
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) begin
            w_en <= 1'b0 ;
        end else begin
            if(pi_data[1]) begin
                w_en <= ~w_en ;
            end else begin
                if(pi_data[0]) begin
                    w_en <= 1'b0 ;
                end else begin
                    w_en <= w_en ;
                end
            end
        end 
    end
    // b_en
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) begin
            b_en <= 1'b0 ;
        end else begin
            if(pi_data[0]) begin
                b_en <= ~b_en ;
            end else begin
                if(pi_data[1]) begin
                    b_en <= 1'b0 ;
                end else begin
                    b_en <= b_en ;
                end
            end
        end 
    end

    // [3:0]   led_out 
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) begin
            led_out <= 3'd0 ;
        end else begin
            if(w_en == 1'b1) begin
                led_out <= led_w;
            end else begin
                if(b_en == 1'b1) begin
                    led_out <= led_b;
                end else begin
                    led_out <= led_out ;
                end
            end 
        end
    end
endmodule

`timescale 1ns/1ns
module test_be_ctrl();
    reg                   sys_clk     ;
    reg                   sys_rst_n   ;
    reg         [7:0]     pi_data_w   ;
    reg                   pi_flag_w   ;

    wire        [3:0]     led_out     ;

    
    // 由例化的模块产生
    wire        [3:0]     led_w_w       ;
    wire        [3:0]     led_b_w       ;

water_led  
#(
    .MAX_CNT                ( 25'd25_0) // 00_000 
)water_led_insert
(
    .sys_clk                ( sys_clk    ) ,
    .sys_rst_n              ( sys_rst_n  ) ,

    .led                    ( led_w_w )
);
breath_led 
#(
    .CNT_1US            ( 5          )  ,
    .CNT_1K             ( 10         ) 
)breath_led_insert
(
    .sys_clk            ( sys_clk    )  ,
    .sys_rst_n          ( sys_rst_n  )  ,

    .led_out_1          ( led_b_w[0] )  ,
    .led_out_2          ( led_b_w[1] )  ,
    .led_out_3          ( led_b_w[2] )  ,
    .led_out_4          ( led_b_w[3] )   
);

be_ctrl be_ctrl_insert(
    .sys_clk            ( sys_clk   ) ,
    .sys_rst_n          ( sys_rst_n ) ,
    .pi_data            ( pi_data_w ) , 
    .pi_flag            ( pi_flag_w ) , 
    .led_w              ( led_w_w   ) , 
    .led_b              ( led_b_w   ) , 

    .led_out            ( led_out   )     
);
    parameter CYCLE = 20 ;

    initial begin
        sys_clk    = 1'b1 ;
        sys_rst_n <= 1'b0 ;
        pi_data_w <= 8'd0 ;
        pi_flag_w <= 1'b0 ;
        #( CYCLE * 10 )   ;
        sys_rst_n <= 1'b1 ;
        #( 210 )          ;
        sys_rst_n <= 1'b0 ;
        #( 10 )           ;
        #( CYCLE * 10 )   ;
        sys_rst_n <= 1'b1 ; // 复位释放。
        #( 50 * CYCLE)    ;
        pi_data_w <= 8'd1 ; // 呼吸灯控制按键按下
        pi_flag_w <= 1'b1 ;
        #( CYCLE )        ;
        pi_data_w <= 8'd0 ;
        pi_flag_w <= 1'b0 ;
        #( CYCLE * 500 )  ;

        pi_data_w <= 8'd1 ; // 呼吸灯控制按键按下
        pi_flag_w <= 1'b1 ;
        #( CYCLE )        ;
        pi_data_w <= 8'd0 ;
        pi_flag_w <= 1'b0 ;
        #( CYCLE * 500 )  ;

        pi_data_w <= 8'd2 ; // 流水灯控制按键按下
        pi_flag_w <= 1'b1 ;
        #( CYCLE )        ;
        pi_data_w <= 8'd0 ;
        pi_flag_w <= 1'b0 ;
        #( CYCLE * 500 )  ;
        
        pi_data_w <= 8'd1 ; // 呼吸灯控制按键按下
        pi_flag_w <= 1'b1 ;
        #( CYCLE )        ;
        pi_data_w <= 8'd0 ;
        pi_flag_w <= 1'b0 ;
        #( CYCLE * 500 )  ;
        $stop ;
    end

    always #( CYCLE / 2 ) sys_clk = ~sys_clk ;


endmodule
流水灯模块与呼吸灯模块是之前工程里的。

module rs_485_tx (
    input       wire            sys_clk   ,
    input       wire            sys_rst_n ,
    input       wire   [7:0]    pi_data   ,
    input       wire            pi_flag   ,

    output      reg             tx        ,
    output      reg             re         
);

    // reg signal define
    reg             pi_flag_r   ;
    reg     [7:0]   pi_data_r   ;
    reg             work_en     ;
    reg     [12:00] baud_cnt    ;
    reg             bit_flag    ;
    reg     [ 3: 0] bit_cnt     ;
    // pi_flag_r     ;
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) begin
            pi_flag_r <= 1'b0 ;
        end else begin
            if(pi_flag == 1'b1) begin
                pi_flag_r <= 1'b1 ;
            end else begin
                pi_flag_r <= 1'b0 ;
            end
        end
    end
    // [7:0] pi_data_r   ;
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) begin
            pi_data_r <= 1'b0 ;
        end else begin
            if(pi_flag == 1'b1) begin
                pi_data_r <= pi_data ;
            end else begin
                pi_data_r <= pi_data_r ;
            end
        end
    end
    //        work_en      ;
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) begin
            work_en <= 1'b0 ;
        end else begin
            if(baud_cnt == 13'd5027 && bit_cnt == 4'd9) begin
                work_en <= 1'b0 ;
            end else begin
                if(pi_flag_r == 1'b1) begin
                    work_en <= 1'b1 ;
                end else begin
                    work_en <= work_en ;
                end
            end
        end
    end
    // [12:00] baud_cnt    ;
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) begin
            baud_cnt <= 13'd0 ;
        end else begin
            if(work_en == 1'b1 && baud_cnt == 13'd5027 || work_en == 1'b0) begin
                baud_cnt <= 13'd0 ;
            end else begin
                if(work_en == 1'b1) begin
                    baud_cnt <= baud_cnt + 1'b1 ;
                end else begin
                    baud_cnt <= 13'd0 ;
                end
            end
        end
    end
    //         bit_flag    ;
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) begin
            bit_flag <= 1'b0 ;
        end else begin
            if(baud_cnt == 13'd5026) begin // 野火上是等于 1 .
                bit_flag <= 1'b1 ;
            end else begin
                bit_flag <= 1'b0 ;
            end
        end
    end
    // [ 3: 0] bit_cnt     ;
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) begin
            bit_cnt <= 4'd0 ;
        end else begin
            if(bit_flag == 1'b1 && bit_cnt == 4'd9 || work_en == 1'b0) begin
                bit_cnt <= 4'd0 ;
            end else begin
                if(bit_flag == 1'b1) begin
                    bit_cnt <= bit_cnt + 1'b1 ;
                end else begin
                    bit_cnt <= bit_cnt ;
                end
            end
        end
    end

    // output signal
    // tx
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) begin
            tx <= 1'b1 ;
        end else begin
            if(work_en == 1'b1 && bit_cnt == 4'd0) begin
                tx <= 1'b0 ;
            end else begin
                if(work_en == 1'b1 && bit_cnt == 4'd9 || work_en == 1'b0) begin
                    tx <= 1'b1 ;
                end else begin
                    tx <= pi_data_r[bit_cnt - 1'b1] ;
                end
            end
        end
    end
    // re
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) begin
            re <= 1'b0 ;
        end else begin
            re <= work_en ;
        end
    end
endmodule

`timescale 1ns/1ns
module test_rs_485_tx();
    reg             sys_clk   ;
    reg             sys_rst_n ;
    reg    [7:0]    pi_data   ;
    reg             pi_flag   ;

    wire            tx        ;
    wire            re        ;


rs_485_tx rs_485_tx_insert(
    .sys_clk        ( sys_clk   ) ,
    .sys_rst_n      ( sys_rst_n ) ,
    .pi_data        ( pi_data   ) ,
    .pi_flag        ( pi_flag   ) ,

    .tx             ( tx        ) ,
    .re             ( re        )  
);
    parameter CYCLE = 20 ;

    initial begin
        sys_clk    = 1'b1 ;
        sys_rst_n <= 1'b0 ;
        pi_data <= 8'd0 ;
        pi_flag <= 1'b0 ;
        #( CYCLE * 10 )   ;
        sys_rst_n <= 1'b1 ;
        #( 210 )          ;
        sys_rst_n <= 1'b0 ;
        #( 10 )           ;
        #( CYCLE * 10 )   ;
        sys_rst_n <= 1'b1 ; // 复位释放。
        #( 50 * CYCLE)    ;
        pi_data <= 8'd1 ; // 呼吸灯控制按键按下
        pi_flag <= 1'b1 ;
        #( CYCLE )        ;
        pi_data <= 8'd0 ;
        pi_flag <= 1'b0 ;
        #( CYCLE * 96100 )  ;

        pi_data <= 8'd1 ; // 呼吸灯控制按键按下
        pi_flag <= 1'b1 ;
        #( CYCLE )        ;
        pi_data <= 8'd0 ;
        pi_flag <= 1'b0 ;
        #( CYCLE * 96100 )  ;

        pi_data <= 8'd2 ; // 流水灯控制按键按下
        pi_flag <= 1'b1 ;
        #( CYCLE )        ;
        pi_data <= 8'd0 ;
        pi_flag <= 1'b0 ;
        #( CYCLE * 96100 )  ;
        
        pi_data <= 8'd1 ; // 呼吸灯控制按键按下
        pi_flag <= 1'b1 ;
        #( CYCLE )        ;
        pi_data <= 8'd0 ;
        pi_flag <= 1'b0 ;
         #( CYCLE * 96100 )  ;
        $stop ;
    end

    always #( CYCLE / 2 ) sys_clk = ~sys_clk ;


endmodule
相关推荐
Hello-FPGA1 天前
基于RFSOC FPGA ZCU216 的CoaXPress 采集demo
fpga开发
9527华安1 天前
FPGA基于ADV7182解码PAL视频,Video Processing Subsystem去隔行,提供6套工程源码和技术支持
fpga开发·音视频·pal·adv7182
hahaha60161 天前
数字图像时域滤波或者3D降噪算法FPGA实现
算法·计算机视觉·fpga开发
GateWorld1 天前
Xilinx 7系列FPGA时钟网络详解
fpga开发·时钟网络·xilinx 7系列
szxinmai主板定制专家2 天前
X86 工控机 vs RK3588 异构主控:AMR 控制器 BOM、散热、长期运维对比
运维·stm32·单片机·嵌入式硬件·fpga开发·am62x
szxinmai主板定制专家2 天前
AMR 项目落地:机器人控制器硬件定制化需求复盘
arm开发·单片机·fpga开发·系统架构·机器人·am62x
FPGA小迷弟3 天前
FPGA 与卫星:从星载硬件到在轨智能的完整技术解析
fpga开发·架构·fpga·1024程序员节·无线电
NamoAmitabha1283 天前
CPU 内部结构是什么?---deepseek
fpga开发
abc light3 天前
ARM 裸机开发(6)——时钟树与定时器
arm开发·单片机·fpga开发
156082072194 天前
JFMZQ28DR、JFMZQ68DR、RFsoc XCZU47DR、XCZU48DR 信号处理板
fpga开发·信号处理