我有一个可变数量的模块通过一个signal bus : std_logic_vector(NUM-1 downto 0)链接到另一个模块,每个组件使用8位,因此:
bus(7 downto 0) = first module
bus(15 downto 8) = second module对于创建实例和执行端口映射,使用
INST: for i in 0 to NUM-1 generate
Inst_module port map ( bus => bus(i*8+7 downto i*8) );
end generate INST;我的问题:我希望能够通过FSM与每个模块进行接口(因为它也需要做一些其他事情),所以希望能够“生成”下面的代码,而不是手动写出每个状态(其中signal empty : std_logic_vector(NUM-1 downto 0)是每个模块的状态标志)。
type state_type is (st0_idle, st1_work0, st1_work1 --,etc.)
signal state : state_type;
begin
process(empty)
begin
if RESET = '1' then
--reset FSM
state <= st0_idle;
else
if CLK'event and CLK='1' then
case state is
when st0_idle =>
if empty(0) = '0' then
state <= st1_work0;
elsif empty(1) = '1' then
state <= st1_work1;
--etc.
end if;
when st1_work0 =>
bus(7 downto 0) <= SOMETHING;
state <= st0_idle;
when st1_work1 =>
bus(15 downto 8) <= SOMETHINGELSE;
state <= st0_idle;
--etc..
end if;
end if;
end process;正如你所看到的,有很多重复。但是我不能简单地将一个for-generate放在这个案例中,那么我应该做什么呢?
发布于 2011-11-08 22:04:19
使使用状态机的进程更具可读性的一个好方法是将公共代码合并到进程中定义的过程中。例如:
process (empty) is
procedure assign_something (
index : natural;
something : std_logic_vector(7 downto 0)
next_state : state_type
) is
begin
bus(index*8+7 downto index*8) <= something;
state <= next_state;
end procedure;
begin
wait until rising_edge(clk);
case state is
when st0_idle => ...
when st1_work0 => assign_something(0, something, st0_idle);
when st1_work1 => assign_something(1, something_else, st0_idle);
-- ... etc ...
end case;
if reset = '1' then
state <= st0_idle;
end if;
end procedure;希望你能明白。根据状态机结构的规则性,您还可能希望将与每个索引对应的枚举状态变量替换为与命名状态一起跟踪的简单计数或索引变量。
这完全取决于您,但无论您如何做,只要您能够使用VHDL,就可以使用过程来筛选出通用代码。
应用此更改将使代码看起来如下所示:
architecture ...
type state_type is (st_idle, st_work);
signal state : state_type;
signal index : integer range 0 to NUM-1;
...
begin
...
process (empty) is
procedure assign_something (
index : natural;
something : std_logic_vector(7 downto 0)
next_state : state_type
) is
begin
bus(index*8+7 downto index*8) <= something;
state <= next_state;
end procedure;
begin
wait until rising_edge(clk);
case state is
when st_idle =>
for i in 0 to NUM-1 loop
if empty(i) = '1' then
index := i;
exit;
end if;
end loop;
when st_work => assign_something(index, something, st_idle);
end case;
if reset = '1' then
state <= st_idle;
end if;
end procedure;显然,必须更改它以与您想要做的操作完全匹配. =)
https://stackoverflow.com/questions/8057197
复制相似问题