我正在使用active-hdl来模拟我的FPGA设计,我想知道是否可以在模拟器中使用动态生成的字符串来表示我的信号。例如,假设我有一个包含操作码的4位std_logic_vector,我希望模拟器显示操作码字符串"nop“、"add”、"sub“等,而不是向量值。
我最初尝试声明一个自定义枚举类型,但很快发现您无法选择各个元素的值。我的下一个解决方案是将枚举仅用于模拟显示,并使用转换函数进行转换:
type op_code_type is (nop, add, sub, unknown); -- not in order
signal op_code_str: op_code_type;
signal op_code: std_logic_vector(3 downto 0);
function to_string(op_code : std_logic_vector(3 downto 0))
return op_code_type is
begin
case op_code is
when "0000" => return nop;
when "0010" => return add;
when "0011" => return sub;
when others => return unknown;
end case;
end to_string;
begin
----- testbench -----
process
begin
op_code <= "0000";
wait for 1ns;
op_code <= "0001";
wait for 1ns;
op_code <= "0010";
wait for 1ns;
op_code <= "0011";
wait for 1ns;
end process;
op_code_str <= to_string(op_code);
end architecture;这实际上工作得很好,可能对我想做的大多数事情都足够了:

然而,主要的问题是我被字符串常量所困,所以对于更复杂的东西,如mov acc,x和现实世界设计中的所有其他变体,它太不切实际了。
有没有像这样构造动态模拟标识符的方法?或者这是HDL的一个基本限制?
发布于 2019-06-18 23:50:55
在Modelsim中,您可以使用虚拟类型和函数。例如,考虑以下向量:
signal opcode : std_logic_vector(2 downto 0);然后,您可以在Modelsim命令行中定义虚拟类型,例如:
virtual type {{0 nop} {1 load} {2 store} {3 invalid}} opcode_type这是一种只有模拟器知道的类型。然后,您可以基于此类型创建虚拟信号来转换矢量,例如:
virtual function {(opcode_type)opcode} opcode_str然后wave opcode_str,它将为您提供一个自定义格式的字符串。
我不知道你是否能用Active-HDL做同样的事情。
现在,至于动态执行,唯一的可能性可能是返回的字符串是由TCL函数定义的,例如:
# TCL code to read a file, or otherwise dynamically generate opcodes
# returning the appropriately formatted virtual type
proc generate_opcode_type {} {
...
}
virtual type [generate_opcode_type] opcode_type
virtual function {(opcode_type)opcode} opcode_str然后挥动opcode_str。
发布于 2019-06-19 12:36:10
对于后人,应@B.Go的要求,这是我之前的答案:
@Paebbels拥有它。我们经常使用这种方法,特别是在进行布局布线后模拟以将状态代码转换为其等效的枚举类型时。为了完整起见,我将向您展示我们是如何做的。下面的示例考虑了使用二进制编码的情况。如果试图从灰色或单热转换,事情就有点不同了。对于one-hot,我倾向于使用函数。
考虑一个具有相关名称的3位向量:
|-----------|----------|
| 000 | Idle |
| 001 | Start |
| 010 | Running |
| 011 | Paused |
| 100 | Done |
| 101 - 111 | Invalid |
|-----------|----------|所以,如果你有一个信号,比如:
signal opcode : std_logic_vector(2 downto 0);然后,您希望转换为枚举类型,该类型将在波形查看器中清晰地显示出来。首先,创建枚举类型和相关信号:
type opcode_names is (idle, start, running, paused, done, invalid);
signal opcode_name : opcode_names;那么它就是一个简单的with/select
with to_integer(unsigned(opcode)) select
opcode_name <= idle when 0,
start when 1,
running when 2,
paused when 3,
done when 4,
invalid when others;不过,如果你有一个完整的集合,它就会简单一点。考虑一个名为"idle,start,running,done“的2位向量。
type opcode_names is (idle, start, running, done);
signal opcode_name : opcode_names;
...
opcode_name <= opcode_names'image(to_integer(unsigned(opcode));对于具有不寻常的非邻接值的更复杂的向量,我通常使用一个函数,例如:
signal opcode : std_logic_vector(31 downto 0);
type opcode_names is (idle, start, running1, running2, paused, done, invalid);
signal opcode_name : opcode_names;
function get_opcode_name(opcode : in std_logic_vector) return opcode_names is
variable ret : opcode_names;
begin
case to_integer(unsigned(opcode)) is
when 0 =>
ret := idle;
when 13 =>
ret := start;
when 87 =>
ret := running1;
when 131 =>
ret := running2;
when 761 =>
ret := paused;
when 3213 =>
ret := done;
when others =>
ret := invalid;
end case;
return ret;
end function get_opcode_name;
...
opcode_name <= get_opcode_name(opcode);https://stackoverflow.com/questions/49081146
复制相似问题