FPGA学习verilog实现b码解码

verilog实现b码解码

时序图和状态转换图

在这里插入图片描述状态转换

代码

b_decoder.v

module b_decoder (
    input wire clk,
    input wire rst_n,
    input wire irig_b,
    output wire [6:0]second_out,
    output wire [6:0]minute_out,
    output wire [6:0]hour_out,
    output wire [9:0]day_out,
    output wire [7:0]year_out
);

parameter MAX_8MS = 999_999;
parameter MAX_5MS = 624_999;
parameter MAX_2MS = 249_999;
parameter MAX_1S = 99;
parameter IDLE = 4'b0000;
parameter P = 4'b0001;
parameter SEC = 4'b0011;
parameter MIN = 4'b0010;
parameter HOUR = 4'b0110;
parameter DAY1 = 4'b0111;
parameter DAY2 = 4'b0101;
parameter YEAR = 4'b0100;
parameter S0 = 4'b1100;
parameter S1 = 4'b1101;
parameter S2 = 4'b1111;
parameter S3 = 4'b1110;

reg irig_b_r1;
reg [19:0]cnt_pos;
reg [1:0]decode;
reg [3:0]state;
reg [6:0]cnt_1s;

reg [6:0]second;
reg [6:0]minute;
reg [5:0]hour;
reg [9:0]day;
reg [7:0]year;

//下降沿和上升沿判断
//延迟一拍的输入波形
always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
        irig_b_r1 <= 1'b0;
    end
    else begin
        irig_b_r1 <= irig_b;
    end
end


assign edge_pos = irig_b & ~irig_b_r1;//上升沿
assign edge_neg = ~irig_b & irig_b_r1;//下降沿

//b码高电平计数
always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
        cnt_pos <= 20'd0;
    end
    else if (edge_pos) begin
        cnt_pos <= 20'd1;
    end
    else if (irig_b) begin
        cnt_pos <= cnt_pos +20'b1;
    end
    else begin
        cnt_pos <= cnt_pos;
    end
end

//下降沿判断,波形编码
always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
        decode <= 2'b00;
    end
    else if (cnt_pos == MAX_8MS + 1 && edge_neg) begin
        decode <= 2'b11;
    end
    else if (cnt_pos == MAX_5MS + 1 && edge_neg) begin
        decode <= 2'b01;
    end
    else if (cnt_pos == MAX_2MS + 1 && edge_neg) begin
        decode <= 2'b00;
    end
end

