2015-01-29 7 views
1

В настоящее время я пытаюсь сделать объявление с общим массивом в моей архитектуре, но он не работает, и он продолжает давать синтаксическую ошибку, может кто-нибудь объяснить мне, почему это так?Как вы объявляете общий std_logic_vector в VHDL?

architecture behav of mpy8 is 
shared variable P : std_logic_vector (17 downto 0); // doesn't work 

Я хочу использовать переменную P в своем процессе перехода и утверждать процесс выходов.

+0

Это работает, если вы сделаете это общим сигналом? – chris

+0

Я не пробовал использовать общий сигнал, но есть ли разница? – BeginnerC

+0

из моего основного понимания, сигналы используются на верхнем уровне архитектуры, переменные для процесса – chris

ответ

0

переменные могут использоваться только в рамках одного процесса в vhdl. Вы не разрешаете использовать переменную внутри блока архитектуры вне процесса. Чтобы делиться значениями между разными процессами или объектами, требуется несколько сигналов. Весь процесс может читать один сигнал. Но только один процесс разрешается записывать в один и тот же сигнал.

Возможно, приведенный ниже пример может помочь вам. Это память данных для процессора я писал в своем последнем семестре:

library ieee; 
    use ieee.std_logic_1164.all; 
    use ieee.numeric_std.all; 
    use work.Instructions_pack.all; 


    entity DataMemory is 

     generic(
      size : natural := 8 --number of instructions 
     ); 
     port(
      clk_i   : in std_logic; 
      rst_i   : in std_logic; 
      alu_result_i : in std_logic_vector(31 DOWNTO 0); 
      writeData_i  : in std_logic_vector(31 DOWNTO 0); 
      memWrite_i  : in std_logic; 
      memRead_i  : in std_logic; 
      loadMode_i : in load_mode; 
      storeMode_i : in store_mode; 

      readData_o : out std_logic_vector(31 DOWNTO 0) 
     ); 
    end entity DataMemory; 

    architecture behaviour of DataMemory is 
     constant size2 : integer := size * 4; 
     type dataMemType is array (0 to size2 - 1) of std_logic_vector(7 downto 0); 
     signal dataMem : dataMemType := (
       "11111011","00000000","00000000","00000000", 
       "11101111","01000010","00000000","00000000", 
       "00000000","00000000","00000000","00000000", 
       "00000000","00000000","00000000","00000000", 
       "00000000","00000000","00000000","00000000", 
       "00000000","00000000","00000000","00000000", 
       "00000000","00000000","00000000","00000000", 
       "00000000","00000000","00000000","00000000" 
     ); 
     signal readout : std_logic_vector(31 downto 0); 
     signal loadWordRaw : std_logic_vector(31 downto 0); 
     signal loadHalfRaw : std_logic_vector(31 downto 0); 
     signal loadByteRaw : std_logic_vector(31 downto 0); 
     signal loadHalfSigned : std_logic_vector(31 downto 0); 
     signal loadByteSigned : std_logic_vector(31 downto 0); 

     begin 

     --determines how much bytes are loaded 
     loadWordRaw <= dataMem(TO_INTEGER(UNSIGNED(alu_result_i))) & 
        dataMem(TO_INTEGER(UNSIGNED(alu_result_i)) + 1) & 
        dataMem(TO_INTEGER(UNSIGNED(alu_result_i)) + 2) & 
        dataMem(TO_INTEGER(UNSIGNED(alu_result_i)) + 3)  when memRead_i = '1' and loadMode_i = ld_lw ELSE 
        (others => '-'); 
     loadHalfRaw <= ("00000000" & "00000000" & 
        dataMem(TO_INTEGER(UNSIGNED(alu_result_i))) & 
        dataMem(TO_INTEGER(UNSIGNED(alu_result_i)) + 1)) when (memRead_i = '1') and ((loadMode_i = ld_lh) or (loadMode_i = ld_lhu)) ELSE 
        (others => '-'); 
     loadByteRaw <= "00000000" & "00000000" & "00000000" & 
        dataMem(TO_INTEGER(UNSIGNED(alu_result_i)))   when memRead_i = '1' and ((loadMode_i = ld_lb) or (loadMode_i = ld_lbu)) ELSE 
        (others => '-'); 

     --signed: resize to 32 bit 
     loadHalfSigned <= std_logic_vector(resize(signed(loadHalfRaw(15 downto 0)), 32)) when loadMode_i = ld_lh ELSE 
        (others => '-'); 
     loadByteSigned <= std_logic_vector(resize(signed(loadByteRaw(7 downto 0)), 32)) when loadMode_i = ld_lb ELSE 
        (others => '-'); 

     --which mode is chosen 
     readout <= loadWordRaw   when loadMode_i = ld_lw ELSE 
        loadHalfRaw   when loadMode_i = ld_lhu ELSE 
        loadHalfSigned when loadMode_i = ld_lh ELSE 
        loadByteRaw   when loadMode_i = ld_lbu ELSE 
        loadByteSigned; 

     dataMem_process : process(clk_i, rst_i) is 
     begin 
      if rst_i = '1' then 
       readData_o <= (others => '0'); 
      elsif rising_edge(clk_i) then 
       readData_o <= readout; 
       if memWrite_i = '1' then 
        if storeMode_i = st_sw then --store normal 
         dataMem(TO_INTEGER(UNSIGNED(alu_result_i))) <= writeData_i(31 DOWNTO 24); 
         dataMem(TO_INTEGER(UNSIGNED(alu_result_i)) + 1) <= writeData_i(23 DOWNTO 16); 
         dataMem(TO_INTEGER(UNSIGNED(alu_result_i)) + 2) <= writeData_i(15 DOWNTO 8); 
         dataMem(TO_INTEGER(UNSIGNED(alu_result_i)) + 3) <= writeData_i(7 DOWNTO 0); 
        elsif storeMode_i = st_sh then  --store half 
         dataMem(TO_INTEGER(UNSIGNED(alu_result_i))) <= writeData_i(15 DOWNTO 8); 
         dataMem(TO_INTEGER(UNSIGNED(alu_result_i)) + 1) <= writeData_i(7 DOWNTO 0); 
        else --store byte 
         dataMem(TO_INTEGER(UNSIGNED(alu_result_i))) <= writeData_i(7 DOWNTO 0); 
         end if; 
       end if; 
      end if; 
     end process dataMem_process;     

    end architecture; 

