-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsyncram.vhd
204 lines (191 loc) · 5.61 KB
/
syncram.vhd
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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use std.textio.all;
use ieee.std_logic_textio.all;
use ieee.numeric_std.all;
-- With reference to http://www.dte.us.es/ing_inf/dise_comp/VHDLsimCMSG.pdf
-- Sparse SRAM
entity syncram is
generic (
mem_file : string
);
port (
clk : in std_logic;
cs : in std_logic;
oe : in std_logic;
we : in std_logic;
addr : in std_logic_vector(31 downto 0);
din : in std_logic_vector(31 downto 0);
dout : out std_logic_vector(31 downto 0)
);
end syncram;
architecture behavioral of syncram is
begin
process (clk)
type Cell;
type CellPtr is access Cell;
type Cell is
record
nextCell : CellPtr;
addr : std_logic_vector(31 downto 0);
word : stD_logic_vector(31 downto 0);
end record;
procedure getWord (
head : inout CellPtr;
addr : in std_logic_vector(31 downto 0);
word : out std_logic_vector(31 downto 0)
) is
variable ptr : CellPtr;
begin
ptr := head;
while ptr /= null loop
if ptr.addr = addr then
word := ptr.word;
return;
end if;
ptr := ptr.nextCell;
end loop;
word := (others => 'U');
end getWord;
procedure setWord (
head : inout CellPtr;
addr : in std_logic_vector(31 downto 0);
word : in std_logic_vector(31 downto 0)
) is
variable ptr : CellPtr;
begin
ptr := head;
while ptr /= head loop
if ptr.addr = addr then
ptr.word := word;
return;
end if;
end loop;
ptr := new Cell'(nextCell => head, addr => addr, word => word);
head := ptr;
end setWord;
-- Borrows from std_logic_textio from synopsys.
procedure Char2QuadBits(C: Character;
RESULT: out Bit_Vector(3 downto 0);
GOOD: out Boolean;
ISSUE_ERROR: in Boolean) is
begin
case c is
when '0' => result := x"0"; good := TRUE;
when '1' => result := x"1"; good := TRUE;
when '2' => result := x"2"; good := TRUE;
when '3' => result := x"3"; good := TRUE;
when '4' => result := x"4"; good := TRUE;
when '5' => result := x"5"; good := TRUE;
when '6' => result := x"6"; good := TRUE;
when '7' => result := x"7"; good := TRUE;
when '8' => result := x"8"; good := TRUE;
when '9' => result := x"9"; good := TRUE;
when 'A' => result := x"A"; good := TRUE;
when 'B' => result := x"B"; good := TRUE;
when 'C' => result := x"C"; good := TRUE;
when 'D' => result := x"D"; good := TRUE;
when 'E' => result := x"E"; good := TRUE;
when 'F' => result := x"F"; good := TRUE;
when 'a' => result := x"A"; good := TRUE;
when 'b' => result := x"B"; good := TRUE;
when 'c' => result := x"C"; good := TRUE;
when 'd' => result := x"D"; good := TRUE;
when 'e' => result := x"E"; good := TRUE;
when 'f' => result := x"F"; good := TRUE;
when others =>
if ISSUE_ERROR then
assert FALSE report
"HREAD Error: Read a '" & c &
"', expected a Hex character (0-F).";
end if;
good := FALSE;
end case;
end;
-- Debug support procedure.
function to_string(sv : std_logic_vector) return string is
variable bv : bit_vector(sv'range) := to_bitvector(sv);
variable lp : line;
begin
write(lp, bv);
return lp.all;
end;
procedure HREADPlus (
l : inout line;
value : out std_logic_vector;
good : out boolean
) is
variable c : character;
variable ok : boolean;
constant ne : integer := value'length / 4;
variable buf : std_logic_vector(value'length-1 downto 0);
variable bitbuf : bit_vector(3 downto 0);
begin
good := false;
if value'length mod 4 /= 0 then
return;
end if;
buf := (others => '0');
main : loop
read(l, c);
exit when not
( (c >= '0' and c <= '9')
or (c >= 'A' and c <= 'F')
or (c >= 'a' and c <= 'f'));
Char2QuadBits(c, bitbuf(3 downto 0), ok, false);
if ok then
good := true;
end if;
exit main when not ok;
buf := buf(27 downto 0) & To_X01(bitbuf);
end loop;
value := buf;
return;
end procedure;
procedure initRAM (
mem_file : in string;
head : inout CellPtr
) is
file infile : TEXT open read_mode is mem_file;
-- file infile : text is in mem_file;
variable inline : Line;
variable inaddr : std_logic_vector(31 downto 0);
variable indata : std_logic_vector(31 downto 0);
variable slash : character; -- string(7 downto 1);
variable semicolon : string(17 downto 1);
variable good : boolean;
begin
scanloop : while not endfile(infile) loop
readline(infile, inline);
next scanloop when inline'length = 0;
HREADPlus(inline, inaddr, good);
next scanloop when not good;
read_data : loop
HREADPlus(inline, indata, good);
exit read_data when good;
end loop read_data;
setWord(head, inaddr, indata);
end loop scanloop;
end initRAM;
variable head : CellPtr;
variable needInit : boolean := true;
variable dbuf : std_logic_vector(31 downto 0);
begin
if needInit then
initRAM(mem_file, head);
needInit := false;
end if;
if rising_edge(clk) then
if cs = '1' then
if oe = '1' then
getWord(head, addr, dbuf);
dout <= dbuf;
end if;
if we = '1' then
setWord(head, addr, din);
end if;
end if;
end if;
end process;
end behavioral;