VHDL 和 Verilog 生成
从 SpinalHDL 组件生成 VHDL 和 Verilog
要从 SpinalHDL 组件生成 VHDL,您只需在 Scala main
函数中调用 SpinalVhdl(new YourComponent)
即可。
生成 Verilog 完全相同,但用 SpinalVerilog
代替 SpinalVHDL
import spinal.core._
// A simple component definition.
class MyTopLevel extends Component {
// Define some input/output signals. Bundle like a VHDL record or a Verilog struct.
val io = new Bundle {
val a = in Bool()
val b = in Bool()
val c = out Bool()
}
// Define some asynchronous logic.
io.c := io.a & io.b
}
// This is the main function that generates the VHDL and the Verilog corresponding to MyTopLevel.
object MyMain {
def main(args: Array[String]) {
SpinalVhdl(new MyTopLevel)
SpinalVerilog(new MyTopLevel)
}
}
重要
SpinalVhdl
和 SpinalVerilog
可能需要创建组件类的多个实例,因此第一个参数不是 Component
引用,而是返回新组件的函数。
重要
SpinalVerilog
实施于 2016 年 6 月 5 日开始。该后端成功通过了与 VHDL 相同的回归测试(RISCV CPU、多核和流水线 Mandelbrot、UART RX/TX、单时钟域 fifo、双时钟域 fifo、格雷码计数器, …)。
如果您对这个新后端有任何问题,请创建 Github 工单 描述问题。
Scala 的参数化
参数名称 |
类型 |
默认值 |
描述 |
---|---|---|---|
|
SpinalMode |
null |
设置 SpinalHDL 生成HDL的模式。
可以设置为
VHDL 或 Verilog |
|
ClockDomainConfig |
RisingEdgeClock
AsynchronousReset
ResetActiveHigh
ClockEnableActiveHigh
|
设置将用作所有新 ``ClockDomain``时钟域默认值的配置。 |
|
Boolean |
false |
将所有无符号/有符号顶级 io 更改为 std_logic_vector类型。 |
|
IClockDomainFrequency |
UnknownFrequency |
默认时钟频率。 |
|
String |
当前目录 |
生成文件的目录。 |
这是设置它们的语法:
SpinalConfig(mode=VHDL, targetDirectory="temp/myDesign").generate(new UartCtrl)
// Or for Verilog in a more scalable formatting:
SpinalConfig(
mode=Verilog,
targetDirectory="temp/myDesign"
).generate(new UartCtrl)
来自 shell 的参数化
您还可以使用命令行参数指定生成参数。
def main(args: Array[String]): Unit = {
SpinalConfig.shell(args)(new UartCtrl)
}
命令行参数的语法是:
Usage: SpinalCore [options]
--vhdl
Select the VHDL mode
--verilog
Select the Verilog mode
-d | --debug
Enter in debug mode directly
-o <value> | --targetDirectory <value>
Set the target directory
生成的 VHDL 和 Verilog
如何将 SpinalHDL RTL 描述转换为 VHDL 和 Verilog 非常重要:
Scala 中变量的名称将保留在 VHDL 和 Verilog 中。
Scala 中的
Component
组件层次结构会保留在 VHDL 和 Verilog 中。Scala 中的
when
语句会生成为 VHDL 和 Verilog 中的 if 语句。Scala 中的
switch
语句在所有标准情况下都生成为 VHDL 和 Verilog 中的 case 语句。
组织
当您使用 VHDL 生成器时,所有模块都会生成到一个文件中,其中包含三个部分:
包含所有 Enum 定义的包
包含架构中所有元素使用函数的包
您的设计所需的所有组件
当您使用 Verilog 生成时,所有模块都会生成到一个文件中,其中包含两个部分:
使用的所有枚举定义
您的设计需要的所有模块
组合逻辑
Scala:
class TopLevel extends Component {
val io = new Bundle {
val cond = in Bool()
val value = in UInt(4 bits)
val withoutProcess = out UInt(4 bits)
val withProcess = out UInt(4 bits)
}
io.withoutProcess := io.value
io.withProcess := 0
when(io.cond) {
switch(io.value) {
is(U"0000") {
io.withProcess := 8
}
is(U"0001") {
io.withProcess := 9
}
default {
io.withProcess := io.value+1
}
}
}
}
VHDL:
entity TopLevel is
port(
io_cond : in std_logic;
io_value : in unsigned(3 downto 0);
io_withoutProcess : out unsigned(3 downto 0);
io_withProcess : out unsigned(3 downto 0)
);
end TopLevel;
architecture arch of TopLevel is
begin
io_withoutProcess <= io_value;
process(io_cond,io_value)
begin
io_withProcess <= pkg_unsigned("0000");
if io_cond = '1' then
case io_value is
when pkg_unsigned("0000") =>
io_withProcess <= pkg_unsigned("1000");
when pkg_unsigned("0001") =>
io_withProcess <= pkg_unsigned("1001");
when others =>
io_withProcess <= (io_value + pkg_unsigned("0001"));
end case;
end if;
end process;
end arch;
时序逻辑
Scala:
class TopLevel extends Component {
val io = new Bundle {
val cond = in Bool()
val value = in UInt (4 bits)
val resultA = out UInt(4 bits)
val resultB = out UInt(4 bits)
}
val regWithReset = Reg(UInt(4 bits)) init(0)
val regWithoutReset = Reg(UInt(4 bits))
regWithReset := io.value
regWithoutReset := 0
when(io.cond) {
regWithoutReset := io.value
}
io.resultA := regWithReset
io.resultB := regWithoutReset
}
VHDL:
entity TopLevel is
port(
io_cond : in std_logic;
io_value : in unsigned(3 downto 0);
io_resultA : out unsigned(3 downto 0);
io_resultB : out unsigned(3 downto 0);
clk : in std_logic;
reset : in std_logic
);
end TopLevel;
architecture arch of TopLevel is
signal regWithReset : unsigned(3 downto 0);
signal regWithoutReset : unsigned(3 downto 0);
begin
io_resultA <= regWithReset;
io_resultB <= regWithoutReset;
process(clk,reset)
begin
if reset = '1' then
regWithReset <= pkg_unsigned("0000");
elsif rising_edge(clk) then
regWithReset <= io_value;
end if;
end process;
process(clk)
begin
if rising_edge(clk) then
regWithoutReset <= pkg_unsigned("0000");
if io_cond = '1' then
regWithoutReset <= io_value;
end if;
end if;
end process;
end arch;
VHDL 和 Verilog 属性
在某些情况下,为设计中的某些信号提供属性以修改它们的综合方式很有用。
为此,您可以对设计中的任何信号或存储器调用以下函数:
语法 |
描述 |
---|---|
|
添加一个名为 |
|
添加一个字符串属性,并将给定的 |
示例:
val pcPlus4 = pc + 4
pcPlus4.addAttribute("keep")
用 VHDL 生成声明:
attribute keep : boolean;
signal pcPlus4 : unsigned(31 downto 0);
attribute keep of pcPlus4: signal is true;
用 Verilog 生成声明:
(* keep *) wire [31:0] pcPlus4;