我目前正在尝试在我的架构中创建一个共享数组声明,但它不起作用并且它一直给我一个语法错误,有人可以向我解释为什么会这样吗?
architecture behav of mpy8 is
shared variable P : std_logic_vector (17 downto 0); // doesn't work
我想在转换过程中使用变量P并断言输出过程。
答案 0 :(得分: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;
希望对你有所帮助
答案 1 :(得分: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;