美文网首页PYNQ
用这个库居然可以使用Python进行FPGA逻辑开发

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

作者: IEEE1364 | 来源:发表于2019-01-06 20:47 被阅读46次

    不好意思,又标题党了,为了骗阅读量没办法。。。

    前言

    今天为大家介绍一下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 shift
    

    FPGA 开发板使用的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.JPG

    三、转换为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.png

    今天就用它来开发了,第一次使用Lattice的芯片,就当给他们做广告了。

    下面这是开发流程的详解。照着做就可以了,非常简单。
    http://www.stepfpga.com/doc/%E5%BF%AB%E9%80%9F%E4%B8%8A%E6%89%8Bstep-mxo2-c
    管脚分配如下:

    LED_IO.JPG

    后记

    其实是使用Python开发逻辑,没有看出足够大的优势,受限于并行电路描述的复杂性,语言上并没有体现出足够的简洁。但是能看到MyDHL在仿真上的优势,如果你在做图像算法,或者其他算法,可以直接调用电脑上的资源进行仿真。

    工程链接:
    链接:https://pan.baidu.com/s/1mQlNsM0jG7AbrWkn9SjfUg
    提取码:xn7o

    相关文章

      网友评论

        本文标题:用这个库居然可以使用Python进行FPGA逻辑开发

        本文链接:https://www.haomeiwen.com/subject/olxerqtx.html