Verilog学习脚印3-简单状态机(三角波)

Verilog学习脚印3-简单状态机(三角波)
附:verilog语法笔记(持续更新ing)


bash命令

bash调用dve和vcs的命令:

dve & // 启用VDE
vcs *.v -R -timescale=1ns/10ps +v2k +define+RTL_SAIF // 编译

实例1:三角波发生器

电路原理(来自B站-北交李金城老师的PPT,侵删)

注意跳转条件

在这里插入图片描述

代码实现与验证

完整代码:

// 三角波发生器
`timescale 1ns/1ps
// ----- 定义 -----
module tri_gen(
                clk,
                res,
                d_out
);
input           clk;
input           res;
output[8:0]     d_out; // 注意位数!

reg             state; // 主状态机寄存器
reg[8:0]        d_out;

always@(posedge clk or negedge res)
if(~res) begin
    state<=0; d_out<=0;
end
else begin
    case(state)
    0: begin // 0状态:上升
        d_out<=d_out+1; // 注意!d_out以300跳出state 0
        if(d_out==299)begin
            state<=1;
        end
    end
    1: begin // 1状态:下降
        d_out<=d_out-1; // 注意!d_out以0跳出state 1
        if(d_out==1)begin
            state<=0;
        end
    end
    endcase // 不要忘记endcase!!!
end

endmodule

// ----- testbench -----
module tri_gen_tb();
reg             clk,res;
wire[8:0]       d_out;
tri_gen tri_gen(       // 异名例化
                .clk(clk),
                .res(res),
                .d_out(d_out)
);

initial begin
    $dumpfile("tri_gen_tb.vcd"); // save wave file
    $dumpvars(0,tri_gen);
end

initial begin
            clk<=0;res<=0;
     #17    res<=1;
     #80000 $stop;
end

always #5 clk<=~clk;

endmodule

波形输出:
在这里插入图片描述


实例2:三角波发生器(加入平顶保持)

电路原理同上

代码实现与验证

代码如下:

// 三角波发生器
`timescale 1ns/1ps
// ----- 定义 -----
module tri_gen(
                clk,
                res,
                d_out
);
input           clk;
input           res;
output[8:0]     d_out; // 注意位数!

reg[1:0]        state; // 主状态机寄存器,注意位数!不要溢出!没用完时记得default!
reg[8:0]        d_out;
reg[7:0]        remain_cou; // 记录平顶周期个数 200个时钟周期

always@(posedge clk or negedge res)
if(~res) begin
    state<=0;d_out<=0;remain_cou<=0;
end
else begin
    case(state)
    0: begin // 0状态:上升
        d_out<=d_out+1; // 注意!d_out以300跳出state 0
        if(d_out==299)begin
            state<=1;
        end
    end
    /* 错误写法:
    1: begin
        remain_cou<=remain_cou+1;
        if(remain_cou==199) begin
            // remain_cou<=0; 错误写法!与'remain_cou<=remain_cou+1;'冲突!造成结果不确定
            state<=2;
        end
    end
    */
    // 正确写法:
    1: begin
        if(remain_cou==200) begin
            remain_cou<=0;
            state<=2;
        end
        else begin
            remain_cou<=remain_cou+1;
        end
    end
    2: begin // 1状态:下降
        d_out<=d_out-1; // 注意!d_out以0跳出state 1
        if(d_out==1)begin
            state<=0;
        end
    end
    default: begin
        state<=0;
        remain_cou<=0;
        d_out<=0;
    end
    endcase // 不要忘记endcase!!!
end

endmodule

// ----- testbench -----
module tri_gen_tb();
reg             clk,res;
wire[8:0]       d_out;
tri_gen tri_gen(       // 异名例化
                .clk(clk),
                .res(res),
                .d_out(d_out)
);

initial begin
    $dumpfile("tri_gen_tb.vcd"); // save wave file
    $dumpvars(0,tri_gen);
end

initial begin
            clk<=0;res<=0;
     #17    res<=1;
     #800000 $stop;
end

always #5 clk<=~clk;

endmodule

验证结果如下:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值