VHDL如何将std_logic_vector(Nbits的一个变量)转换为std_logic变量(N个变量为1bit),反之亦然?

时间:2015-01-11 22:54:17

标签: vhdl

我有以下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;

但我想要以下最终端口:

(我只是把初始化模块的PORT的部分,以显示我想修改上面的代码)

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_VECTOR。

有人可以帮我吗? :)

于2015年1月15日编辑

嗨,我非常感谢为这篇文章做出贡献的所有人。 而且现在我还想在这个时期添加一些关于同一主题的东西,以帮助像我这样的初学者。

有两种方法可以“制造”一个记忆(如果有更多的方法,我还没学会!): 或者使用FPGA的内部逻辑(如前所述,在这篇文章中)...... 或者使用FPGA的内部存储器(根据我的理解,这仅在具有此内部存储器的模型中可能)。

在第一种情况下,FPGA消耗很大,如果你愿意的话 做别的事,也许是不可能的(这是我的情况)。

在第二种情况下,FPGA消耗为0或最小值。 只会消耗内部存储器,从而节省了FPGA的逻辑。

所以,我认为使用现成模型对我来说会更好, Altera Quartus提供并修改它,就像我在这里学到的那样。 这也很酷,我通过这种方式学习了如何用VHDL编写程序的其他形式。

在第一种情况下,使用“PROCESS()”“END PROCESS;” 这样我可以使用“IF()THEN”,如此处(上文)中提供的示例所示。

但在第二种情况(下图)中,无法使用“IF()那么”。 经过简短的搜索,我找到了文档“VHDL Math Tricks of the Trade.pdf”, 并了解到它可以使用以下句子:

X&lt; = VALUE时(LOGIC)其他ANOTHER_VALUE;

这样我就设法解决了第二个内存选项中存在的另一个问题(在库中), 这是没有控制引脚将存储器置于三态或禁用它的事实。

在下面的示例中,我设法安装总线(地址和数据)并添加引脚控件,如我所需。 (我原来的部分留下了评论)

再一次,我要感谢参与这个帖子的人的帮助,并提供了很好的例子。

谢谢你们。

-- ============================================================
--  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

2 个答案:

答案 0 :(得分:2)

我可以想到你可以探索的两个选项。

第一种方法是使用连接运算符和中间内部信号。

示例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
);

答案 1 :(得分:2)

您可以使用聚合:

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;

这给了你:

ramtest_tb.png 可点击

工作RAM。