-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcell.vhd
121 lines (97 loc) · 2.43 KB
/
cell.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
package types is
type Source is (Idle, NextGeneration, OneSet, FromSeed);
end;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.types.all;
entity cell is
generic( size : natural );
port (
clk, reset : in std_logic;
cellSource : in Source;
save : in std_logic;
rule : in std_logic_vector(7 downto 0);
current: out std_ulogic
);
end;
architecture a of cell is
constant cellMax : natural := size-1;
signal c, cs, css : std_logic;
signal cell, seed: std_logic_vector(cellMax downto 0);
signal cnt, setCnt, setCntT: integer range 0 to cellMax;
signal working, setWorking, setWorkingT : std_logic;
signal cellMode : Source := Idle;
signal saveMode : std_logic;
signal store : std_logic_vector(1 downto 0);
signal threeCells : std_logic_vector(2 downto 0);
signal writeEnable : boolean;
signal writeContent : std_logic;
function active_high(b : boolean) return std_logic is begin
if b then return '1';
else return '0'; end if;
end function;
begin
process (clk, reset) is begin
if reset = '1' then
cnt <= 0;
elsif rising_edge(clk) then
store <= store(0) & c;
if cnt = cellMax then
cnt <= 0;
elsif working = '1' then
cnt <= cnt + 1;
end if;
end if;
end process;
working <= '1' when cellMode /= Idle else '0';
process (clk) is begin
if rising_edge(clk) then
setCntT <= cnt;
setWorkingT <= working;
setWorking <= setWorkingT;
setCnt <= setCntT;
c <= cell(cnt);
cs <= seed(cnt);
css <= cs;
end if;
end process;
threeCells <= '0' & store(0) & c when setCnt = 0 else
store & '0' when setCnt = cellMax else
store & c;
--Writer
writeEnable <= (cellMode /= Idle) and (setWorking = '1');
with cellMode select
writeContent <= rule(to_integer(unsigned(threeCells))) when NextGeneration,
active_high(cnt = size/2) when OneSet,
css when FromSeed,
'0' when others;
process (clk) is begin
if rising_edge(clk) then
if writeEnable then
cell(setCnt) <= writeContent;
end if;
if saveMode = '1' then
seed(setCntT) <= c;
end if;
end if;
end process;
process (clk, reset) is
begin
if reset = '1' then
cellMode <= Idle;
saveMode <= '0';
elsif rising_edge(clk) then
if cellMode = Idle then
cellMode <= cellSource;
elsif setCnt = cellMax then
cellMode <= cellSource;
saveMode <= '0';
end if;
if save = '1' then
saveMode <= '1';
end if;
end if;
end process;
current <= c;
end;