-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathprimes_finder.vhd
More file actions
163 lines (133 loc) · 5.69 KB
/
Copy pathprimes_finder.vhd
File metadata and controls
163 lines (133 loc) · 5.69 KB
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
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity primes_finder is
generic (
P : integer := 256; -- καλύτερη υλοποίηση με δυνάμεις του 2
N_BITS : integer := 11
);
port (
clk : in std_logic;
rst : in std_logic;
counter_out : out unsigned(N_BITS-1 downto 0);
prime_out : out unsigned(N_BITS-1 downto 0);
done_out : out std_logic
);
end entity primes_finder;
architecture rtl of primes_finder is
constant CHECK_PERIOD : integer := 11; -- κάθε πόσους κύκλους μηχανής θα ελέγχουμε για αποτέλεσμα
constant NUM_CLUSTERS : integer := (P + 7) / 8; -- κάθε cluster έχει 8 oscillators
constant NUM_GROUPS : integer := (NUM_CLUSTERS + 7) / 8; -- κάθε Group έχει 8 Clusters
-- Εσωτερικά Σήματα
signal counter : unsigned(N_BITS-1 downto 0) := (others => '0');
signal timer : integer range 0 to CHECK_PERIOD := 0; -- Ο μετρητής κύκλων μηχανής
signal primes_count : integer range 0 to P := 0;
signal prime_found : unsigned(N_BITS-1 downto 0);
signal any_lap : std_logic;
signal state_initialized : std_logic := '0';
signal done : std_logic := '0'; -- Εσωτερικό σήμα για το done
-- Σήματα Ελέγχου των Clusters
signal run_en : std_logic;
signal load_en_all : std_logic := '0';
signal load_en_vector : std_logic_vector(NUM_CLUSTERS-1 downto 0) := (others => '0');
signal load_slot : std_logic_vector(2 downto 0);
signal load_val : std_logic_vector(N_BITS-1 downto 0);
signal all_coincidences : std_logic_vector(NUM_CLUSTERS - 1 downto 0) := (others => '0');
type group_regs_t is array (0 to NUM_GROUPS - 1) of std_logic_vector(7 downto 0);
signal reg_groups : group_regs_t := (others => (others => '0'));
signal groups_has_lap : std_logic_vector(NUM_GROUPS - 1 downto 0) := (others => '0');
type state_t is (RUNNING, FINISHED);
signal state : state_t := RUNNING;
begin
counter_out <= counter;
prime_out <= prime_found;
done_out <= done;
-- Το run_en μένει ανοιχτό για 8 κύκλους
run_en <= '1' when (state = RUNNING and timer < 8) else '0';
-- 1. ΠΑΡΑΓΩΓΗ ΤΩΝ CLUSTERS
GEN_CLUSTERS: for i in 0 to NUM_CLUSTERS - 1 generate
cluster_inst : entity work.oscillators_cluster
generic map (
BIT_WIDTH => N_BITS
)
port map (
clk => clk,
reset => rst,
run_en => run_en,
load_en => load_en_vector(i),
load_slot => load_slot,
load_val => load_val,
coincidence => all_coincidences(i) -- Σύνδεση του 1 bit
);
end generate;
-------------------------------------------------------------------------
-- ΑΥΤΟΜΑΤΟΠΟΙΗΜΕΝΟ PIPELINE REGISTERS
-------------------------------------------------------------------------
process(clk, rst)
begin
if rst = '1' then
reg_groups <= (others => (others => '0'));
elsif rising_edge(clk) then
-- Αρχικοποίηση με '0' για την περίπτωση που τα clusters δεν είναι πολλαπλάσιο του 8
reg_groups <= (others => (others => '0'));
-- Δυναμικό μοίρασμα των clusters στα αντίστοιχα groups
for i in 0 to NUM_CLUSTERS - 1 loop
reg_groups(i / 8)(i rem 8) <= all_coincidences(i);
end loop;
end if;
end process;
-- Δυναμικό Zero Detection για κάθε Group
GEN_GROUP_DETECTORS: for g in 0 to NUM_GROUPS - 1 generate
groups_has_lap(g) <= '1' when reg_groups(g) /= "00000000" else '0';
end generate;
-- Η τελική OR που ελέγχει μόνο τα groups
any_lap <= '0' when groups_has_lap = (groups_has_lap'range => '0') else '1';
-------------------------------------------------------------------------
-- 4. ΚΕΝΤΡΙΚΟΣ ΕΛΕΓΧΟΣ (STATE MACHINE)
-------------------------------------------------------------------------
process(clk, rst)
begin
if rst = '1' then
counter <= to_unsigned(2, N_BITS); -- Ξεκινάμε από το 3
prime_found <= to_unsigned(2, N_BITS);
primes_count <= 1; -- Το 2 είναι ήδη ο 1ος πρώτος
done <= '0';
timer <= 0;
load_en_vector <= (others => '0');
state <= RUNNING;
elsif rising_edge(clk) then
load_en_vector <= (others => '0');
case state is
when RUNNING =>
-- 1. Στην αρχή της περιόδου αυξάνουμε τον μετρητή
if timer = 0 then
if done /= '1' then
counter <= counter + 1;
end if;
end if;
-- 2. Ενδιάμεσα δίνουμε χρόνο να τρέξουν οι διάφορες διαδικασίες και ενημερώσεις
-- 3. Στο τέλος της περιόδου ελέγχουμε το αποτέλεσμα
if timer = CHECK_PERIOD - 1 then
if any_lap = '0' then
-- Βρέθηκε Πρώτος
prime_found <= counter;
primes_count <= primes_count + 1;
-- Ενεργοποίηση του επόμενου ελεύθερου oscillator
load_en_vector(primes_count / 8) <= '1';
load_slot <= std_logic_vector(to_unsigned(primes_count rem 8, 3));
load_val <= std_logic_vector(counter);
if (primes_count + 1 >= P) then
done <= '1';
state <= FINISHED;
end if;
end if;
timer <= 0;
else
timer <= timer + 1;
end if;
when FINISHED =>
null;
end case;
end if;
end process;
end architecture rtl;