开启辅助访问
 找回密码
 立即注册

用这个库居然可以使用Python进行FPGA逻辑开发

vincenttin 回答数20 浏览数1105
未经私信同意禁止转载!
不好意思,又标题党了,为了骗阅读量没办法。。。
前言

今天为大家介绍一下python的MyHDL 库。MyHDL项目的目标是通过python语言的优雅和简洁性来增强硬件设计者的能力。
MyHDL是一种免费、开源的软件包,用于使用python作为硬件描述和验证语言。python是一种非常高级的语言,硬件设计者可以利用它的全部力量来建模和仿真他们的设计。此外,可以将设计转换为verilog或vhdl语言。这提供了一台融入传统设计流程的切入口。
这个库有完整的文档,网上还有翻译成中文的《MyHDL中文手册》,自行搜索。今天我为大家演示一台完整的使用MyDHL进行FPGA逻辑开发的流程。程序员都喜欢搞hello world, 我们硬件工程师都是弄个流水灯。
一、编写开发功能代码

流水灯的代码用硬件描述语言来写,可以写出花,今天我们就用最朴实的移位寄存器来实现。对0b00000001循环向左移位就可以实现流水灯的功能。由于我们使用的LED电路是低电平点亮,所以在输出的时候需要将输出按位取反。Python代码如下:
from myhdl import *

@block
def shifting_register(clock, reset,led_driver):
    """ Incrementer with enable.
    clock -- clock input
    reset -- asynchronous reset input
    reg -- output port to drive leds
    """
    reg = Signal(modbv(1)[8:])

    @always(clock.posedge, reset.negedge)
    def shift():
        if not reset:
            reg.next = 1
        else:
            if reg[7] == 1:
                reg.next = 1
            else:
                reg.next = reg<<1
        led_driver.next = ~ reg
    return shiftFPGA 开发板使用的12M晶振,所以我们还需要一台分频器,产生一台0.5Hz的时钟来驱动移位寄存器。代码也很简单:
from myhdl import *

@block
def clock_divider(clock, reset,clock_led):
    """ Incrementer with enable.
    clock -- clock input
    reset -- asynchronous reset input
    clock_led -- led clock output frequency is clock/6 000 000
    """
    counter = Signal(modbv(0,min=0,max=2**24))

    @always(clock.posedge, reset.negedge)
    def divider():
        if not reset:
            counter.next = 0
            clock_led.next  =  True
        else:
            counter.next = counter + 1
            if counter == 3000000 :
                counter.next = 0
                clock_led.next = not clock_led
    return divider接下来我们在顶层链接两个模块,形成完整的设计。
from myhdl import *
from clock_divider import clock_divider
from shifting_register import shifting_register

@block
def running_led(clock, reset,led_driver):
    """ Incrementer with enable.
    clock -- clock input
    reset -- asynchronous reset input
    leds -- output for led driver
    """
    clock_led = Signal(bool(0))

    clock_divider_1 =     clock_divider(clock, reset, clock_led)
    shifting_register_1 =    shifting_register(clock_led, reset,  led_driver)

    return clock_divider_1,shifting_register_1二、仿真代码

逻辑开发的麻烦之处在于后期验证非常麻烦,不能像MCU那样进行断点仿真,所有前期的逻辑仿真非常重要。MyHDL同样支持对设计进行仿真,并且好像还可以联合Verilog进行仿真,不过这一台我没有尝试。
这里只放一台移位寄存器的textbench代码。完整的设计会上传到网盘,在文末能看到链接。
from myhdl import *
from running_led import running_led

@block
def running_led_testbech():
    clock = Signal(bool(0))
    reset = ResetSignal(0,active = 0, async= True)
    led_driver = Signal(intbv(1)[8:])

    runing_led_1 = running_led(clock,reset,led_driver)
    HALF_PERIOD = delay(10)

    @always(HALF_PERIOD)
    def clockGen():
        clock.next = not clock

    @instance
    def stimulus():
        reset.next = 1
        delay(20)
        reset.next = 0
        delay(20)
        reset.next = 1

        for i in range(100):
            yield clock.negedge
        rAIse StopSimulation()

    @instance
    def monitor():
        print("clock    led")
        yield reset.posedge
        while 1:
            yield clock.posedge
            yield delay(1)
            print("  %s    %s"%(int(clock),int(led_driver)))
    return clockGen, stimulus,monitor,runing_led_1

tb =  running_led_testbech()
tb.config_sim(trace=True)
tb.run_sim()这段代码中添加了波形查看的支持,运行完测试脚本后会得到一台.vcd文件,这个文件可以用GTK打开来查看。



led_wave

三、转换为Verilog

在仿真验证设计完成之后,我们需要将python源代码转化为verilog,因为现行的各大FPGA供应商的工具或是只支持Verilog 和VHDL设计,当然目前也支持C和Matlab。但是HDL语言在严谨性和逻辑效率上或是有着无可比拟的有点的。
使用下面代码,可以将我们前面的设计文件转化为Verilog。
from myhdl import *
from running_led import running_led

