【发布时间】:2017-11-22 02:06:22
【问题描述】:
我的背景是软件,我是 (System)Verilog 的新手,所以当我负责实现一个凯撒移位器时(将字符串中的每个字母移位 N 个字母,必要时环绕,例如 ABCXYZ 移位 3 变为 DEFABC),我写了以下内容,希望能够减少代码重复,就像我在软件中一样:
/* every variable except 'direction' has the type 'byte' */
always_comb
begin
shifted_char = fresh_char; /* don't touch bytes that aren't letters */
is_lower_case = "z" >= fresh_char && fresh_char >= "a";
is_upper_case = "Z" >= fresh_char && fresh_char >= "A";
if (is_lower_case || is_upper_case)
begin
unique if (is_lower_case)
alphabet_start = "a";
else if (is_upper_case)
alphabet_start = "A";
alphabet_position = fresh_char - alphabet_start;
if (direction == "f") /* direction is a module parameter: f for forwards results in a shifter, any other value results in an 'unshifter' */
new_alphabet_position = (26 + (alphabet_position + shift_by)) % 26;
else
new_alphabet_position = (26 + (alphabet_position - shift_by)) % 26;
shifted_char = new_alphabet_position + alphabet_start;
end
end
我的问题是(假设它是一个前移器):关于“% 26”部分,我是否可以期望合成器推断出它在该点获得的可能值的范围是 [26, 26+25+ 25] ([26, 76]) 所以只有两种情况逻辑需要区分(> 26和> 52),而不是[处理所有可能的256个不同输入时的智能调用是什么-(会是考虑>26、>52、>78 等案例...?还是有更好的方法?我跑题了...)]?
我总是可以做到以下几点:
new_alphabet_position = alphabet_position + shift_by;
if (new_alphabet_position > 25)
new_alpahbet_position -= 26;
/* Or, for the reverse shifter: */
new_alphabet_position = alphabet_position - shift_by;
if (new_alphabet_position < 0)
new_alpahbet_position += 26;
...但是很好奇并想问这个问题,以及一个相关的问题(我希望更多人能够回答):它可以用来制作普通的非 2 次幂计数器吗(例如。 计数 https://forums.xilinx.com/t5/Synthesis/Modulus-synthesizable-or-non-synthesizable/td-p/747493
【问题讨论】:
-
即使从软件的角度来看,这也不是最有效的程序。至于硬件,您要求它合成几个全加器和除法器(%)。如果有的话,可能会产生丑陋的结果。看起来你需要一起重新考虑算法。此外,您还需要以某种方式将其与时钟同步。
-
@Serge 它在软件中的效率如何?关于硬件,综合工具不会找到逻辑上等效的东西并避免合成分频器吗?至于加法器,这对我来说似乎是不可避免的;不是吗?
-
我的意思是,由于您只使用 ascii 字母,您可能能够找到一种不同的方法来解决问题,例如使用特殊字母表来尝试摆脱额外的 +/- 26 操作和特别是模运算符。在软件中,您可以为性能并不重要的程序提供额外的指令。在硬件中,您开始浪费硅片/lut,这可能会显着影响性能、功耗、面积、成本……
标签: verilog system-verilog hdl caesar-cipher