Пакет «Instructions_pack»:

library ieee; 
    use ieee.std_logic_1164.all; 

    package Instructions_pack is 
     constant c_op_bits  : integer      := 6; 
     constant c_instr_bits : integer      := 5; 
     constant c_immed_bits : integer      := 16; 
     constant c_address_bits : integer      := 26; 
     ---------------------------------------------------- 
     --- MIPS registers --------------------------------- 
     ---------------------------------------------------- 
     constant R0    : std_logic_vector(4 downto 0) := (others => '0'); 
     constant Rat   : std_logic_vector(4 downto 0) := '0' & x"1"; 
     constant Rv0   : std_logic_vector(4 downto 0) := '0' & x"2"; 
     constant Rv1   : std_logic_vector(4 downto 0) := '0' & x"3"; 
     constant Ra0   : std_logic_vector(4 downto 0) := '0' & x"4"; 
     constant Ra1   : std_logic_vector(4 downto 0) := '0' & x"5"; 
     constant Ra2   : std_logic_vector(4 downto 0) := '0' & x"6"; 
     constant Ra3   : std_logic_vector(4 downto 0) := '0' & x"7"; 
     constant Rt0   : std_logic_vector(4 downto 0) := '0' & x"8"; 
     constant Rt1   : std_logic_vector(4 downto 0) := '0' & x"9"; 
     constant Rt2   : std_logic_vector(4 downto 0) := '0' & x"A"; 
     constant Rt3   : std_logic_vector(4 downto 0) := '0' & x"B"; 
     constant Rt4   : std_logic_vector(4 downto 0) := '0' & x"C"; 
     constant Rt5   : std_logic_vector(4 downto 0) := '0' & x"D"; 
     constant Rt6   : std_logic_vector(4 downto 0) := '0' & x"E"; 
     constant Rt7   : std_logic_vector(4 downto 0) := '0' & x"F"; --15 
     constant Rt8   : std_logic_vector(4 downto 0) := '1' & x"8"; --24 
     constant Rt9   : std_logic_vector(4 downto 0) := '1' & x"9"; --25 
     constant Rs0   : std_logic_vector(4 downto 0) := '1' & x"0"; --16 
     constant Rs1   : std_logic_vector(4 downto 0) := '1' & x"1"; --17 
     constant Rs2   : std_logic_vector(4 downto 0) := '1' & x"2"; --18 
     constant Rs3   : std_logic_vector(4 downto 0) := '1' & x"3"; --19 
     constant Rs4   : std_logic_vector(4 downto 0) := '1' & x"4"; --20 
     constant Rs5   : std_logic_vector(4 downto 0) := '1' & x"5"; --21 
     constant Rs6   : std_logic_vector(4 downto 0) := '1' & x"6"; --22 
     constant Rs7   : std_logic_vector(4 downto 0) := '1' & x"7"; --23 
     constant Rk0   : std_logic_vector(4 downto 0) := '1' & x"A"; --26 
     constant Rk1   : std_logic_vector(4 downto 0) := '1' & x"B"; --27 
     constant Rgp   : std_logic_vector(4 downto 0) := '1' & x"C"; --28 
     constant Rsp   : std_logic_vector(4 downto 0) := '1' & x"D"; --29 
     constant Rfp   : std_logic_vector(4 downto 0) := '1' & x"E"; --30 
     constant Rra   : std_logic_vector(4 downto 0) := '1' & x"F"; --31 

     ---------------------------------------------------- 
     ------- r type constants --------------------------- 
     ---------------------------------------------------- 
     type R_Type_Constant is record 
      opcode : std_logic_vector(c_op_bits - 1 downto 0); 
      funct : std_logic_vector(c_op_bits - 1 downto 0); 
     end record; 
     --reg <= c_add.opcode & rs & rt & rd & shamt & c_add.funct; 
     constant c_add : R_Type_Constant := (
      opcode => (others => '0'), funct => "10" & x"0" 
     ); 
     constant c_addu : R_Type_Constant := (
      opcode => (others => '0'), funct => "10" & x"1" 
     ); 
     constant c_and : R_Type_Constant := (
      opcode => "000000", 
      funct => "10" & x"4" 
     ); 
     -- count leading ones 
     constant c_clo : R_Type_Constant := (
      opcode => "01" & x"C", 
      funct => "10" & x"1" 
     ); 
     -- count leading zeros 
     constant c_clz : R_Type_Constant := (
      opcode => "01" & x"C", 
      funct => "10" & x"0" 
     ); 
     constant c_div : R_Type_Constant := (
      opcode => (others => '0'), funct => "01" & x"A" 
     ); 
     constant c_divu : R_Type_Constant := (
      opcode => (others => '0'), funct => "01" & x"B" 
     ); 
     --multiply 
     constant c_mult : R_Type_Constant := (
      opcode => (others => '0'), funct => "01" & x"8" 
     ); 
     --unsigned multiply 
     constant c_multu : R_Type_Constant := (
      opcode => (others => '0'), funct => "01" & x"9" 
     ); 
     --multiply without overflow 
     constant c_mul : R_Type_Constant := (
      opcode => "01" & x"C", 
      funct => "00" & x"2" 
     ); 
     --multiply and add 
     constant c_madd : R_Type_Constant := (
      opcode => "01" & x"C", 
      funct => (others => '0') 
     ); 
     --unsigned multiply add 
     constant c_maddu : R_Type_Constant := (
      opcode => "01" & x"C", 
      funct => "00" & x"1" 
     ); 
     --multiply subtract 
     constant c_msub : R_Type_Constant := (
      opcode => "01" & x"C", 
      funct => "00" & x"4" 
     ); 
     --unsigned multiply subtract 
     constant c_msubu : R_Type_Constant := (
      opcode => "01" & x"C", 
      funct => "00" & x"5" 
     ); 

     constant c_nor : R_Type_Constant := (
      opcode => (others => '0'), funct => "10" & x"7" 
     ); 

     constant c_or : R_Type_Constant := (
      opcode => (others => '0'), funct => "10" & x"5" 
     ); 
     --logical shift left 
     constant c_sll : R_Type_Constant := (
      opcode => (others => '0'), funct => (others => '0') 
     ); 
     --shift left logical variable 
     constant c_sllv : R_Type_Constant := (
      opcode => (others => '0'), funct => "00" & x"4" 
     ); 
     --shift right arithmetic 
     constant c_sra : R_Type_Constant := (
      opcode => (others => '0'), funct => "00" & x"3" 
     ); 
     --shift right arithmetic variable 
     constant c_srav : R_Type_Constant := (
      opcode => (others => '0'), funct => "00" & x"7" 
     ); 
     --shift right logical 
     constant c_srl : R_Type_Constant := (
      opcode => (others => '0'), funct => "00" & x"2" 
     ); 
     --shift right logical variable 
     constant c_srlv : R_Type_Constant := (
      opcode => (others => '0'), funct => "00" & x"6" 
     ); 
     --subtract with overflow 
     constant c_sub : R_Type_Constant := (
      opcode => (others => '0'), funct => "10" & x"2" 
     ); 
     --subtract without overflow 
     constant c_subu : R_Type_Constant := (
      opcode => (others => '0'), funct => "10" & x"3" 
     ); 

     constant c_xor : R_Type_Constant := (
      opcode => (others => '0'), funct => "10" & x"6" 
     ); 
     --comparison instructions 
     --set less than 
     constant c_slt : R_Type_Constant := (
      opcode => (others => '0'), funct => "10" & x"A" 
     ); 
     --set less than unsigned 
     constant c_sltu : R_Type_Constant := (
      opcode => (others => '0'), funct => "10" & x"B" 
     ); 

     ------------------------------------------------------ 
     ----Branch constants 
     ------------------------------------------------------ 
     type Branch_Type_Const is record 
      opcode : std_logic_vector(c_op_bits - 1 downto 0); 
      rt  : std_logic_vector(4 downto 0); 
     end record; 

     type Branch_Type_2regs_Const is record 
      opcode : std_logic_vector(c_op_bits - 1 downto 0); 
     end record; 

     --branch on equal, use 2 registers 
     constant c_beq : Branch_Type_2regs_Const := (opcode => "00" & x"4"); 

     --branch on not equal, use 2 registers 
     constant c_bne : Branch_Type_2regs_Const := (opcode => "00" & x"5"); 

     -- branch on greater than equal zero 
     constant c_bgez : Branch_Type_Const := (
      opcode => "00" & x"1", 
      rt  => "0" & x"1" 
     ); 

     --branch on greater than equal zero and link 
     --(save the address of next instruct. in reg. 31) 
     constant c_bgezal : Branch_Type_Const := (
      opcode => "00" & x"1", 
      rt  => "1" & x"1" 
     ); 

     --branch on greater than zero 
     constant c_bgtz : Branch_Type_Const := (
      opcode => "00" & x"7", 
      rt  => (others => '0') 
     ); 

     --branch on less than equal zero 
     constant c_blez : Branch_Type_Const := (
      opcode => "00" & x"6", 
      rt  => (others => '0') 
     ); 

     --branch on less than zero and link 
     --(save address in reg. 31) 
     constant c_bltzal : Branch_Type_Const := (
      opcode => "00" & x"1", 
      rt  => "1" & x"0" 
     ); 

     --branch on less than zero 
     constant c_bltz : Branch_Type_Const := (
      opcode => "00" & x"1", 
      rt  => (others => '0') 
     ); 

     ------------------------------------------------------ 
     -----i type instructions, load store 
     ------------------------------------------------------ 
     subtype OP_Type_Const is std_logic_vector(c_op_bits - 1 downto 0); 

     constant c_addi : OP_Type_Const := "00" & x"8"; 
     constant c_addiu : OP_Type_Const := "00" & x"9"; 
     constant c_andi : OP_Type_Const := "00" & x"C"; 
     constant c_ori : OP_Type_Const := "00" & x"D"; --immediate or 
     constant c_xori : OP_Type_Const := "00" & x"E"; 
     --constant manipulation: load upper immediate 
     constant c_lui : OP_Type_Const := "00" & x"F"; 
     --set less than 
     constant c_slti : OP_Type_Const := "00" & x"A"; 
     constant c_sltiu : OP_Type_Const := "00" & x"B"; 
     --load instructions 
     --load byte 
     constant c_lb : OP_Type_Const := "10" & x"0"; 
     --load unsigned byte 
     constant c_lbu : OP_Type_Const := "10" & x"4"; 
     --load halfword 
     constant c_lh : OP_Type_Const := "10" & x"1"; 
     --load halfword unsigned 
     constant c_lhu : OP_Type_Const := "10" & x"5"; 
     --load word 
     constant c_lw : OP_Type_Const := "10" & x"3"; 
     --lw left 
     constant c_lwl : OP_Type_Const := "10" & x"2"; 
     --lw right 
     constant c_lwr : OP_Type_Const := "10" & x"6"; 
     --load linked 
     constant c_ll : OP_Type_Const := "11" & x"0"; 
     --store word (sw) 
     constant c_sw : OP_Type_Const := "10" & x"B"; 
     --store byte 
     constant c_sb : OP_Type_Const := "10" & x"8"; 
     --store halfword 
     constant c_sh : OP_Type_Const := "10" & x"9"; 
     --store word left 
     constant c_swl : OP_Type_Const := "10" & x"A"; 
     --store word right 
     constant c_swr : OP_Type_Const := "10" & x"E"; 
     --store conditional: olways succeeds on SPIM (stores 1 to rt) 
     constant c_sc : OP_Type_Const := "11" & x"8"; 

     ------------------------------------------------------ 
     --Jump Instructions 
     ------------------------------------------------------ 
     type J_Type_Const is record 
      opcode : std_logic_vector(c_op_bits - 1 downto 0); 
      rt  : std_logic_vector(c_instr_bits - 1 downto 0); 
      funct : std_logic_vector(c_op_bits - 1 downto 0); 
     end record; 

     --jump unconditionally to instruction at target 
     -- PC(31 downto 28) & target(26 downto 0) & "00" 
     constant c_j : OP_Type_Const := "00" & x"2"; 

     --Jump and link: unconditionally jump to instruction 
     --at target address, save the address of next 
     --instruction in register $ra (register 31) 
     --PC(31 downto 28) & target(26 downto 0) & "00" 
     constant c_jal : OP_Type_Const := "00" & x"3"; 

     --jump and link register: 
     --unconditionally jump to instruction whose address 
     --is in register rs. Save address of next instruct. 
     --in register rd (default reg $ra) 
     constant c_jalr : J_Type_Const := (
      opcode => "00" & x"0", 
      rt  => "00000", 
      funct => "00" & x"9" 
     ); 

     --jump register: 
     --unconditionally jump to instruction whose address is in register rs 
     constant c_jr : J_Type_Const := (
      opcode => "000000", 
      rt  => "00000", 
      funct => "00" & x"8" 
     ); 

     ------------------------------------------------------ 

     --type for r type instructions 
     type R_Type is record 
      opcode : std_logic_vector(c_op_bits - 1 downto 0); 
      rs  : std_logic_vector(c_instr_bits - 1 downto 0); 
      rt  : std_logic_vector(c_instr_bits - 1 downto 0); 
      rd  : std_logic_vector(c_instr_bits - 1 downto 0); 
      shamt : std_logic_vector(c_instr_bits - 1 downto 0); 
      funct : std_logic_vector(c_op_bits - 1 downto 0); 
     end record; 

     -- i type instructions 
     type I_Type is record 
      opcode : std_logic_vector(c_op_bits - 1 downto 0); 
      rs  : std_logic_vector(c_instr_bits - 1 downto 0); 
      rt  : std_logic_vector(c_instr_bits - 1 downto 0); 
      immediate : std_logic_vector(c_immed_bits - 1 downto 0); --can used as offset value 
     end record; 

     --j type instructions 
     type J_Type is record 
      opcode : std_logic_vector(c_op_bits - 1 downto 0); 
      address : std_logic_vector(c_address_bits - 1 downto 0); 
     end record; 


     --alu code definition 
     type alu_code is ( c_alu_add, c_alu_addu, c_alu_sub, c_alu_subu, 
          c_alu_and, c_alu_or, c_alu_nor, c_alu_xor, 
          c_alu_sllv, c_alu_srlv, c_alu_sll, c_alu_srl, 
          c_alu_sra, c_alu_srav, c_alu_zero, 
          c_alu_error --needed? 
          ); 
     --when to branch 
     type branch_condition is (bc_beq, bc_bgtz, bc_blez, bc_bne); 

     --how much data to load 
     type load_mode is (ld_lb, ld_lbu, ld_lh, ld_lhu, ld_lw); 

     --how much data to store 
     type store_mode is (st_sb, st_sh, st_sw); 

    end package Instructions_pack; 

    package body Instructions_pack is 
    end package body Instructions_pack; 

