Verilog-实现4-FSK字符编码(无FM)
在这里,我们将研究在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-无符号);
- 全字大小;
- 分数部分的大小。
接下来,我们来看一个简单的例子。
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'0,io_Bit_1,1'0}+{2'0,io_Bit_2},1'0}-4'3)
- {1'0,0,1'0}:000
- {2'0,1}:001
- {0,0,0} + {0,0,1}: 001
- {001, 0}: 0010
- 4'3:0011
现在让我们继续回答这个问题。 如果我们采取位减法,结果是:[1111]。
- 0010 - 0011 = -1
- 我们采取模块:1:0001
- 反转位:0001:1110
- 添加1:1110+1:1111
基于上述论文,我们可以认为4-FSK调制器的简化实现是正确的。
结论
在这个例子中,我们分析了在Engee中生成和验证Verilog代码的可能性,并确保这种开发FPGA系统的方法是适用的和相关的。 此外,由于能够即时编辑和测试模型,它可以显着加快开发过程。