#verilog #wrap #fpga #rust-hdl #macro

macro build wrap_verilog_in_rust_hdl_macro

将Verilog代码包裹在rust-hdl模块中的proc-macro

2 个版本

0.1.1 2023年6月21日
0.1.0 2023年3月17日

#503 in 编程语言

MIT/Apache

77KB
1.5K SLoC

wrap_verilog_in_rust_hdl_macro

提供了一个 wrap_verilog! 宏,可以用于将Verilog模块包裹在Rust结构体中。

示例

use wrap_verilog_in_rust_hdl_macro::wrap_verilog;

wrap_verilog!("module test(); endmodule", "test");

更大的示例

在这个示例中,我们将包裹以下Verilog模块

module counter
(
    input clock,
    output [5:0] led
);
    reg [23:0] clockCounter = 0;
    localparam WAIT_TIME = 1000;
    reg [5:0] ledCounter = 0;
    
    always @(posedge clock) begin
        clockCounter <= clockCounter + 1;
        if (clockCounter == WAIT_TIME) begin
            clockCounter <= 0;
            ledCounter <= ledCounter + 1;
        end
    end
    
    assign led = ~ledCounter;
endmodule

要生成一个与rust-hdl兼容的结构体,我们可以使用 wrap_verilog! 宏。该宏接受包含Verilog代码和模块名的字符串字面量作为输入。

use wrap_verilog_in_rust_hdl_macro::wrap_verilog;

wrap_verilog!(
r#"
module counter
(
    input clock,
    output [5:0] led
);

reg [23:0] clockCounter = 0;
localparam WAIT_TIME = 1000;
reg [5:0] ledCounter = 0;

always @(posedge clock) begin
    clockCounter <= clockCounter + 1;
    if (clockCounter == WAIT_TIME) begin
        clockCounter <= 0;
        ledCounter <= ledCounter + 1;
    end
end

assign led = ~ledCounter;
endmodule
"#,
    "counter"
);

这会展开成以下结构体和逻辑实现

use rust_hdl::prelude::*;
#[derive(LogicBlock, Default)]
struct Counter {
    pub clock: Signal<
        In,
        Clock,
    >,
    pub led: Signal<
        Out,
        Bits<6usize>,
    >,
}

impl Logic for Counter {
    fn update(&mut self) {}
    fn connect(&mut self) {
        self.led.connect();
    }
    fn hdl(&self) -> Verilog {
        Verilog::Wrapper(Wrapper {
            code: "counter counter_inst(.clock(clock), .led(led));".into(),
            cores: r#"
                module counter
                (
                    input clock,
                    output [5:0] led
                );
                
                reg [23:0] clockCounter = 0;
                localparam WAIT_TIME = 1000;
                reg [5:0] ledCounter = 0;
                
                always @(posedge clock) begin
                    clockCounter <= clockCounter + 1;
                    if (clockCounter == WAIT_TIME) begin
                        clockCounter <= 0;
                        ledCounter <= ledCounter + 1;
                    end
                end
                
                assign led = ~ledCounter;
                endmodule
                "#.into(),
        })
    }
}

限制

  • 生成的模块仅仅是围绕Verilog的rust-hdl包装。
  • 由于rust-hdl不支持模拟Verilog,因此生成的模块不能使用rust-hdl进行模拟。
  • 您需要显式指定顶层模块的名称,因为我们无法自动检测它。

依赖项

~12MB
~228K SLoC