我想使用生成语句但在我的代码中我有一个只接受顺序语句的case语句。
然后我想我会在一个包中使用它,我可以定义一个函数,这样我也会收到错误:'非法顺序语句'。
那么可以做些什么。有什么建议?
代码块:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE work.my_package.all;
-- Entity for ALU component
-- Use this Entity for your C&A project
ENTITY ALU_E IS
PORT(
reset_n : in std_logic;
clk : in std_logic;
OperandA : in std_logic_vector(3 downto 0);
OperandB : in std_logic_vector(3 downto 0);
Operation : in std_logic_vector(2 downto 0);
Start : in std_logic;
Result_Low : out std_logic_vector(3 downto 0);
Result_High : out std_logic_vector(3 downto 0);
Ready : out std_logic;
Errorsig : out std_Logic);
END ALU_E;
architecture Behavioral_ALU of ALU_E is
signal c : std_logic_vector(7 downto 0);
signal carry_internal :std_logic_vector(4 downto 0);
COMPONENT fulladder IS
PORT(
a: IN std_logic;
b: IN std_logic;
cin : IN std_logic;
cout: OUT std_logic;
s: OUT std_logic );
END component fulladder;
begin
adders: for N in 0 to 3 generate
ff1:fulladder
port map
(a => OperandA(N),b => OperandB(N),cin => carry_internal(N),cout => carry_internal(N+1),s => c(N));
end generate adders;
c(4) <= carry_internal(4);
process(clk,reset_n)
begin
if reset_n = '0' then
if (clk'event) then
case Operation is
when "000" => --no operation
NULL;
when "001" => --Rotate left logical operator ?0000?&A by B steps
c <= rotlef (OperandA,OperandB);
when "010" => --Rotate right logical operator ?0000?&A by B steps (result width is 8 bit)
c <= rotrig (OperandA,OperandB);
when "011" => --Bitwise XOR operation
Result_Low <= OperandA xor OperandB;
when "100" => --Sum of A and B
--here i want to use a statement such that i can call the gatelevel --add function
--I have already all functions gatelevel defined when i try to use portmap or ----generate it gives an error illegal sequential statement
when Others =>
NULL;
end case;
end if;
end if;
end process;
end Behavioral_ALU;
答案 0 :(得分:0)
这个问题存在一些误解。
首先是标题:实际代码中没有任何功能。您使用for ... generate
语句所做的是生成一个单独的硬件,与主进程并行运行。它将始终运行,并始终用总和驱动信号'c',就好像您已经用c <= a + b;
代替for ... generate
。它始终是,持续工作,而不是只有你想要时才能打电话的功能。
其次,这意味着加法器和时钟进程一直驱动c
,具有不同的值。这样做不会很好......实际上你应该在模拟中看到信号c
上的“XXXX”。
我认为你想要做的是为加法器的输出创建一个名为sum
的新信号,并在sum
中为c
而不是for ... generate
加载。然后,在Case语句中,将sum
分配给c
将完成Add操作。
答案 1 :(得分:0)
就您收到错误消息的原因而言,组件实例化语句或生成语句是并发语句,而案例选择或函数体由顺序语句组成。
你不需要一个函数,你需要求和并从generate语句中实现四个fulladder
s。
Ø
为fulladder假装实体/架构对:
library ieee;
use ieee.std_logic_1164.all;
entity fulladder is
port (
a: in std_logic;
b: in std_logic;
cin: in std_logic;
cout: out std_logic;
s: out std_logic
);
end entity;
architecture foo of fulladder is
begin
s <= a xor b xor cin;
cout <= (a and b) or (a and cin) or (b and cin);
end architecture;
假装无功能my_package
:
library ieee;
use ieee.std_logic_1164.all;
package my_package is
function rotlef (a, b: std_logic_vector) return std_logic_vector;
function rotrig (a, b: std_logic_vector) return std_logic_vector;
end package;
package body my_package is
function rotlef (a, b: std_logic_vector) return std_logic_vector is
variable ret_val: std_logic_vector (a'range);
begin
return ret_val;
end function;
function rotrig (a, b: std_logic_vector) return std_logic_vector is
variable ret_val: std_logic_vector (a'range);
begin
return ret_val;
end function;
end package body;
(注意函数返回值长度与左操作数长度匹配)
为生成的fulladder
的输出添加新声明:
architecture changed of alu_e is
signal c: std_logic_vector(7 downto 0);
signal carry_internal: std_logic_vector(4 downto 0);
signal s: std_logic_vector(3 downto 0); -- added
更改generate语句以使用新信号作为总和:
adders:
for n in 0 to 3 generate
ff1:
fulladder
port map (
a => operanda(n),
b => operandb(n),
cin => carry_internal(n),
cout => carry_internal(n+1),
s => s(n) -- was c(n)
);
end generate;
-- c(4) <= carry_internal(4);
(取消对c(4)的分配)
并更改选项“100”的语句顺序:
when "100" => --sum of a and b
result_low <= s; -- added
result_high(0) <= carry_internal(4); --(un)signed?
您的设计分析,详细说明和模拟(虽然没有做太多 - 当others
未被驱动且所有operation
时,案例U
的过程中没有任何分配,我没有编写一个测试平台来驱动operation
或为其提供默认值。
请注意c
的声明长度为8,而两个函数的返回值与a
输入(长度4)相匹配。
如果您要执行operation
s "001"
或"010"
的虚拟函数,则由于右侧长度不匹配而导致模拟错误。我原样离开了这个问题,但没有确定您的rotlef
或rotrig
函数是否实际返回的长度更长。
通常,您只需要8位乘法结果。 c
的长度及其分配给result_low
和result_high
的方式并不明显(至今)。
在没有更多细节的情况下,无法辨别您是在进行有符号算术还是无符号算术。而不是:
result_high(0) <= carry_internal(4); --(un)signed?
签名的加号可能如下所示:
result_high <= (others => carry_internal(4)); --sign extended
请注意,在实例化乘数时,您还需要为8位结果使用新的信号声明。修改轮播操作以分配result_low
和result_high
将允许c
用于实例化的乘法,但您可以选择重命名。
将流程语句中的case语句想象为实例化多路复用器,在某些情况下,您恰好也在输入上表达逻辑。 xor
或符号扩展或函数调用(表达式)是示例。
当您实例化提供功能的组件时,您希望将其输出连接到多路复用器输入。