4-FSK 调制器的 Verilog 生成¶
下面我们将了解在Engee中如何使用 4-FSK(频移键控)。
频率调制是一种通过改变信号频率来编码信息的调制方式。4-FSK(四电平频移键控)是 DMR(数字移动无线电)中使用的调制类型,也是 PMR(专业移动无线电)系统的最佳选择。
我们还将根据该模型生成 Verilog 代码,并在 Vivado 中验证其是否有效。
Verilog 是一种用于开发电子系统的硬件描述语言。
在不同抽象层次的模拟、数字和混合电子系统的设计、验证和实施中都需要 Verilog。
让我们声明辅助函数¶
function run_model( name_model)
Path = (@__DIR__) * "/" * name_model * ".engee"
if name_model in [m.name for m in engee.get_all_models()] # Проверка условия загрузки модели в ядро
model = engee.open( name_model ) # Открыть модель
model_output = engee.run( model, verbose=true ); # Запустить модель
else
model = engee.load( Path, force=true ) # Загрузить модель
model_output = engee.run( model, verbose=true ); # Запустить модель
engee.close( name_model, force=true ); # Закрыть модель
end
sleep(0.01)
return model_output
end
分析模型¶
我们研究了该模型的两个变体。一种是通过开关实现标准选择逻辑。第二个变体使用数学公式实现。在开发系统时,为了优化速度或资源方面的性能,这种方法经常被用来改变算法,使其无法识别。
以下是据以开发模型的表格。
symbol = [-3, -1, 1, 3]
bits = [[0, 0], [0, 1], [1, 0], [1, 1]]
println(join(["bits: $bit, symbol: $f" for (f, bit) in zip(symbol, bits)], "\n"))
下面的截图显示了所开发的模型。
源码块 4-FSK。
我们可以看到,使用该公式实现的程序块比原始程序块的逻辑少得多。此外,它的所有乘法块都使用 2 乘法,因此,在生成代码时,这种逻辑将表示移位一位。
我们还可以注意到,与使用 Int8 的原始代码块相比,本例使用的数据类型更短。
让我们简单谈谈定点数据类型。这种数据类型由 fi(X,1,16,5)命令指定,其中从左到右的参数是
- 数值; 符号(1-符号,0-无符号); 3; 字的全位大小; 4; 小数部分的大小。
接下来,我们来看一个简单的例子。
x = fi(7.5, 1, 7, 5)
y = fi(7.5, 1, 7, 3)
println("x: $x")
println("y: $y")
我们可以看到,在第一种情况下,数字7.5溢出。
x+y
我们还可以看到,在将这两个数字相加时,为它们分配的内存超过了最初分配的内存。
检查模型的性能¶
现在,让我们来分析一下两种实现方式之间的一致性。首先,让我们运行模型。
bit_1 = 1; bit_2 = 1;
println("Inp_bit: $([bit_1, bit_2])")
println()
@time run_model("FSK_V") # Запуск модели.
现在让我们比较一下结果。我们可以看到,两个结果都与初始表格一致。
Symbol_math = collect(Symbol_sim).value[end]
println("Symbol_math: $Symbol_math")
Symbol_switch = collect(Symbol_sim_switch).value[end]
println("Symbol_switch: $Symbol_switch")
为了验证最终项目,我们可以用公式的形式来表示我们要生成代码的模块。让我们确保公式与模型完全一致。
Symbol_ref = 2 * (2 * bit_1 + bit_2) - 3
println("Symbol_ref: $Symbol_ref")
println("Symbol_sim: $Symbol_math")
让我们从 4-FSK 调制器模块开始生成代码¶
让我们从代码生成命令开始。下面将介绍如何使用代码生成器。
? engee.generate_code
现在,让我们在模型中设置目标平台。
让我们执行代码生成。由于目标平台已在模型设置中明确设置,因此我们不需要目标字符串。
engee.generate_code(
"$(@__DIR__)/FSK_V.engee",
"$(@__DIR__)/V_Code",
subsystem_name="4-FSK modulator math",
# target="verilog"
)
使用 Vivado¶
现在,让我们在 Vivado 中测试获得的代码并下载获得的文件。
让我们创建一个空项目。
让我们添加生成的文件。
让我们为项目定义目标平台。
现在,我们可以看看我们项目的最终原理图了。结果非常简单。
让我们来综合并实施该项目。我们可以看到,时序没有定义。这是因为我们程序块的输入端口是空的,没有任何输入。
我们也可以通过观察模拟结果来验证这一点。所有输入和输出均未定义。
让我们通过将输入端口设置为常量来解决这个问题,并为我们的代码块添加流水线功能。
现在让我们重复模拟。
模拟的结果似乎并不正确,但让我们逐点分析一下生成的逻辑,前提是输入一对位[0,1]。让我们先用我们开发的公式分析一下结果。
Symbol_ref = 2*(2*0+1)-3 #[0,1]
println("Ожидаемый результат: $Symbol_ref")
现在,让我们继续编写代码:
(io_Symbol = {{1'h0, io_Bit_1, 1'h0} + {2'h0, io_Bit_2}, 1'h0} - 4'h3)
1.{1'h0, 0, 1'h0}: 000。 2.{2'h0, 1}: 001 3.{0,0,0} + {0,0,1}: 001 4.{001, 0}: 0010 5.4'h3: 0011
现在我们来看看答案。如果我们进行位相减,结果是[1111]. 1.0010 - 0011 = -1 2.取模:1:0001。 3.Invert the bits: 0001: 1110. 4.添加 1: 1110 + 1: 1111*.
根据以上论述,我们可以说,我们简化的 4-FSK 调制器的实现是正确的。
结论¶
在本示例中,我们分析了在 Engee 中生成和验证 Verilog 代码的可能性,我们已经看到这种 FPGA 系统开发方法的适用性和相关性。此外,由于能够即时编辑和测试模型,它还能大大加快开发过程。