FPGA project: uart_rs485

文章详细描述了两个模块(ctrl和be_ctrl)之间的交互,通过按键控制LED灯的开关状态,以及rs_485_tx模块用于数据传输的部分。展示了Verilog语言中如何实现输入输出信号的处理和时序逻辑控制。

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 )           ;
`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: // // Create Date: 2020/05/16 22:08:00 // Design Name: // Module Name: RS485_top // Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// module RS485_top( clk_25m, clk_50m, clk_125m, rstn, run, stop, reset, rx, tx, t_data, t_en, s_data, s_en, //input wire reset, rx2, tx2, t_data_2, s_data_2, s_en_2, t_en_2, con, rs485_err ); input clk_25m; input clk_50m; input clk_125m; input rstn; input rx; output tx; output [247:0] t_data; output t_en; output [31:0] s_data; output s_en; input run; input stop; input reset; wire status; wire temperature; //需要一个模块输出查5个温度,5个状态 //input wire reset, input rx2; output tx2; output [247:0] t_data_2; output [31:0] s_data_2; output s_en_2; output t_en_2; output con; wire bps; wire bps_2; wire run_to_485; wire stop_to_485; wire reset_to_485; wire status_to_485; wire temperature_to_485; (* ASYNC_REG = "TRUE" *)reg reset_sy5; (* ASYNC_REG = "TRUE" *)reg reset_sy6; always @ (posedge clk_125m) begin reset_sy5 <= reset; end always @ (posedge clk_125m) begin reset_sy6 <= reset_sy5; end (* ASYNC_REG = "TRUE" *)reg run_sy5; (* ASYNC_REG = "TRUE" *)reg run_sy6; reg run_sy7; always @ (posedge clk_125m) begin run_sy5 <= run; end always @ (posedge clk_125m) begin run_sy6 <= run_sy5; end reg [31:0] cnt_wait_run = 32'd625_000_00; reg wait_run = 1'b0; always @ (posedge clk_125m) begin if (run_sy6) begin cnt_wait_run <= 32'd0; wait_run <= 1'b1; end else if (cnt_wait_run == 32'd625_000_00) begin cnt_wait_run <= cnt_wait_run; wait_run <= 1'b0; end else begin cnt_wait_run <= cnt_wait_run + 1'b1; wait_run <= wait_run; end end always @ (posedge clk_125m) begin if (cnt_wait_run == 32'd1) begin run_sy7 <= 1'b1; end else if (cnt_wait_run == 32'd125_000_00) begin run_sy7 <= 1'b1; end else if (cnt_wait_run == 32'd250_000_00) begin run_sy7 <= 1'b1; end else if (cnt_wait_run == 32'd375_000_00) begin run_sy7 <= 1'b1; end else if (cnt_wait_run == 32'd500_000_00) begin run_sy7 <= 1'b1; end else if (cnt_wait_run == 32'd624_999_00) begin run_sy7 <= 1'b1; end else begin run_sy7 <= 1'b0; end end (* ASYNC_REG = "TRUE" *)reg stop_sy5; (* ASYNC_REG = "TRUE" *)reg stop_sy6; always @ (posedge clk_125m) begin stop_sy5 <= stop; end always @ (posedge clk_125m) begin stop_sy6 <= stop_sy5; end (* ASYNC_REG = "TRUE" *)reg status_sy5; (* ASYNC_REG = "TRUE" *)reg status_sy6; always @ (posedge clk_125m) begin status_sy5 <= status; end always @ (posedge clk_125m) begin if (!wait_run) status_sy6 <= status_sy5; else status_sy6 <= 1'b0; end (* ASYNC_REG = "TRUE" *)reg temperature_sy5; (* ASYNC_REG = "TRUE" *)reg temperature_sy6; always @ (posedge clk_125m) begin temperature_sy5 <= temperature; end always @ (posedge clk_125m) begin if (!wait_run) temperature_sy6 <= temperature_sy5; else temperature_sy6 <= 1'b0; end (* ASYNC_REG = "TRUE" *)reg run_to_485_sy4; (* ASYNC_REG = "TRUE" *)reg run_to_485_sy5; (* ASYNC_REG = "TRUE" *)reg run_to_485_sy6; always @ (posedge clk_50m) begin run_to_485_sy5 <= run_to_485_sy4; end always @ (posedge clk_50m) begin run_to_485_sy4 <= run_to_485; end always @ (posedge clk_50m) begin run_to_485_sy6 <= run_to_485_sy5; end (* ASYNC_REG = "TRUE" *)reg stop_to_485_sy5; (* ASYNC_REG = "TRUE" *)reg stop_to_485_sy6; always @ (posedge clk_50m) begin stop_to_485_sy5 <= stop_to_485; end always @ (posedge clk_50m) begin stop_to_485_sy6 <= stop_to_485_sy5; end (* ASYNC_REG = "TRUE" *)reg reset_to_485_sy5; (* ASYNC_REG = "TRUE" *)reg reset_to_485_sy6; always @ (posedge clk_50m) begin reset_to_485_sy5 <= reset_to_485; end always @ (posedge clk_50m) begin reset_to_485_sy6 <= reset_to_485_sy5; end (* ASYNC_REG = "TRUE" *)reg status_to_485_sy5; (* ASYNC_REG = "TRUE" *)reg status_to_485_sy6; always @ (posedge clk_50m) begin status_to_485_sy5 <= status_to_485; end always @ (posedge clk_50m) begin status_to_485_sy6 <= status_to_485_sy5; end (* ASYNC_REG = "TRUE" *)reg temperature_to_485_sy5; (* ASYNC_REG = "TRUE" *)reg temperature_to_485_sy6; always @ (posedge clk_50m) begin temperature_to_485_sy5 <= temperature_to_485; end always @ (posedge clk_50m) begin temperature_to_485_sy6 <= temperature_to_485_sy5; end //signal_gen signal_gen( //.clk(clk_125m), //.run_rx(run), //.stop_rx(stop), //.reset_rx(reset), //.run(run_to_485), //.stop(stop_to_485), //.reset(reset_to_485), //.s_req(9'h0), //.t_req(9'h0), //.status(1'b0),//output //.temperature(1'b0), //output //.fpga_num() // ); wire err;//crc error wire err_2; uart_test reuse_uart_test_1( .clk50mhz(clk_50m),//50Mhz //input wire reset, .rx(rx), .tx(tx), .t_data(t_data), //out .s_data(s_data), //out .run(run_to_485_sy6), .stop(stop_to_485_sy6), .rst(reset_to_485_sy6), .status(status_to_485_sy6), .s_en(s_en), //out .temperature(temperature_to_485_sy6), .t_en(t_en), //out .bps(bps) , .err(err) // .con(con) ); uart_test reuse_uart_test_2( .clk50mhz(clk_50m),//25mhz //input wire reset, .rx(rx2), .tx(tx2), .t_data(t_data_2), //out .s_data(s_data_2), //out .run(run_to_485_sy6), .stop(stop_to_485_sy6), .rst(reset_to_485_sy6), .status(status_to_485_sy6), .s_en(s_en_2), //out .temperature(temperature_to_485_sy6), .t_en(t_en_2), //out .bps(bps_2), .err(err_2) ); priority_process priority_process_u1( .clk(clk_125m), //125Mhz .rstn_in(rstn), .run(run_sy7), .stop(stop_sy6), .reset(reset_sy6), .status(status_sy6), .temperature(temperature_sy6), .run_to_485(run_to_485), .stop_to_485(stop_to_485), .reset_to_485(reset_to_485), .status_to_485(status_to_485), .temperature_to_485(temperature_to_485) ); wire [29:0] detection_count; breakdown_dection_counter reuse_breakdown_dection_counter( clk_50m, detection_count ); query_rs485 query_rs485_u1( .clk(clk_50m), .rstn(rstn), .status_pulse(status), .temperature_pulse(temperature) ); reg [9:0]err_cnt; reg crc_err; wire s_en_come,t_en_come; reg [9:0] rx_err_cnt; reg rs485_rx_err; output wire rs485_err; initial begin err_cnt <= 10'd0; crc_err <= 1'b0; rx_err_cnt <= 10'd0; rs485_rx_err <= 1'b0; end //这里只用了2 posedge_detection_new reuse_posedge_detection_new( clk_50m, 1'b1, s_en_2, s_en_come //output start ); posedge_detection_new reuse_posedge_detection_new_2( clk_50m, 1'b1, t_en_2, t_en_come //output start ); always @ (posedge clk_125m) begin if (err_cnt <= 10'd10) begin err_cnt <= err_cnt + err_2; end else if (detection_count == 30'd600000000) begin err_cnt <= 10'd0; end else begin err_cnt <= err_cnt; end end always @ (posedge clk_125m) begin if (err_cnt >= 10'd5) begin crc_err <= 1'b1; end else if (reset) begin crc_err <= 1'b0; end else begin crc_err <= crc_err; end end always @ (posedge clk_125m) begin if (s_en_come) begin rx_err_cnt <= rx_err_cnt + 1'b1; end else if (detection_count == 30'd599999999) begin rx_err_cnt <= 10'd0; end else begin rx_err_cnt <= rx_err_cnt; end end always @ (posedge clk_125m) begin if (detection_count == 30'd599900000) begin if (rx_err_cnt == 10'd0) begin rs485_rx_err <= 1'b1; end else begin rs485_rx_err <= rs485_rx_err; end end else if (reset) begin rs485_rx_err <= 1'b0; end else begin rs485_rx_err <= rs485_rx_err; end end assign rs485_err = rs485_rx_err || crc_err; endmodule
07-10
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值