FPGA project : inf_rcv

module top (
    input       wire            sys_clk     ,
    input       wire            sys_rst_n   ,
    input       wire            inf_in      ,

    output      wire            led         ,
    output      wire            ds          ,
    output      wire            oe          ,
    output      wire            shcp        ,
    output      wire            stcp     
);


// 例化连线
    wire    [7:0]   data        ;
    wire            sign        ;
    wire    [19:00] data_w      ;
    assign          data_w = {12'd0,data} ;
    wire    [05:00] point_w     ;
    assign          point_w = 6'b000000 ;
    wire            sign_w      ;
    assign          sign_w = 1'b0 ;
    wire            seg_en_w    ;
    assign          seg_en_w = 1'b1 ;
inf_rcv inf_rcv_insert(
    .sys_clk                ( sys_clk   ) ,
    .sys_rst_n              ( sys_rst_n ) ,
    .inf_in                 ( inf_in    ) ,

    .data                   ( data      ) ,
    .sign                   ( sign      )        
);

led led_insert(
    .sys_clk                ( sys_clk   ) ,
    .sys_rst_n              ( sys_rst_n ) ,
    .key_in                 ( sign ) ,

    .led_out                ( led  )     
);

seg_595_dynamic seg_595_dynamic_insert(
    .sys_clk                ( sys_clk    ) ,
    .sys_rst_n              ( sys_rst_n  ) ,
    .data                   ( data_w     ) ,
    .point                  ( point_w    ) ,
    .sign                   ( sign_w     ) ,
    .seg_en                 ( seg_en_w   ) ,

    .ds                     ( ds         ) ,
    .oe                     ( oe         ) ,
    .shcp                   ( shcp       ) ,
    .stcp                   ( stcp       )    
);

endmodule
module inf_rcv (
    input       wire            sys_clk     ,
    input       wire            sys_rst_n   ,
    input       wire            inf_in      ,

    output      reg     [7:0]   data        ,
    output      reg             sign        
);
    // parameter degine
    parameter       T_9MS    = 19'd450_000 ,
                    T_4_5MS  = 18'd225_000 ,
                    T_2_225MS= 17'd112_500 ,
                    T_560US  = 15'd28_000  ,
                    T_1_69MS = 17'd84_500  ;

    // parameter degine
    localparam      IDLE     = 5'b0_0001 ,
                    TIME_9MS = 5'b0_0010 ,
                    ARBITE   = 5'b0_0100 ,
                    DATA     = 5'b0_1000 ,
                    REPEAT   = 5'b1_0000 ;

    // wire signal define 
    wire            nege        ;
    wire            pose        ;


    // reg signal define
    reg             inf_in_reg0 ;
    reg             inf_in_reg1 ;
    reg             inf_in_reg2 ;
    reg     [ 4:0]  state       ;
    reg     [19:0]  cnt         ; // 虽然最大计数9ms只需19位宽,但还是定义20位宽。
    reg             flag_9ms    ; // 由于设备制造精度与环境因素影响,这个标志信号在指定目标附近拉高即可。
    reg             flag_4_5ms  ;
    reg             flag_2_25ms ;
    reg             flag_560us  ;
    reg             flag_1_69ms ;
    reg     [ 5:0]  cnt_bit     ; // 32 bit 数据
    reg     [31:0]  data_reg    ;


    // // reg signal define
    // reg             inf_in_reg0 ;
    // reg             inf_in_reg1 ;
    // reg             inf_in_reg2 ;
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) begin
            inf_in_reg0 <= 1'b1 ;
            inf_in_reg1 <= 1'b1 ;
            inf_in_reg2 <= 1'b1 ;
        end else begin
            inf_in_reg0 <= inf_in      ;
            inf_in_reg1 <= inf_in_reg0 ;
            inf_in_reg2 <= inf_in_reg1 ;
        end
    end
    // // wire signal define 
    // wire            nege        ;
    // wire            pose        ;
    assign  nege = ~inf_in_reg1 &&  inf_in_reg2 ;
    assign  pose =  inf_in_reg1 && ~inf_in_reg2 ;
    // reg     [ 4:0]  state       ;
    always @(posedge sys_clk or negedge sys_rst_n)
        if(~sys_rst_n) 
            state <= IDLE ;
        else case (state)
        IDLE    :if (nege == 1'b1) 
                    state <= TIME_9MS ;
                 else 
                    state <= IDLE ;
        TIME_9MS:if(pose == 1'b1 && flag_9ms == 1'b1) //T_9MS - 19'd100
                    state <= ARBITE ;
                 else if(pose == 1'b1 && flag_9ms == 1'b0)
                    state <= IDLE ;
                 else 
                    state <= TIME_9MS ;
        ARBITE  :if(nege == 1'b1 && flag_4_5ms == 1'b1) // 说明是引导码
                    state <= DATA ;
                 else if(nege == 1'b1 && flag_2_25ms == 1'b1) // 说明是重复码
                    state <= REPEAT ;
                 else if(nege == 1'b1 && flag_4_5ms == 1'b0 && flag_2_25ms == 1'b0)
                    state <= IDLE ;
                 else 
                    state <= ARBITE ;
        DATA    :if((pose == 1'b1 && flag_560us == 1'b1 && cnt_bit == 6'd32) 
                    || (pose == 1'b1 && flag_560us == 1'b0) 
                    || (nege == 1'b1 && ( flag_560us == 1'b0 && flag_1_69ms == 1'b0)))
                    state <= IDLE ;
                 else
                    state <= DATA ;
        REPEAT  :if(pose == 1'b1 )
                    state <= IDLE ;
                 else
                    state <= REPEAT ;
        default : state <= IDLE ;
        endcase
    // reg     [19:0]  cnt         ; // 虽然最大计数9ms只需19位宽,但还是定义20位宽。
    // reg             flag_9ms    ; // 由于设备制造精度与环境因素影响,这个标志信号在指定目标附近拉高即可。
    // reg             flag_4_5ms  ;
    // reg             flag_2_25ms ;
    // reg             flag_560us  ;
    // reg             flag_1_69ms ;
    // reg     [ 5:0]  cnt_bit     ; // 32 bit 数据
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) begin
            cnt         <= 20'd0 ;
            flag_9ms    <= 1'b0  ;
            flag_4_5ms  <= 1'b0  ;
            flag_2_25ms <= 1'b0  ;
            flag_560us  <= 1'b0  ;
            flag_1_69ms <= 1'b0  ;
            cnt_bit     <= 6'd0  ;
        end else begin
            case (state)
            IDLE    :begin
                        cnt         <= 20'd0 ;
                        flag_9ms    <= 1'b0  ;
                        flag_4_5ms  <= 1'b0  ;
                        flag_2_25ms <= 1'b0  ;
                        flag_560us  <= 1'b0  ;
                        flag_1_69ms <= 1'b0  ;
                        cnt_bit     <= 6'd0  ;
                     end
            TIME_9MS:begin
                        if(pose == 1'b1) begin
                            cnt <= 20'd0 ;
                        end else begin
                            cnt <= cnt + 1'b1 ;
                        end

                        if(cnt >= T_9MS - 19'd8000 && cnt <= T_9MS + 19'd8000) // 9ms附近拉高。不能太“离谱”。
                            flag_9ms <= 1'b1 ;
                        else 
                            flag_9ms <= 1'b0 ;

                        flag_4_5ms  <= 1'b0  ;
                        flag_2_25ms <= 1'b0  ;
                        flag_560us  <= 1'b0  ;
                        flag_1_69ms <= 1'b0  ;
                        cnt_bit     <= 6'd0  ;
                     end
            ARBITE  :begin
                        if(nege == 1'b1)
                            cnt <= 20'd0 ;
                        else 
                            cnt <= cnt + 1'b1 ;
                        
                        if(cnt >= T_4_5MS - 18'd8000 && cnt <= T_4_5MS + 18'd8000)
                            flag_4_5ms <= 1'b1 ;
                        else 
                            flag_4_5ms <= 1'b0 ;

                        if(cnt >= T_2_225MS - 17'd8000 && cnt <= T_2_225MS + 17'd8000)
                            flag_2_25ms <= 1'b1 ;
                        else 
                            flag_2_25ms <= 1'b0 ;

                        flag_9ms    <= 1'b0  ;
                        flag_560us  <= 1'b0  ;
                        flag_1_69ms <= 1'b0  ;
                        cnt_bit     <= 6'd0  ;
                        end
            DATA    :begin
                        if(nege == 1'b1 || pose == 1'b1)
                            cnt <= 20'd0 ;
                        else 
                            cnt <= cnt + 1'b1 ;
                        
                        if(cnt >= T_560US - 15'd8000 && cnt <= T_560US + 15'd8000)
                            flag_560us <= 1'b1 ;
                        else 
                            flag_560us <= 1'b0 ;
                        
                        if(cnt >= T_1_69MS - 15'd8000 && cnt <= T_1_69MS + 15'd8000)
                            flag_1_69ms <= 1'b1 ;
                        else 
                            flag_1_69ms <= 1'b0 ;

                        flag_9ms    <= 1'b0  ;
                        flag_4_5ms  <= 1'b0  ;
                        flag_2_25ms <= 1'b0  ;

                        if(pose == 1'b1 && flag_560us == 1'b1 && cnt_bit == 6'd32)
                            cnt_bit <= 'd0 ;
                        else if(nege == 1'b1)
                            cnt_bit     <= cnt_bit + 1'b1 ;
                        else 
                            cnt_bit     <= cnt_bit ;
                     end
            REPEAT  :begin
                        cnt         <= 20'd0 ;
                        flag_9ms    <= 1'b0  ;
                        flag_4_5ms  <= 1'b0  ;
                        flag_2_25ms <= 1'b0  ;
                        flag_560us  <= 1'b0  ;
                        flag_1_69ms <= 1'b0  ;
                        cnt_bit     <= 6'd0  ;
                        end
            default:begin
                        cnt         <= 20'd0 ;
                        flag_9ms    <= 1'b0  ;
                        flag_4_5ms  <= 1'b0  ;
                        flag_2_25ms <= 1'b0  ;
                        flag_560us  <= 1'b0  ;
                        flag_1_69ms <= 1'b0  ;
                        cnt_bit     <= 6'd0  ;
                    end
            endcase
        end
    end

    // reg [31:0]       data_reg    ;
    always @(posedge sys_clk or negedge sys_rst_n)
        if(~sys_rst_n)
            data_reg <= 31'd0 ;
        else if(state == DATA && nege == 1'b1 && cnt_bit <= 6'd31 && flag_1_69ms == 1'b1)
            data_reg[cnt_bit] <= 1'b1 ;
        else if(state == DATA && nege == 1'b1 && cnt_bit <= 6'd31 && flag_560us == 1'b1)
            data_reg[cnt_bit] <= 1'b0 ;
        else 
            data_reg <= data_reg ;

    // output signal 
    // reg     [7:0]   data        ,
    always @(posedge sys_clk or negedge sys_rst_n)
        if(~sys_rst_n)
            data <= 8'd0 ;
        else if((data_reg[23:16] == ~data_reg[31:24]) && (data_reg[7:0] == ~data_reg[15:8]))
            data <= data_reg[23:16] ;
        else 
            data <= data ;
    // reg             sign   
    always @(posedge sys_clk or negedge sys_rst_n)
        if(~sys_rst_n) 
            sign <= 1'b0 ;
        else if(state == REPEAT)
            sign <= 1'b1 ; 
        else 
            sign <= 1'b0 ;
endmodule
module led(
    input           sys_clk ,
    input           sys_rst_n ,
    input           key_in      ,

    output    wire   led_out     
);
    reg   key_in_reg1 ;
    reg   key_in_reg2 ;
    wire  pose        ;
    reg   [24:0]    cnt_500ms   ; // 24_999_999
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) begin
            key_in_reg1 <= 1'b0 ;
            key_in_reg2 <= 1'b0 ;
        end else begin
            key_in_reg1 <= key_in ;
            key_in_reg2 <= key_in_reg1 ;
        end
    end
    assign pose = ~key_in_reg2 && key_in_reg1 ;
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) begin
            cnt_500ms <= 25'd0 ;
        end else begin
            if(cnt_500ms == 25'd0 && pose == 1'b1) begin
                cnt_500ms <= 25'd24_999_999 ;
            end else begin
                if(cnt_500ms == 25'd0) begin
                    cnt_500ms <= cnt_500ms ;
                end else begin
                    cnt_500ms <= cnt_500ms - 1'b1 ;
                end
            end
        end
    end
    assign led_out = (cnt_500ms == 0) ? 1'b1 : 1'b0 ;  // 低电平亮。
    
endmodule

 

`timescale 1ns/1ns
module test_inf_rcv();
    reg             sys_clk     ;
    reg             sys_rst_n   ;
    reg             inf_in      ;

    wire    [7:0]   data        ;
    wire            sign        ;

// Instantiation
inf_rcv inf_rcv_insert(
    .sys_clk        ( sys_clk    ) ,
    .sys_rst_n      ( sys_rst_n  ) ,
    .inf_in         ( inf_in     ) ,

    .data           ( data       ) ,
    .sign           ( sign       )        
);
    parameter CYCLE = 20 ;
    initial begin
        sys_clk    = 1'b1 ;
        sys_rst_n <= 1'b0 ;
        inf_in    <= 1'b1 ;
        #( CYCLE * 10 )   ;
        sys_rst_n <= 1'b1 ;
        #( CYCLE * 500  ) ;

// 引导码
        inf_in <= 1'b0 ;
        #(9_000_000)   ;
        inf_in <= 1'b1 ;
        #(4_500_000)   ;
// 地址码 8'h57 0101_0111 1110_1010
        inf_in <= 1'b0 ; // 1
        #(560_000)     ;
        inf_in <= 1'b1 ;
        #(1690_000)    ;
        inf_in <= 1'b0 ; // 1
        #(560_000)     ;
        inf_in <= 1'b1 ;
        #(1690_000)    ;
        inf_in <= 1'b0 ; // 1
        #(560_000)     ;
        inf_in <= 1'b1 ;
        #(1690_000)    ;
        inf_in <= 1'b0 ; // 0
        #(560_000)     ;
        inf_in <= 1'b1 ;
        #(560_000)     ;
        inf_in <= 1'b0 ; // 1
        #(560_000)     ;
        inf_in <= 1'b1 ;
        #(1690_000)    ;
        inf_in <= 1'b0 ; // 0
        #(560_000)     ;
        inf_in <= 1'b1 ;
        #(560_000)     ;
        inf_in <= 1'b0 ; // 1
        #(560_000)     ;
        inf_in <= 1'b1 ;
        #(1690_000)    ;
        inf_in <= 1'b0 ; // 0
        #(560_000)     ;
        inf_in <= 1'b1 ;
        #(560_000)     ;
// 地址反码 8'hA8 1010_1000 0001_0101
        inf_in <= 1'b0 ; // 0
        #(560_000)     ;
        inf_in <= 1'b1 ;
        #(560_000)     ;
        inf_in <= 1'b0 ; // 0
        #(560_000)     ;
        inf_in <= 1'b1 ;
        #(560_000)     ;
        inf_in <= 1'b0 ; // 0
        #(560_000)     ;
        inf_in <= 1'b1 ;
        #(560_000)     ;
        inf_in <= 1'b0 ; // 1
        #(560_000)     ;
        inf_in <= 1'b1 ;
        #(1690_000)    ;
        inf_in <= 1'b0 ; // 0
        #(560_000)     ;
        inf_in <= 1'b1 ;
        #(560_000)     ;
        inf_in <= 1'b0 ; // 1
        #(560_000)     ;
        inf_in <= 1'b1 ;
        #(1690_000)    ;
        inf_in <= 1'b0 ; // 0
        #(560_000)     ;
        inf_in <= 1'b1 ;
        #(560_000)     ;
        inf_in <= 1'b0 ; // 1
        #(560_000)     ;
        inf_in <= 1'b1 ;
        #(1690_000)    ;
// 数据码 8'h22 0010_0010 0100_0100
        inf_in <= 1'b0 ; // 0
        #(560_000)     ;
        inf_in <= 1'b1 ;
        #(560_000)     ;
        inf_in <= 1'b0 ; // 1
        #(560_000)     ;
        inf_in <= 1'b1 ;
        #(1690_000)    ;
        inf_in <= 1'b0 ; // 0
        #(560_000)     ;
        inf_in <= 1'b1 ;
        #(560_000)     ;
        inf_in <= 1'b0 ; // 0
        #(560_000)     ;
        inf_in <= 1'b1 ;
        #(560_000)     ;
        inf_in <= 1'b0 ; // 0
        #(560_000)     ;
        inf_in <= 1'b1 ;
        #(560_000)     ;
        inf_in <= 1'b0 ; // 1
        #(560_000)     ;
        inf_in <= 1'b1 ;
        #(1690_000)    ;
        inf_in <= 1'b0 ; // 0
        #(560_000)     ;
        inf_in <= 1'b1 ;
        #(560_000)     ;
        inf_in <= 1'b0 ; // 0
        #(560_000)     ;
        inf_in <= 1'b1 ;
        #(560_000)     ;
// 数据反码 8'hDD 1101_1101 1011_1011
        inf_in <= 1'b0 ; // 1
        #(560_000)     ;
        inf_in <= 1'b1 ;
        #(1690_000)    ;
        inf_in <= 1'b0 ; // 0
        #(560_000)     ;
        inf_in <= 1'b1 ;
        #(560_000)     ;
        inf_in <= 1'b0 ; // 1
        #(560_000)     ;
        inf_in <= 1'b1 ;
        #(1690_000)    ;
        inf_in <= 1'b0 ; // 1
        #(560_000)     ;
        inf_in <= 1'b1 ;
        #(1690_000)    ;
        inf_in <= 1'b0 ; // 1
        #(560_000)     ;
        inf_in <= 1'b1 ;
        #(1690_000)    ;
        inf_in <= 1'b0 ; // 0
        #(560_000)     ;
        inf_in <= 1'b1 ;
        #(560_000)     ;
        inf_in <= 1'b0 ; // 1
        #(560_000)     ;
        inf_in <= 1'b1 ;
        #(1690_000)    ;
        inf_in <= 1'b0 ; // 1
        #(560_000)     ;
        inf_in <= 1'b1 ;
        #(1690_000)    ;
// 结束码 
        inf_in <= 1'b0 ;
        #(560_000)     ;
        inf_in <= 1'b1 ;
        #(1_000_000)   ;
// 重复码 
        inf_in <= 1'b0 ;
        #(9_000_000)   ;
        inf_in <= 1'b1 ;
        #(2_250_000)   ;
// 结束码 
        inf_in <= 1'b0 ;
        #(560_000)     ;
        inf_in <= 1'b1 ;
        #(1_000_000)   ;
        $stop             ;
    end
    always #( CYCLE / 2 ) sys_clk = ~sys_clk ;


endmodule

 

 

其他模块是之前的。

已上板验证成功。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值