1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
|
library ieee;
use ieee.std_logic_1164.all;
library grlib;
use grlib.amba.all;
use grlib.stdlib.all;
use grlib.devices.all;
library hzdr;
use hzdr.devices_hzdr.all;
entity dualport_ram_ahb_wrapper is
generic (
hindex : integer := 0;
haddr : integer := 0;
hmask : integer := 16#fff#
);
port (
clk : in std_ulogic;
reset : in std_ulogic;
-- ahb
ahbsi : in ahb_slv_in_type;
ahbso : out ahb_slv_out_type
);
end entity dualport_ram_ahb_wrapper;
library ieee;
use ieee.std_logic_1164;
library zpu;
use zpu.zpu_config.all;
use zpu.zpupkg.all; -- wordsize
use zpu.zpupkg.dualport_ram;
architecture rtl of dualport_ram_ahb_wrapper is
constant hconfig : ahb_config_type := (
0 => ahb_device_reg ( VENDOR_HZDR, HZDR_ZPU_MEM_WRAPPER, 0, maxAddrBitBRAM+2, 0),
4 => ahb_membar(haddr, '1', '1', hmask),
others => zero32);
type reg_t is record
hwrite : std_ulogic;
hready : std_ulogic;
hsel : std_ulogic;
we : std_ulogic;
addr : std_logic_vector(maxAddrBitBRAM downto minAddrBit);
haddr : std_logic_vector(maxAddrBitBRAM downto minAddrBit);
data : std_logic_vector(wordSize-1 downto 0);
end record;
constant default_reg_c : reg_t := (
hwrite => '0',
hready => '0',
hsel => '0',
we => '0',
addr => (others => '0'),
haddr => (others => '0'),
data => (others => '0')
);
type src_t is record
data : std_logic_vector(wordSize-1 downto 0);
end record;
signal r, r_in : reg_t;
signal s : src_t;
signal we : std_logic;
signal addr : std_logic_vector(maxAddrBitBRAM downto minAddrBit);
begin
dualport_ram_i0: dualport_ram
port map (
clk => clk, -- : in std_logic;
memAWriteEnable => we, -- : in std_logic;
memAAddr => addr, -- : in std_logic_vector(maxAddrBitBRAM downto minAddrBit);
memAWrite => ahbsi.hwdata, -- : in std_logic_vector(wordSize-1 downto 0);
memARead => s.data, -- : out std_logic_vector(wordSize-1 downto 0);
memBWriteEnable => '0', -- : in std_logic;
memBAddr => (others => '0'), -- : in std_logic_vector(maxAddrBitBRAM downto minAddrBit);
memBWrite => (others => '0'), -- : in std_logic_vector(wordSize-1 downto 0);
memBRead => open -- : out std_logic_vector(wordSize-1 downto 0)
);
comb: process(ahbsi, r, s)
variable v: reg_t;
begin
v := r;
ahbso.hready <= v.hready;
v.hready := '1';
v.we := '0';
if (r.hwrite or not r.hready) = '1' then
v.haddr := v.addr;
else
v.haddr := ahbsi.haddr(maxAddrBitBRAM downto minAddrBit);
end if;
if ahbsi.hready = '1' then -- react only when bus is ready
v.hsel := ahbsi.hsel( hindex) and ahbsi.htrans(1);
v.hwrite := ahbsi.hwrite and v.hsel;
v.addr := ahbsi.haddr(maxAddrBitBRAM downto minAddrBit);
end if;
if r.hwrite = '1' then
v.we := '1';
v.hready := not (v.hsel and not ahbsi.hwrite);
v.hwrite := v.hwrite and v.hready;
end if;
v.data := ahbsi.hwdata;
ahbso.hrdata <= s.data;
if is_x( v.haddr) then
addr <= (others => '0');
else
addr <= v.haddr;
end if;
we <= v.we;
r_in <= v;
end process;
seq: process
begin
wait until rising_edge( clk);
r <= r_in;
if reset = '1' then
r <= default_reg_c;
end if;
end process;
ahbso.hresp <= "00";
ahbso.hsplit <= (others => '0');
ahbso.hirq <= (others => '0');
ahbso.hcache <= '1';
ahbso.hconfig <= hconfig;
ahbso.hindex <= hindex;
-- pragma translate_off
bootmsg : report_version
generic map ("zpumem" & tost(hindex) &
": ZPU Memory AHB Wrapper, " & tost((2**(maxAddrBitBRAM + 1))/1024 ) & " kbytes addressable (" & tost( bram_words) & " words)");
-- pragma translate_on
end architecture rtl;
|