clock = Signal(bool(0))
reset = ResetSignal(0, active=0, async=True)
led_driver = Signal(intbv(1)[8:])

runing_led_1 = running_led(clock, reset, led_driver)

runing_led_1.convert(hdl='Verilog')转化完的结果如下:
// File: running_led.v
// Generated by MyHDL 0.10
// Date: Sun Jan  6 18:32:47 2019

`timescale 1ns/10ps

module running_led (
    clock,
    reset,
    led_driver
);
// Incrementer with enable.
// clock -- clock input
// reset -- asynchronous reset input
// leds -- output for led driver

input clock;
input reset;
output [7:0] led_driver;
reg [7:0] led_driver;

reg clock_led;
reg [23:0] clock_divider0_counter;
reg [7:0] shifting_register0_reg;



always @(posedge clock, negedge reset) begin: RUNNING_LED_CLOCK_DIVIDER0_DIVIDER
    if ((!reset)) begin
        clock_divider0_counter <= 0;
        clock_led <= 1'b1;
    end
    else begin
        clock_divider0_counter <= (clock_divider0_counter + 1);
        if ((clock_divider0_counter == 3000000)) begin
            clock_divider0_counter <= 0;
            clock_led <= (!clock_led);
        end
    end
end


always @(posedge clock_led, negedge reset) begin: RUNNING_LED_SHIFTING_REGISTER0_SHIFT
    if ((!reset)) begin
        shifting_register0_reg <= 1;
    end
    else begin
        if ((shifting_register0_reg[7] == 1)) begin
            shifting_register0_reg <= 1;
        end
        else begin
            shifting_register0_reg <= (shifting_register0_reg << 1);
        end
    end
    led_driver <= (~shifting_register0_reg);
end

endmodule
这个代码很简单,可以人工比对转化的正确性。
四、在FPGA上实现

得到Verilog文件,后面的设计流程就参照一般FPGA开发的流程了。
市场上用的最多的是Xilinx 和Altera的。但是前一段时间刚好一元夺宝中了一台Latticed的小开发板,叫小脚丫。就长这样!



step_mxo2_c1

今天就用它来开发了,第一次使用Lattice的芯片,就当给他们做广告了。
下面这是开发流程的详解。照着做就可以了,非常简单。
http://www.stepfpga.com/doc/%E5%BF%AB%E9%80%9F%E4%B8%8A%E6%89%8Bstep-mxo2-c
管脚分配如下:



LED_IO


后记
其实是使用Python开发逻辑,没有看出足够大的优势,受限于并行电路描述的复杂性,语言上并没有体现出足够的简洁。但是能看到MyDHL在仿真上的优势,如果你在做图像算法,或者其他算法,可以直接调用电脑上的资源进行仿真。
工程链接:
链接:https://pan.baidu.com/s/1mQlNsM0jG7AbrWkn9SjfUg
提取码:xn7o

欢迎关注我的专栏,你将看到更多Python与硬件结合的文章。
使用道具 举报
| 来自北京 用Deepseek满血版问问看
流星可乐 | 未知
还有这种东西
用Deepseek满血版问问看
回复
使用道具 举报
yusyang | 来自广东
好几年前就出来了,更新了10个版本
回复
使用道具 举报
fexsilence | 来自北京
我们学校还开发了一个叫pymtl的
回复
使用道具 举报
zhxymh | 来自北京
我也用了这个工具,我觉得这个工具最大的好处就是仿真,可惜我本人基本没有从事过仿真的开发工作。所以在学习中也不够深入。你对写仿真在行吗?希望和你请教
回复
使用道具 举报
zhongruken | 来自吉林
不在行,我做逻辑开发比较少。
回复
使用道具 举报
cpiao | 来自北京
这语法跟verilog几乎没有区别,有学这个的功夫可以把verilog学一遍了,相比之下不如学Xilinx的HSL,那个是真C++语法写硬件,唯一缺点就是写非标准接口时序太痛苦
回复
使用道具 举报
wgycn | 未知
文章的结尾说了,这个语言上没有简洁的优势,有优势的地方在于仿真。这个库支持python与verilog联合仿真,后面应该会有文章进一步讨论这个问题。至于HLS,个人觉得,在算法领域的优势是明显的,但是应该用来设计ip,而不是用来设计整个系统的,接口和总线还是用硬件描述语言来设计。有兴趣的话可以看一下专栏里面用与PYNQ的文章,在zynq上使用python进行设计。后续会有更多相关文章放出,欢迎关注专栏,并提出建议!
回复
使用道具 举报
DJ战神 | 来自北京
就算是仿真sv也很强了……很久以前看过何种编译到hdl的实现,最后发现还是直接写hdl效率最高
回复
使用道具 举报
w99 | 来自浙江
我还是老老实实Verilog吧 最近也在看HLS
回复
使用道具 举报

相关问题更多>

123下一页
快速回复
您需要登录后才可以回帖 登录 | 立即注册

当贝投影