MyHDL,体验一下“用python设计电路”

2022-03-29 14:14:48 浏览数 (2)

写代码:

下面的myhdl代码写了一个模块top,里面有两个计数器:cnt1从0计到9,当cnt1=9时,cnt2从0计到4。

代码语言:javascript复制
from myhdl import *

@block
def top(cnt1, cnt2, clk, rst_n):
    """
    this is an example of counter
    """

    @always_seq(clk.posedge, reset=rst_n)
    def counter1():
        if cnt1 == 9:
            cnt1.next = 0
        else:
            cnt1.next = cnt1   1

    @always(clk.posedge, rst_n.negedge)
    def counter2():
        if rst_n == 0:
            cnt2.next = 5
        elif cnt1 == 9:
            if cnt2 == 4:
                cnt2.next = 0
            else:
                cnt2.next = cnt2   1

    return counter1, counter2

从上面的代码可以看到其实与verilog非常接近,只是复位和时钟在python装饰器always和always_seq里实现了。另一个特殊点是,给一个信号赋值需要用xxx.next,这样就描述了DFF的功能,赋的值下一个时钟生效。

转Verilog:

我们用下面的方法来把myhdl转成verilog:

代码语言:javascript复制
def convert():
    cnt1 = Signal(intbv(0,0,16))
    cnt2 = Signal(intbv(0,0,8))
    clk = Signal(bool(0))
    rst_n = ResetSignal(0, active=0, isasync=True)
    dut = top(cnt1, cnt2, clk, rst_n)
    dut.convert(hdl='verilog')

convert()

直接上效果,不解释了,大家自己看:

代码语言:javascript复制
// File: top.v
// Generated by MyHDL 0.11
// Date: Sat Feb 26 21:29:06 2022

`timescale 1ns/10ps

module top (
    cnt1,
    cnt2,
    clk,
    rst_n
);
// this is an example of counter

output [3:0] cnt1;
reg [3:0] cnt1;
output [2:0] cnt2;
reg [2:0] cnt2;
input clk;
input rst_n;

always @(posedge clk, negedge rst_n) begin: TOP_COUNTER1
    if (rst_n == 0) begin
        cnt1 <= 0;
    end
    else begin
        if ((cnt1 == 9)) begin
            cnt1 <= 0;
        end
        else begin
            cnt1 <= (cnt1   1);
        end
    end
end

always @(posedge clk, negedge rst_n) begin: TOP_COUNTER2
    if ((rst_n == 0)) begin
        cnt2 <= 5;
    end
    else if ((cnt1 == 9)) begin
        if ((cnt2 == 4)) begin
            cnt2 <= 0;
        end
        else begin
            cnt2 <= (cnt2   1);
        end
    end
end

endmodule

写验证环境,仿真:

代码语言:javascript复制
from random import randrange

def testbench():

    cnt1 = Signal(intbv(0,0,16))
    cnt2 = Signal(intbv(0,0,8))
    clk = Signal(bool(0))
    rst_n = ResetSignal(0, active=0, isasync=True)

    dut = top(cnt1, cnt2, clk, rst_n)

    @always(delay(10))
    def clkgen():
        clk.next = not clk

    @instance
    def rstgen():
        yield delay(15)
        rst_n.next = 1

    return dut, clkgen, rstgen

def simulate(timesteps):
    tb = traceSignals(testbench)
    sim = Simulation(tb)
    sim.run(timesteps)

simulate(2000)

与Verilog的验证环境没有太大区别,实例化、编写时钟、复位等激励,设置dump波形,仿真时间等。

看波形:

运行后目录下产生testbench.vcd。用Verdi打开如下图:

0 人点赞