надеюсь, это поможет вам

0

я использую следующую общую переменную код для имитации многопортовой памяти в одном из моих проектов. В этом случае объем памяти симулятора намного меньше, а симуляция работает быстрее, чем при использовании простых сигналов.

Насколько мне известно, это не синтезируется и может не поддерживаться всеми тренажерами.

architecture behavioral of testbench is 
    type shared_ram is protected 
     procedure write(addr: in integer; value: in std_logic_vector(63 downto 0)); 
     impure function read(addr: integer) return std_logic_vector; 
    end protected shared_ram; 

    type shared_ram is protected body 
     -- bit_vector has a smaller simulation memory requirement than std_logic_vector 
     type ram_t is array(0 to 2**25-1) of bit_vector(63 downto 0); 
     variable ram: ram_t; 

     procedure write(addr: in integer; value: in std_logic_vector(63 downto 0)) is 
     begin 
      ram(addr) := to_bitvector(value); 
     end procedure write; 

     impure function read(addr: integer) return std_logic_vector is 
     begin 
      return to_stdlogicvector(ram(addr)); 
     end function read; 
    end protected body shared_ram; 

    shared variable ram: shared_ram; 
begin 
    -- Processes can use ram.write(address, value) and ram.read(address) 
end architecture behavioral; 
Смежные вопросы