//状态机
always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
        state <= IDLE;
    end
    else case (state)
        IDLE : begin
            if (decode == 2'b11 && edge_pos) begin
                state <= P;
            end
            else begin
                state <= state;
            end
        end
        P : begin
            if (decode == 2'b11 && edge_pos) begin
                state <= SEC;
            end
            else if ((decode == 2'b00 && edge_pos)||(decode == 2'b00 && edge_pos)) begin
                state <= IDLE;
            end
            else begin
                state <= state;
            end
        end
        SEC : begin
            if (decode == 2'b11 && edge_pos) begin
                state <= MIN;
            end
            else begin
                state <= state;
            end
        end
        MIN : begin
            if (decode == 2'b11 && edge_pos) begin
                state <= HOUR;
            end
            else begin
                state <= state;
            end
        end
        HOUR : begin
            if (decode == 2'b11 && edge_pos) begin
                state <= DAY1;
            end
            else begin
                state <= state;
            end
        end
        DAY1 : begin
            if (decode == 2'b11 && edge_pos) begin
                state <= DAY2;
            end
            else begin
                state <= state;
            end
        end
        DAY2 : begin
            if (decode == 2'b11 && edge_pos) begin
                state <= YEAR;
            end
            else begin
                state <= state;
            end
        end
        YEAR : begin
            if (decode == 2'b11 && edge_pos) begin
                state <= S0;
            end
            else begin
                state <= state;
            end
        end
        S0 : begin
            if (decode == 2'b11 && edge_pos) begin
                state <= S1;
            end
            else begin
                state <= state;
            end
        end
        S1 : begin
            if (decode == 2'b11 && edge_pos) begin
                state <= S2;
            end
            else begin
                state <= state;
            end
        end
        S2 : begin
            if (decode == 2'b11 && edge_pos) begin
                state <= S3;
            end
            else begin
                state <= state;
            end
        end
        S3 : begin
            if (decode == 2'b11 && edge_pos) begin
                state <= P;
            end
            else begin
                state <= state;
            end
        end
        default: state <= state;
    endcase
end
    
    
// 根据状态机控制cnt_1s计数
always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
        cnt_1s <= 7'd0;
    end
    else if (cnt_1s == MAX_1S && edge_pos) begin
        cnt_1s <= 7'd0;
    end
    else if (state == P && edge_pos) begin
        cnt_1s <= 7'd1;
    end
    else if (edge_pos) begin
        cnt_1s <= cnt_1s + 7'd1;
    end
    else begin
        cnt_1s <= cnt_1s;
    end
end

//赋值
always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
        second <= 7'b0;
    end
    else if (cnt_1s == 8'd1) begin
        second[0] <= decode[0];
    end
    else if (cnt_1s == 8'd2) begin
        second[1] <= decode[0];
    end
    else if (cnt_1s == 8'd3) begin
        second[2] <= decode[0];
    end
    else if (cnt_1s == 8'd4) begin
        second[3] <= decode[0];
    end
    else if (cnt_1s == 8'd6) begin
        second[4] <= decode[0];
    end
    else if (cnt_1s == 8'd7) begin
        second[5] <= decode[0];
    end
    else if (cnt_1s == 8'd8) begin
        second[6] <= decode[0];
    end
    else begin
        second <= second;
    end
end

always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
        minute <= 7'b0;
    end
    else if (cnt_1s == 8'd10) begin
        minute[0] <= decode[0];
    end
    else if (cnt_1s == 8'd111) begin
        minute[1] <= decode[0];
    end
    else if (cnt_1s == 8'd12) begin
        minute[2] <=decode[0];
    end
    else if (cnt_1s == 8'd13) begin
        minute[3] <= decode[0];
    end
    else if (cnt_1s == 8'd15) begin
        minute[4] <= decode[0];
    end
    else if (cnt_1s == 8'd16) begin
        minute[5] <= decode[0];
    end
    else if (cnt_1s == 8'd17) begin
        minute[6] <= decode[0];
    end
    else begin
        minute <= minute;
    end
end

always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
        hour <= 6'b0;
    end
    else if (cnt_1s == 8'd20) begin
        hour[0] <= decode[0];
    end
    else if (cnt_1s == 8'd21) begin
        hour[1] <= decode[0];
    end
    else if (cnt_1s == 8'd22) begin
        hour[2] <= decode[0];
    end
    else if (cnt_1s == 8'd23) begin
        hour[3] <= decode[0];
    end
    else if (cnt_1s == 8'd25) begin
        hour[4] <= decode[0];
    end
    else if (cnt_1s == 8'd26) begin
        hour[5] <= decode[0];
    end
    else begin
        hour <= hour;
    end
end

always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
        day <= 10'b0;
    end
    else if (cnt_1s == 8'd30) begin
        day[0] <= decode[0];
    end
    else if (cnt_1s == 8'd31) begin
        day[1] <= decode[0];
    end
    else if (cnt_1s == 8'd32) begin
        day[2] <= decode[0];
    end
    else if (cnt_1s == 8'd33) begin
        day[3] <= decode[0];
    end
    else if (cnt_1s == 8'd35) begin
        day[4] <= decode[0];
    end
    else if (cnt_1s == 8'd36) begin
        day[5] <= decode[0];
    end
    else if (cnt_1s == 8'd37) begin
        day[6] <= decode[0];
    end
    else if (cnt_1s == 8'd38) begin
        day[7] <= decode[0];
    end
    else if (cnt_1s == 8'd40) begin
        day[8] <= decode[0];
    end
    else if (cnt_1s == 8'd41) begin
        day[9] <= decode[0];
    end
    else begin
        day <= day;
    end
end

always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
        year <= 6'b0;
    end
    else if (cnt_1s == 8'd50) begin
        year[0] <= decode[0];
    end
    else if (cnt_1s == 8'd51) begin
        year[1] <= decode[0];
    end
    else if (cnt_1s == 8'd52) begin
        year[2] <= decode[0];
    end
    else if (cnt_1s == 8'd53) begin
        year[3] <= decode[0];
    end
    else if (cnt_1s == 8'd55) begin
        year[4] <= decode[0];
    end
    else if (cnt_1s == 8'd56) begin
        year[5] <= decode[0];
    end
    else if (cnt_1s == 8'd57) begin
        year[6] <= decode[0];
    end
    else if (cnt_1s == 8'd58) begin
        year[7] <= decode[0];
    end
    else begin
        year <= year;
    end
end


assign second_out = second[6:4]*10 + second[3:0];
assign minute_out = minute[6:4]*10 + minute[3:0];
assign hour_out = hour[5:4]*10 + hour[3:0];
assign day_out = day[9:8]*100 + day[7:4]*10 + day[3:0];
assign year_out = year[7:4]*10 + year[3:0];

endmodule

tb文件

`timescale 1ns/1ps

module b_decoder_tb ();
    

reg clk;
reg rst_n;
reg irig_b;
wire  [6:0]second_out;
wire  [6:0]minute_out;
wire  [6:0]hour_out;
wire  [9:0]day_out;
wire  [7:0]year_out;

initial begin
    rst_n = 1'b0;
    clk = 1'b0;
    #2
    rst_n = 1'b1;
end

always #4 clk = ~clk;

wire [7:0]mem[1:100];

assign mem[1] = 8'h70; P
assign mem[2] = 8'h30; 0
assign mem[3] = 8'h30; 0
assign mem[4] = 8'h30; 0
assign mem[5] = 8'h31; 1
assign mem[6] = 8'h30; 0
assign mem[7] = 8'h30; 0
assign mem[8] = 8'h30; 0
assign mem[9] = 8'h30; 0

assign mem[10] = 8'h70; P
assign mem[11] = 8'h30; 0
assign mem[12] = 8'h30; 0
assign mem[13] = 8'h30; 0
assign mem[14] = 8'h31; 1
assign mem[15] = 8'h30; 0
assign mem[16] = 8'h30; 0
assign mem[17] = 8'h30; 0
assign mem[18] = 8'h31; 1
assign mem[19] = 8'h30; 0

assign mem[20] = 8'h70; P
assign mem[21] = 8'h31; 1
assign mem[22] = 8'h30; 0
assign mem[23] = 8'h30; 0
assign mem[24] = 8'h30; 0
assign mem[25] = 8'h30; 0
assign mem[26] = 8'h30; 0
assign mem[27] = 8'h30; 0
assign mem[28] = 8'h30; 0
assign mem[29] = 8'h30; 0

assign mem[30] = 8'h70; P
assign mem[31] = 8'h31; 1
assign mem[32] = 8'h30; 0
assign mem[33] = 8'h30; 0
assign mem[34] = 8'h30; 0
assign mem[35] = 8'h30; 0
assign mem[36] = 8'h31; 1
assign mem[37] = 8'h30; 0
assign mem[38] = 8'h31; 1
assign mem[39] = 8'h30; 0

assign mem[40] = 8'h70; P
assign mem[41] = 8'h30; 0
assign mem[42] = 8'h31; 1
assign mem[43] = 8'h30; 0
assign mem[44] = 8'h30; 0
assign mem[45] = 8'h30; 0
assign mem[46] = 8'h30; 0
assign mem[47] = 8'h30; 0
assign mem[48] = 8'h30; 0
assign mem[49] = 8'h30; 0

assign mem[50] = 8'h70; P
assign mem[51] = 8'h31; 1
assign mem[52] = 8'h30; 0
assign mem[53] = 8'h30; 0
assign mem[54] = 8'h30; 0
assign mem[55] = 8'h30; 0
assign mem[56] = 8'h30; 0
assign mem[57] = 8'h31; 1
assign mem[58] = 8'h30; 0
assign mem[59] = 8'h30; 0

assign mem[60] = 8'h70; P
assign mem[61] = 8'h30; 0
assign mem[62] = 8'h30; 0
assign mem[63] = 8'h30; 0
assign mem[64] = 8'h30; 0
assign mem[65] = 8'h30; 0
assign mem[66] = 8'h30; 0
assign mem[67] = 8'h30; 0
assign mem[68] = 8'h30; 0
assign mem[69] = 8'h30; 0

assign mem[70] = 8'h70; P
assign mem[71] = 8'h30; 0
assign mem[72] = 8'h30; 0
assign mem[73] = 8'h30; 0
assign mem[74] = 8'h30; 0
assign mem[75] = 8'h30; 0
assign mem[76] = 8'h31; 1
assign mem[77] = 8'h30; 0
assign mem[78] = 8'h30; 0
assign mem[79] = 8'h30; 0

assign mem[80] = 8'h70; P
assign mem[81] = 8'h30; 0
assign mem[82] = 8'h30; 0
assign mem[83] = 8'h30; 0
assign mem[84] = 8'h31; 1
assign mem[85] = 8'h31; 1
assign mem[86] = 8'h30; 0
assign mem[87] = 8'h31; 1
assign mem[88] = 8'h30; 0
assign mem[89] = 8'h31; 1

assign mem[90] = 8'h70; P
assign mem[91] = 8'h30; 0
assign mem[92] = 8'h30; 0
assign mem[93] = 8'h31; 1
assign mem[94] = 8'h31; 1
assign mem[95] = 8'h30; 0
assign mem[96] = 8'h30; 0
assign mem[97] = 8'h30; 0
assign mem[98] = 8'h30; 0
assign mem[99] = 8'h30; 0

assign mem[100] = 8'h70; P

reg [6:0]cnt_1s;
reg [20:0]cnt_10ms;
reg [2:0]state;
parameter IDLE = 3'd0;
parameter S0 = 3'd1;
parameter S1 = 3'd2;
parameter S2 = 3'd3;
parameter S3 = 3'd4;
parameter MAX_10MS = 1249999;
parameter MAX_8MS = 999_999;
parameter MAX_5MS = 624_999;
parameter MAX_2MS = 249_999;

always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
        state <= IDLE;
        cnt_10ms <= 21'd0;
        cnt_1s <= 7'd1;
    end
    else case (state)
        IDLE : begin
            if (mem[cnt_1s] == 8'h70) begin
                state <= S0;
                cnt_10ms <= 21'd0;
            end
            else if (mem[cnt_1s] == 8'h31) begin
                state <= S1;
                cnt_10ms <= 21'd0;
            end
            else if (mem[cnt_1s] == 8'h30) begin
                state <= S2;
                cnt_10ms <= 21'd0;
            end
        end
        S0: begin
            if (cnt_10ms == MAX_10MS - 2) begin
                state <= S3;
                cnt_10ms <= 21'd0;
            end
            else  begin
                cnt_10ms <= cnt_10ms + 21'd1;
            end

            if(cnt_10ms <= MAX_8MS)begin
                irig_b <= 1'b1;
            end
            else begin
                irig_b <= 1'b0;
            end
        end
        S1: begin
            if (cnt_10ms == MAX_10MS - 2) begin
                state <= S3;
                cnt_10ms <= 21'd0;
            end
            else  begin
                cnt_10ms <= cnt_10ms + 21'd1;
            end

            if(cnt_10ms <= MAX_5MS)begin
                irig_b <= 1'b1;
            end
            else begin
                irig_b <= 1'b0;
            end
        end
        S2: begin
            if (cnt_10ms == MAX_10MS - 2) begin
                state <= S3;
                cnt_10ms <= 21'd0;
            end
            else  begin
                cnt_10ms <= cnt_10ms + 21'd1;
            end

            if(cnt_10ms <= MAX_2MS)begin
                irig_b <= 1'b1;
            end
            else begin
                irig_b <= 1'b0;
            end
        end
        S3 : begin
            state <= IDLE;
            if (cnt_1s == 7'd100) begin
                cnt_1s <= 7'd1;       
            end
            else  begin
                cnt_1s <= cnt_1s + 7'd1;
            end
        end
    endcase
end

b_decoder b_decoder_1 (
    .clk(clk),
    .rst_n(rst_n),
    .irig_b(irig_b),
    .second_out(second_out),
    .minute_out(minute_out),
    .hour_out(hour_out),
    .day_out(day_out),
    .year_out(year_out)
);

endmodule

这个tb文件本质上是一个编码器。

仿真

连续两个p开始计数
在这里插入图片描述cnt_1s为68时,年的数据识别完成。
在这里插入图片描述

  • 9
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值