VHDL如何将std_logic_vector(Nbits的一个变量)转换为std_logic变量(1bit的N个变量),反之亦然?
VHDL How to convert std_logic_vector (one variable of Nbits) to std_logic variables (N variables of 1bit) and vice-versa?
我有以下 VHDL 代码到 1k x 8 位 RAM:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY RAM IS
PORT(
DATA : INOUT STD_LOGIC_VECTOR(7 DOWNTO 0); -- data to/from external pin on bi-dir 8 bit bus
ADDR : IN STD_LOGIC_VECTOR(9 DOWNTO 0); -- address from external pin on input 10 bit bus
RW : IN STD_LOGIC;
CS : IN STD_LOGIC
);
END ENTITY;
ARCHITECTURE BEV OF RAM IS
TYPE MEM IS ARRAY (1023 DOWNTO 0) OF STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL MEMORY : MEM;
SIGNAL ADDRESS : INTEGER RANGE 0 TO 1023;
BEGIN
PROCESS(ADDR, DATA, RW, CS)
BEGIN
ADDRESS <= CONV_INTEGER(ADDR);
IF(CS = '0')THEN
IF(RW = '0') THEN
MEMORY(ADDRESS) <= DATA;
ELSE
DATA <= MEMORY(ADDRESS);
END IF;
ELSE
DATA <= "ZZZZZZZZ";
END IF;
END PROCESS;
END BEV;
但我想要以下最终端口:
(我只放了初始化模块端口的部分,以表明我想修改上面的代码)
ENTITY RAM IS
PORT(
D0 : INOUT STD_LOGIC; -- data to/from external pin on bi-dir 1 bit wire LSB
D1 : INOUT STD_LOGIC; -- data to/from external pin on bi-dir 1 bit wire
D2 : INOUT STD_LOGIC; -- data to/from external pin on bi-dir 1 bit wire
D3 : INOUT STD_LOGIC; -- data to/from external pin on bi-dir 1 bit wire
D4 : INOUT STD_LOGIC; -- data to/from external pin on bi-dir 1 bit wire
D5 : INOUT STD_LOGIC; -- data to/from external pin on bi-dir 1 bit wire
D6 : INOUT STD_LOGIC; -- data to/from external pin on bi-dir 1 bit wire
D7 : INOUT STD_LOGIC; -- data to/from external pin on bi-dir 1 bit wire HSB
A0 : IN STD_LOGIC; -- address from external pin on input 1 bit wire LSB
A1 : IN STD_LOGIC; -- address from external pin on input 1 bit wire
A2 : IN STD_LOGIC; -- address from external pin on input 1 bit wire
A3 : IN STD_LOGIC; -- address from external pin on input 1 bit wire
A4 : IN STD_LOGIC; -- address from external pin on input 1 bit wire
A5 : IN STD_LOGIC; -- address from external pin on input 1 bit wire
A6 : IN STD_LOGIC; -- address from external pin on input 1 bit wire
A7 : IN STD_LOGIC; -- address from external pin on input 1 bit wire
A8 : IN STD_LOGIC; -- address from external pin on input 1 bit wire
A9 : IN STD_LOGIC; -- address from external pin on input 1 bit wire HSB
RW : IN STD_LOGIC;
CS : IN STD_LOGIC
);
END ENTITY;
我想用 STD_LOGICs(电线)替换 STD_LOGIC_VECTORs。
有人可以帮我解决这个问题吗? :)
2015 年 1 月 15 日编辑
你好,我非常感谢所有为此做出贡献的人 post。
现在我还想补充一些我在此期间学到的关于同一主题的东西,以帮助像我这样的初学者。
有2种方法可以"make"一段记忆(如果有更多的方法,我还是没学会!):
或使用 FPGA 的内部逻辑(如前所述,在此 post 中)...
或者使用FPGA的内部存储器(据我了解,这只有在具有该内部存储器的模型中才有可能)。
第一种情况FPGA消耗较大,如果想
做别的事情,也许是不可能的(这是我的情况)。
在第二种情况下,FPGA 消耗为 0 或最小值。
只会有内存的消耗,节省了FPGA的逻辑。
所以,我认为使用现成的模型对我来说会更好,
Altera Quartus 提供并修改了它,正如我在这里了解到的那样。
这也很酷,通过这种方式我还学习了如何用 VHDL 编写程序的其他形式。
第一种情况,使用的是"PROCESS ()"和"END PROCESS;"
这样我就可以使用 "IF () THEN",如上文示例所示。
但是在第二种情况下(下图),是不可能使用"IF () THEN"的。
简单搜索后,我找到了文档"VHDL Math Tricks of the Trade.pdf",
并了解到它可以使用以下句子:
X <= VALUE when (LOGIC) else ANOTHER_VALUE;
通过这种方式我设法解决了内存第二个选项(在库中)存在的另一个问题,
这是没有控制引脚将内存置于三态或禁用它的事实。
在下面的示例中,我设法安装了总线(地址和数据)并根据需要添加了引脚控制。
(我留下了原始部分的评论)
再次感谢那些参与post的人的帮助,还有很好的例子。
谢谢大家。
-- ============================================================
-- megafunction wizard: %ROM: 1-PORT%
--
-- GENERATION: STANDARD
-- VERSION: WM1.0
-- MODULE: altsyncram
-- File Name: ROM.vhd
-- Megafunction Name(s): altsyncram
-- Simulation Library Files(s): altera_mf
-- ============================================================
LIBRARY ieee;
USE ieee.std_logic_1164.all;
LIBRARY altera_mf;
USE altera_mf.all;
ENTITY ROM IS
PORT
(
A0 : IN STD_LOGIC;
A1 : IN STD_LOGIC;
A2 : IN STD_LOGIC;
A3 : IN STD_LOGIC;
A4 : IN STD_LOGIC;
A5 : IN STD_LOGIC;
A6 : IN STD_LOGIC;
A7 : IN STD_LOGIC;
A8 : IN STD_LOGIC;
A9 : IN STD_LOGIC;
A10 : IN STD_LOGIC;
D7 : OUT STD_LOGIC;
D6 : OUT STD_LOGIC;
D5 : OUT STD_LOGIC;
D4 : OUT STD_LOGIC;
D3 : OUT STD_LOGIC;
D2 : OUT STD_LOGIC;
D1 : OUT STD_LOGIC;
D0 : OUT STD_LOGIC;
CLK : IN STD_LOGIC := '1';
CS : IN STD_LOGIC := '1'
-- address : IN STD_LOGIC_VECTOR (10 DOWNTO 0);
-- clock : IN STD_LOGIC := '1';
-- q : OUT STD_LOGIC_VECTOR (7 DOWNTO 0)
);
END ROM;
ARCHITECTURE SYN OF rom IS
SIGNAL sub_wire0 : STD_LOGIC_VECTOR (7 DOWNTO 0);
COMPONENT altsyncram
GENERIC (
address_aclr_a : STRING;
clock_enable_input_a : STRING;
clock_enable_output_a : STRING;
init_file : STRING;
intended_device_family : STRING;
lpm_hint : STRING;
lpm_type : STRING;
numwords_a : NATURAL;
operation_mode : STRING;
outdata_aclr_a : STRING;
outdata_reg_a : STRING;
widthad_a : NATURAL;
width_a : NATURAL;
width_byteena_a : NATURAL
);
PORT (
address_a : IN STD_LOGIC_VECTOR (10 DOWNTO 0);
clock0 : IN STD_LOGIC ;
q_a : OUT STD_LOGIC_VECTOR (7 DOWNTO 0)
);
END COMPONENT;
BEGIN
-- q <= sub_wire0(7 DOWNTO 0);
(D7,D6,D5,D4,D3,D2,D1,D0) <= sub_wire0(7 DOWNTO 0) when (CS <= '0') else std_logic_vector'("ZZZZZZZZ");
altsyncram_component : altsyncram
GENERIC MAP (
address_aclr_a => "NONE",
clock_enable_input_a => "BYPASS",
clock_enable_output_a => "BYPASS",
init_file => "ROM.mif",
intended_device_family => "Cyclone IV E",
lpm_hint => "ENABLE_RUNTIME_MOD=NO",
lpm_type => "altsyncram",
numwords_a => 2048,
operation_mode => "ROM",
outdata_aclr_a => "NONE",
outdata_reg_a => "CLOCK0",
widthad_a => 11,
width_a => 8,
width_byteena_a => 1
)
PORT MAP (
-- address_a => address,
address_a => (A10,A9,A8,A7,A6,A5,A4,A3,A2,A1,A0),
-- clock0 => clock,
clock0 => CLK,
q_a => sub_wire0
);
END SYN;
-- ============================================================
-- CNX file retrieval info
-- ============================================================
-- Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0"
-- Retrieval info: PRIVATE: AclrAddr NUMERIC "0"
-- Retrieval info: PRIVATE: AclrByte NUMERIC "0"
-- Retrieval info: PRIVATE: AclrOutput NUMERIC "0"
-- Retrieval info: PRIVATE: BYTE_ENABLE NUMERIC "0"
-- Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8"
-- Retrieval info: PRIVATE: BlankMemory NUMERIC "0"
-- Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0"
-- Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0"
-- Retrieval info: PRIVATE: Clken NUMERIC "0"
-- Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0"
-- Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_A"
-- Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0"
-- Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E"
-- Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0"
-- Retrieval info: PRIVATE: JTAG_ID STRING "NONE"
-- Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0"
-- Retrieval info: PRIVATE: MIFfilename STRING "ROM.mif"
-- Retrieval info: PRIVATE: NUMWORDS_A NUMERIC "2048"
-- Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0"
-- Retrieval info: PRIVATE: RegAddr NUMERIC "1"
-- Retrieval info: PRIVATE: RegOutput NUMERIC "1"
-- Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
-- Retrieval info: PRIVATE: SingleClock NUMERIC "1"
-- Retrieval info: PRIVATE: UseDQRAM NUMERIC "0"
-- Retrieval info: PRIVATE: WidthAddr NUMERIC "11"
-- Retrieval info: PRIVATE: WidthData NUMERIC "8"
-- Retrieval info: PRIVATE: rden NUMERIC "0"
-- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
-- Retrieval info: CONSTANT: ADDRESS_ACLR_A STRING "NONE"
-- Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS"
-- Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_A STRING "BYPASS"
-- Retrieval info: CONSTANT: INIT_FILE STRING "ROM.mif"
-- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E"
-- Retrieval info: CONSTANT: LPM_HINT STRING "ENABLE_RUNTIME_MOD=NO"
-- Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram"
-- Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "2048"
-- Retrieval info: CONSTANT: OPERATION_MODE STRING "ROM"
-- Retrieval info: CONSTANT: OUTDATA_ACLR_A STRING "NONE"
-- Retrieval info: CONSTANT: OUTDATA_REG_A STRING "CLOCK0"
-- Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "11"
-- Retrieval info: CONSTANT: WIDTH_A NUMERIC "8"
-- Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1"
-- Retrieval info: USED_PORT: address 0 0 11 0 INPUT NODEFVAL "address[10..0]"
-- Retrieval info: USED_PORT: clock 0 0 0 0 INPUT VCC "clock"
-- Retrieval info: USED_PORT: q 0 0 8 0 OUTPUT NODEFVAL "q[7..0]"
-- Retrieval info: CONNECT: @address_a 0 0 11 0 address 0 0 11 0
-- Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0
-- Retrieval info: CONNECT: q 0 0 8 0 @q_a 0 0 8 0
-- Retrieval info: GEN_FILE: TYPE_NORMAL ROM.vhd TRUE
-- Retrieval info: GEN_FILE: TYPE_NORMAL ROM.inc FALSE
-- Retrieval info: GEN_FILE: TYPE_NORMAL ROM.cmp TRUE
-- Retrieval info: GEN_FILE: TYPE_NORMAL ROM.bsf TRUE
-- Retrieval info: GEN_FILE: TYPE_NORMAL ROM_inst.vhd FALSE
-- Retrieval info: LIB_FILE: altera_mf
我能想到两个选项供您探索。
第一个是使用串联运算符和中间内部信号。
示例 1:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY RAM IS
PORT(
D0 : INOUT STD_LOGIC; -- data to/from external pin on bi-dir 1 bit wire LSB
D1 : INOUT STD_LOGIC; -- data to/from external pin on bi-dir 1 bit wire
D2 : INOUT STD_LOGIC; -- data to/from external pin on bi-dir 1 bit wire
D3 : INOUT STD_LOGIC; -- data to/from external pin on bi-dir 1 bit wire
D4 : INOUT STD_LOGIC; -- data to/from external pin on bi-dir 1 bit wire
D5 : INOUT STD_LOGIC; -- data to/from external pin on bi-dir 1 bit wire
D6 : INOUT STD_LOGIC; -- data to/from external pin on bi-dir 1 bit wire
D7 : INOUT STD_LOGIC; -- data to/from external pin on bi-dir 1 bit wire HSB
);
END ENTITY;
ARCHITECTURE BEV OF RAM IS
SIGNAL data_in_i :STD_LOGIC_VECTOR(7 downto 0);
SIGNAL data_out_i :STD_LOGIC_VECTOR(7 downto 0);
BEGIN
data_in_i <= D7 & D6 & D5 & D4 & D3 & D2 & D1 & D0;
...
D7 <= data_out_i(7);
D6 <= data_out_i(6);
D5 <= data_out_i(5);
D4 <= data_out_i(4);
D3 <= data_out_i(3);
D2 <= data_out_i(2);
D1 <= data_out_i(1);
D0 <= data_out_i(0);
...
END BEV;
就我个人而言,我认为这有点难看而且不够灵活。我不确定您将端口总线拆分成单独的位的意图是什么,但我觉得更好的解决方案可能是保持 RAM 实体不变,并在实例化时直接分配 STD_LOGIC_VECTOR 输入的每一位在你的设计中。
示例 2:
ram_i: ENTITY work.RAM
PORT MAP(
D(0) => data0,
D(1) => data1,
D(2) => data2,
D(3) => data3,
D(4) => data4,
D(5) => data5,
D(6) => data6,
D(7) => data7
);
您可以使用聚合:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity ram is
port(
d0: inout std_logic;
d1: inout std_logic;
d2: inout std_logic;
d3: inout std_logic;
d4: inout std_logic;
d5: inout std_logic;
d6: inout std_logic;
d7: inout std_logic;
a0: in std_logic;
a1: in std_logic;
a2: in std_logic;
a3: in std_logic;
a4: in std_logic;
a5: in std_logic;
a6: in std_logic;
a8: in std_logic;
a7: in std_logic;
a9: in std_logic;
rw: in std_logic;
cs: in std_logic
);
end entity;
architecture foo of ram is
type mem is array (1023 downto 0) of std_logic_vector(7 downto 0);
signal memory : mem;
signal address : integer range 0 to 1023;
begin
process(a9,a8,a7,a6,a5,a4,a3,a2,a1,a0,d7,d6,d5,d4,d3,d2,d1,d0,rw,cs)
begin
address <= to_integer(unsigned'(a9,a8,a7,a6,a5,a4,a3,a2,a1,a0));
if cs = '0' then
if rw = '0' then
memory(address) <= (d7 & d6 & d5 & d4 & d3 & d2 & d1 & d0);
else
(d7,d6,d5,d4,d3,d2,d1,d0) <= std_logic_vector'(memory(address));
end if;
else
(d7,d6,d5,d4,d3,d2,d1,d0) <= std_logic_vector'("ZZZZZZZZ");
end if;
end process;
end architecture;
library ieee;
use ieee.std_logic_1164.all;
entity ramtest_tb is
end entity;
architecture foo of ramtest_tb is
signal a0,a1,a2,a3,a4,a5,a6,a7,a8,a9: std_logic := '0';
signal d0,d1,d2,d3,d4,d5,d6,d7: std_logic := 'Z';
signal rw: std_logic := '1';
signal cs: std_logic := '1';
begin
DUT:
entity work.ram
port map (
d0 => d0,
d1 => d1,
d2 => d2,
d3 => d3,
d4 => d4,
d5 => d5,
d6 => d6,
d7 => d7,
a0 => a0,
a1 => a1,
a2 => a2,
a3 => a3,
a4 => a4,
a5 => a5,
a6 => a6,
a7 => a7,
a8 => a8,
a9 => a9,
rw => rw,
cs => cs
);
TEST:
process
begin
wait for 10 ns;
rw <= '0';
a5 <= '1'; a3 <= '1'; a1 <= '1'; --42
wait for 10 ns;
cs <= '0';
(d7,d6,d5,d4,d3,d2,d1,d0) <= std_logic_vector'("10101010");
wait for 10 ns;
cs <= '1';
(d7,d6,d5,d4,d3,d2,d1,d0) <= std_logic_vector'("ZZZZZZZZ");
wait for 10 ns;
rw <= '1';
wait for 10 ns;
cs <= '0';
wait for 10 ns;
cs <= '1';
wait for 10 ns;
wait;
end process;
end architecture;
这给你:
可点击
工作 RAM。
我有以下 VHDL 代码到 1k x 8 位 RAM:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY RAM IS
PORT(
DATA : INOUT STD_LOGIC_VECTOR(7 DOWNTO 0); -- data to/from external pin on bi-dir 8 bit bus
ADDR : IN STD_LOGIC_VECTOR(9 DOWNTO 0); -- address from external pin on input 10 bit bus
RW : IN STD_LOGIC;
CS : IN STD_LOGIC
);
END ENTITY;
ARCHITECTURE BEV OF RAM IS
TYPE MEM IS ARRAY (1023 DOWNTO 0) OF STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL MEMORY : MEM;
SIGNAL ADDRESS : INTEGER RANGE 0 TO 1023;
BEGIN
PROCESS(ADDR, DATA, RW, CS)
BEGIN
ADDRESS <= CONV_INTEGER(ADDR);
IF(CS = '0')THEN
IF(RW = '0') THEN
MEMORY(ADDRESS) <= DATA;
ELSE
DATA <= MEMORY(ADDRESS);
END IF;
ELSE
DATA <= "ZZZZZZZZ";
END IF;
END PROCESS;
END BEV;
但我想要以下最终端口:
(我只放了初始化模块端口的部分,以表明我想修改上面的代码)
ENTITY RAM IS
PORT(
D0 : INOUT STD_LOGIC; -- data to/from external pin on bi-dir 1 bit wire LSB
D1 : INOUT STD_LOGIC; -- data to/from external pin on bi-dir 1 bit wire
D2 : INOUT STD_LOGIC; -- data to/from external pin on bi-dir 1 bit wire
D3 : INOUT STD_LOGIC; -- data to/from external pin on bi-dir 1 bit wire
D4 : INOUT STD_LOGIC; -- data to/from external pin on bi-dir 1 bit wire
D5 : INOUT STD_LOGIC; -- data to/from external pin on bi-dir 1 bit wire
D6 : INOUT STD_LOGIC; -- data to/from external pin on bi-dir 1 bit wire
D7 : INOUT STD_LOGIC; -- data to/from external pin on bi-dir 1 bit wire HSB
A0 : IN STD_LOGIC; -- address from external pin on input 1 bit wire LSB
A1 : IN STD_LOGIC; -- address from external pin on input 1 bit wire
A2 : IN STD_LOGIC; -- address from external pin on input 1 bit wire
A3 : IN STD_LOGIC; -- address from external pin on input 1 bit wire
A4 : IN STD_LOGIC; -- address from external pin on input 1 bit wire
A5 : IN STD_LOGIC; -- address from external pin on input 1 bit wire
A6 : IN STD_LOGIC; -- address from external pin on input 1 bit wire
A7 : IN STD_LOGIC; -- address from external pin on input 1 bit wire
A8 : IN STD_LOGIC; -- address from external pin on input 1 bit wire
A9 : IN STD_LOGIC; -- address from external pin on input 1 bit wire HSB
RW : IN STD_LOGIC;
CS : IN STD_LOGIC
);
END ENTITY;
我想用 STD_LOGICs(电线)替换 STD_LOGIC_VECTORs。
有人可以帮我解决这个问题吗? :)
2015 年 1 月 15 日编辑
你好,我非常感谢所有为此做出贡献的人 post。 现在我还想补充一些我在此期间学到的关于同一主题的东西,以帮助像我这样的初学者。
有2种方法可以"make"一段记忆(如果有更多的方法,我还是没学会!): 或使用 FPGA 的内部逻辑(如前所述,在此 post 中)... 或者使用FPGA的内部存储器(据我了解,这只有在具有该内部存储器的模型中才有可能)。
第一种情况FPGA消耗较大,如果想 做别的事情,也许是不可能的(这是我的情况)。
在第二种情况下,FPGA 消耗为 0 或最小值。 只会有内存的消耗,节省了FPGA的逻辑。
所以,我认为使用现成的模型对我来说会更好, Altera Quartus 提供并修改了它,正如我在这里了解到的那样。 这也很酷,通过这种方式我还学习了如何用 VHDL 编写程序的其他形式。
第一种情况,使用的是"PROCESS ()"和"END PROCESS;" 这样我就可以使用 "IF () THEN",如上文示例所示。
但是在第二种情况下(下图),是不可能使用"IF () THEN"的。 简单搜索后,我找到了文档"VHDL Math Tricks of the Trade.pdf", 并了解到它可以使用以下句子:
X <= VALUE when (LOGIC) else ANOTHER_VALUE;
通过这种方式我设法解决了内存第二个选项(在库中)存在的另一个问题, 这是没有控制引脚将内存置于三态或禁用它的事实。
在下面的示例中,我设法安装了总线(地址和数据)并根据需要添加了引脚控制。 (我留下了原始部分的评论)
再次感谢那些参与post的人的帮助,还有很好的例子。
谢谢大家。
-- ============================================================
-- megafunction wizard: %ROM: 1-PORT%
--
-- GENERATION: STANDARD
-- VERSION: WM1.0
-- MODULE: altsyncram
-- File Name: ROM.vhd
-- Megafunction Name(s): altsyncram
-- Simulation Library Files(s): altera_mf
-- ============================================================
LIBRARY ieee;
USE ieee.std_logic_1164.all;
LIBRARY altera_mf;
USE altera_mf.all;
ENTITY ROM IS
PORT
(
A0 : IN STD_LOGIC;
A1 : IN STD_LOGIC;
A2 : IN STD_LOGIC;
A3 : IN STD_LOGIC;
A4 : IN STD_LOGIC;
A5 : IN STD_LOGIC;
A6 : IN STD_LOGIC;
A7 : IN STD_LOGIC;
A8 : IN STD_LOGIC;
A9 : IN STD_LOGIC;
A10 : IN STD_LOGIC;
D7 : OUT STD_LOGIC;
D6 : OUT STD_LOGIC;
D5 : OUT STD_LOGIC;
D4 : OUT STD_LOGIC;
D3 : OUT STD_LOGIC;
D2 : OUT STD_LOGIC;
D1 : OUT STD_LOGIC;
D0 : OUT STD_LOGIC;
CLK : IN STD_LOGIC := '1';
CS : IN STD_LOGIC := '1'
-- address : IN STD_LOGIC_VECTOR (10 DOWNTO 0);
-- clock : IN STD_LOGIC := '1';
-- q : OUT STD_LOGIC_VECTOR (7 DOWNTO 0)
);
END ROM;
ARCHITECTURE SYN OF rom IS
SIGNAL sub_wire0 : STD_LOGIC_VECTOR (7 DOWNTO 0);
COMPONENT altsyncram
GENERIC (
address_aclr_a : STRING;
clock_enable_input_a : STRING;
clock_enable_output_a : STRING;
init_file : STRING;
intended_device_family : STRING;
lpm_hint : STRING;
lpm_type : STRING;
numwords_a : NATURAL;
operation_mode : STRING;
outdata_aclr_a : STRING;
outdata_reg_a : STRING;
widthad_a : NATURAL;
width_a : NATURAL;
width_byteena_a : NATURAL
);
PORT (
address_a : IN STD_LOGIC_VECTOR (10 DOWNTO 0);
clock0 : IN STD_LOGIC ;
q_a : OUT STD_LOGIC_VECTOR (7 DOWNTO 0)
);
END COMPONENT;
BEGIN
-- q <= sub_wire0(7 DOWNTO 0);
(D7,D6,D5,D4,D3,D2,D1,D0) <= sub_wire0(7 DOWNTO 0) when (CS <= '0') else std_logic_vector'("ZZZZZZZZ");
altsyncram_component : altsyncram
GENERIC MAP (
address_aclr_a => "NONE",
clock_enable_input_a => "BYPASS",
clock_enable_output_a => "BYPASS",
init_file => "ROM.mif",
intended_device_family => "Cyclone IV E",
lpm_hint => "ENABLE_RUNTIME_MOD=NO",
lpm_type => "altsyncram",
numwords_a => 2048,
operation_mode => "ROM",
outdata_aclr_a => "NONE",
outdata_reg_a => "CLOCK0",
widthad_a => 11,
width_a => 8,
width_byteena_a => 1
)
PORT MAP (
-- address_a => address,
address_a => (A10,A9,A8,A7,A6,A5,A4,A3,A2,A1,A0),
-- clock0 => clock,
clock0 => CLK,
q_a => sub_wire0
);
END SYN;
-- ============================================================
-- CNX file retrieval info
-- ============================================================
-- Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0"
-- Retrieval info: PRIVATE: AclrAddr NUMERIC "0"
-- Retrieval info: PRIVATE: AclrByte NUMERIC "0"
-- Retrieval info: PRIVATE: AclrOutput NUMERIC "0"
-- Retrieval info: PRIVATE: BYTE_ENABLE NUMERIC "0"
-- Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8"
-- Retrieval info: PRIVATE: BlankMemory NUMERIC "0"
-- Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0"
-- Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0"
-- Retrieval info: PRIVATE: Clken NUMERIC "0"
-- Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0"
-- Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_A"
-- Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0"
-- Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E"
-- Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0"
-- Retrieval info: PRIVATE: JTAG_ID STRING "NONE"
-- Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0"
-- Retrieval info: PRIVATE: MIFfilename STRING "ROM.mif"
-- Retrieval info: PRIVATE: NUMWORDS_A NUMERIC "2048"
-- Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0"
-- Retrieval info: PRIVATE: RegAddr NUMERIC "1"
-- Retrieval info: PRIVATE: RegOutput NUMERIC "1"
-- Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
-- Retrieval info: PRIVATE: SingleClock NUMERIC "1"
-- Retrieval info: PRIVATE: UseDQRAM NUMERIC "0"
-- Retrieval info: PRIVATE: WidthAddr NUMERIC "11"
-- Retrieval info: PRIVATE: WidthData NUMERIC "8"
-- Retrieval info: PRIVATE: rden NUMERIC "0"
-- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
-- Retrieval info: CONSTANT: ADDRESS_ACLR_A STRING "NONE"
-- Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS"
-- Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_A STRING "BYPASS"
-- Retrieval info: CONSTANT: INIT_FILE STRING "ROM.mif"
-- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E"
-- Retrieval info: CONSTANT: LPM_HINT STRING "ENABLE_RUNTIME_MOD=NO"
-- Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram"
-- Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "2048"
-- Retrieval info: CONSTANT: OPERATION_MODE STRING "ROM"
-- Retrieval info: CONSTANT: OUTDATA_ACLR_A STRING "NONE"
-- Retrieval info: CONSTANT: OUTDATA_REG_A STRING "CLOCK0"
-- Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "11"
-- Retrieval info: CONSTANT: WIDTH_A NUMERIC "8"
-- Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1"
-- Retrieval info: USED_PORT: address 0 0 11 0 INPUT NODEFVAL "address[10..0]"
-- Retrieval info: USED_PORT: clock 0 0 0 0 INPUT VCC "clock"
-- Retrieval info: USED_PORT: q 0 0 8 0 OUTPUT NODEFVAL "q[7..0]"
-- Retrieval info: CONNECT: @address_a 0 0 11 0 address 0 0 11 0
-- Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0
-- Retrieval info: CONNECT: q 0 0 8 0 @q_a 0 0 8 0
-- Retrieval info: GEN_FILE: TYPE_NORMAL ROM.vhd TRUE
-- Retrieval info: GEN_FILE: TYPE_NORMAL ROM.inc FALSE
-- Retrieval info: GEN_FILE: TYPE_NORMAL ROM.cmp TRUE
-- Retrieval info: GEN_FILE: TYPE_NORMAL ROM.bsf TRUE
-- Retrieval info: GEN_FILE: TYPE_NORMAL ROM_inst.vhd FALSE
-- Retrieval info: LIB_FILE: altera_mf
我能想到两个选项供您探索。
第一个是使用串联运算符和中间内部信号。
示例 1:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY RAM IS
PORT(
D0 : INOUT STD_LOGIC; -- data to/from external pin on bi-dir 1 bit wire LSB
D1 : INOUT STD_LOGIC; -- data to/from external pin on bi-dir 1 bit wire
D2 : INOUT STD_LOGIC; -- data to/from external pin on bi-dir 1 bit wire
D3 : INOUT STD_LOGIC; -- data to/from external pin on bi-dir 1 bit wire
D4 : INOUT STD_LOGIC; -- data to/from external pin on bi-dir 1 bit wire
D5 : INOUT STD_LOGIC; -- data to/from external pin on bi-dir 1 bit wire
D6 : INOUT STD_LOGIC; -- data to/from external pin on bi-dir 1 bit wire
D7 : INOUT STD_LOGIC; -- data to/from external pin on bi-dir 1 bit wire HSB
);
END ENTITY;
ARCHITECTURE BEV OF RAM IS
SIGNAL data_in_i :STD_LOGIC_VECTOR(7 downto 0);
SIGNAL data_out_i :STD_LOGIC_VECTOR(7 downto 0);
BEGIN
data_in_i <= D7 & D6 & D5 & D4 & D3 & D2 & D1 & D0;
...
D7 <= data_out_i(7);
D6 <= data_out_i(6);
D5 <= data_out_i(5);
D4 <= data_out_i(4);
D3 <= data_out_i(3);
D2 <= data_out_i(2);
D1 <= data_out_i(1);
D0 <= data_out_i(0);
...
END BEV;
就我个人而言,我认为这有点难看而且不够灵活。我不确定您将端口总线拆分成单独的位的意图是什么,但我觉得更好的解决方案可能是保持 RAM 实体不变,并在实例化时直接分配 STD_LOGIC_VECTOR 输入的每一位在你的设计中。
示例 2:
ram_i: ENTITY work.RAM
PORT MAP(
D(0) => data0,
D(1) => data1,
D(2) => data2,
D(3) => data3,
D(4) => data4,
D(5) => data5,
D(6) => data6,
D(7) => data7
);
您可以使用聚合:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity ram is
port(
d0: inout std_logic;
d1: inout std_logic;
d2: inout std_logic;
d3: inout std_logic;
d4: inout std_logic;
d5: inout std_logic;
d6: inout std_logic;
d7: inout std_logic;
a0: in std_logic;
a1: in std_logic;
a2: in std_logic;
a3: in std_logic;
a4: in std_logic;
a5: in std_logic;
a6: in std_logic;
a8: in std_logic;
a7: in std_logic;
a9: in std_logic;
rw: in std_logic;
cs: in std_logic
);
end entity;
architecture foo of ram is
type mem is array (1023 downto 0) of std_logic_vector(7 downto 0);
signal memory : mem;
signal address : integer range 0 to 1023;
begin
process(a9,a8,a7,a6,a5,a4,a3,a2,a1,a0,d7,d6,d5,d4,d3,d2,d1,d0,rw,cs)
begin
address <= to_integer(unsigned'(a9,a8,a7,a6,a5,a4,a3,a2,a1,a0));
if cs = '0' then
if rw = '0' then
memory(address) <= (d7 & d6 & d5 & d4 & d3 & d2 & d1 & d0);
else
(d7,d6,d5,d4,d3,d2,d1,d0) <= std_logic_vector'(memory(address));
end if;
else
(d7,d6,d5,d4,d3,d2,d1,d0) <= std_logic_vector'("ZZZZZZZZ");
end if;
end process;
end architecture;
library ieee;
use ieee.std_logic_1164.all;
entity ramtest_tb is
end entity;
architecture foo of ramtest_tb is
signal a0,a1,a2,a3,a4,a5,a6,a7,a8,a9: std_logic := '0';
signal d0,d1,d2,d3,d4,d5,d6,d7: std_logic := 'Z';
signal rw: std_logic := '1';
signal cs: std_logic := '1';
begin
DUT:
entity work.ram
port map (
d0 => d0,
d1 => d1,
d2 => d2,
d3 => d3,
d4 => d4,
d5 => d5,
d6 => d6,
d7 => d7,
a0 => a0,
a1 => a1,
a2 => a2,
a3 => a3,
a4 => a4,
a5 => a5,
a6 => a6,
a7 => a7,
a8 => a8,
a9 => a9,
rw => rw,
cs => cs
);
TEST:
process
begin
wait for 10 ns;
rw <= '0';
a5 <= '1'; a3 <= '1'; a1 <= '1'; --42
wait for 10 ns;
cs <= '0';
(d7,d6,d5,d4,d3,d2,d1,d0) <= std_logic_vector'("10101010");
wait for 10 ns;
cs <= '1';
(d7,d6,d5,d4,d3,d2,d1,d0) <= std_logic_vector'("ZZZZZZZZ");
wait for 10 ns;
rw <= '1';
wait for 10 ns;
cs <= '0';
wait for 10 ns;
cs <= '1';
wait for 10 ns;
wait;
end process;
end architecture;
这给你:
工作 RAM。