OpenCores
URL https://opencores.org/ocsvn/avuc/avuc/trunk

Subversion Repositories avuc

[/] [avuc/] [trunk/] [example/] [max_mem.vhd] - Blame information for rev 6

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 6 fblanco
-- File generated by avuc.pl (8/8/2009)
2
--
3 5 fblanco
---------------------------------------------------------------------------------------
4
-- Copyright 2008 by USM
5
-- Description: Search for the maximum number in a memory.
6
---------------------------------------------------------------------------------------
7 6 fblanco
 
8
 
9 5 fblanco
library ieee;
10
use ieee.std_logic_1164.all;
11
use ieee.std_logic_unsigned.all;
12 6 fblanco
 
13 5 fblanco
library work;
14
use work.usm_pkg.all;
15 6 fblanco
 
16
 
17
entity max_mem is
18
   port (
19
      -- To start the program:
20
      avuc_start: in std_logic;
21
      -- To stop the program:
22
      avuc_rst: in std_logic;
23 5 fblanco
      -- Main clock:
24
      clk: in std_logic;
25
      -- Memory data bus:
26
      mem_data: in std_logic_vector(7 downto 0);
27
      -- Memory address bus:
28
      mem_addr: out std_logic_vector(6 downto 0);
29 6 fblanco
      -- State of the program (running/stopped):
30
      avuc_state: out std_logic
31
   );
32
end max_mem;
33
 
34
 
35
architecture program of max_mem is
36
 
37
 
38 5 fblanco
-- Temporary maximum number 
39
signal max_number: std_logic_vector(mem_data'range);
40
-- Copy of output:
41
signal mem_addr_s: std_logic_vector(mem_addr'range);
42 6 fblanco
 
43
 
44
-- Basic registers of usm:
45
signal usm_opcode: std_logic_vector(2 downto 0);
46
signal usm_pc: std_logic_vector(2 downto 0) := (others => '1');
47
signal usm_data: std_logic_vector(2 downto 0);
48
signal usm_cyclesno: std_logic_vector(0 downto 0);
49
-- Cycles counter:
50
signal usm_cy: std_logic_vector(1 downto 0);
51
-- usm_cy(0) delayed 1 clock:
52
signal usm_cy_0_d1: std_logic;
53
-- To avoid usm_cy deadlock:
54
signal usm_cy_rst: std_logic;
55
 
56
-- Commands list:
57
constant USMO_NOP:
58
         std_logic_vector(usm_opcode'range) := "000";
59
constant USMO_JUMP:
60
         std_logic_vector(usm_opcode'range) := "001";
61
constant USMO_MEM_ADDR_INI:
62
         std_logic_vector(usm_opcode'range) := "010";
63
constant USMO_MEM_ADDR_INC:
64
         std_logic_vector(usm_opcode'range) := "011";
65
constant USMO_MAX_NUMBER_INI:
66
         std_logic_vector(usm_opcode'range) := "100";
67
constant USMO_MAX_NUMBER_ASSIGN:
68
         std_logic_vector(usm_opcode'range) := "101";
69
constant USMO_JUMP_IF_MEM_ADDR_EQ_LAST:
70
         std_logic_vector(usm_opcode'range) := "110";
71
constant USMO_JUMP_IF_MEM_DATA_LT_MAX:
72
         std_logic_vector(usm_opcode'range) := "111";
73
 
74
-- Labels list:
75
constant USML_NEXT1:
76
         std_logic_vector(usm_pc'range) := "100";
77
constant USML_LOOP1:
78
         std_logic_vector(usm_pc'range) := "010";
79
constant USML_BEGIN:
80
         std_logic_vector(usm_pc'range) := "000";
81
constant USML_END:
82
         std_logic_vector(usm_pc'range) := "111";
83
 
84
-- usm_pc reset:
85
signal avuc_start_d: std_logic_vector(2 downto 0);
86
signal avuc_rst_d: std_logic_vector(2 downto 0);
87
signal stup_rst, stup_rst_d1: std_logic;
88
signal stup_rst_cnt: std_logic_vector(5 downto 0) := (others => '0');
89
signal usm_pc_gt_end: std_logic;
90
signal usm_pc_ldini_init_d1: std_logic;
91
signal usm_pc_ldend_init_d1: std_logic;
92
-- usm_pc microcodes:
93
signal usm_pc_inc: std_logic;
94
signal usm_pc_ldjmp: std_logic;
95
signal usm_pc_ldini: std_logic;
96
signal usm_pc_ldend: std_logic;
97
-- Remaining microcodes:
98
signal usm_max_number_assign_0: std_logic;
99
signal usm_max_number_ini_0: std_logic;
100
signal usm_mem_addr_ini_0: std_logic;
101
signal usm_mem_addr_inc_0: std_logic;
102
 
103
 
104
begin
105
 
106
--***************************** Program processes *****************************--
107
-- Program start/stop/state:
108
p_prog_init: process(clk)
109
variable usm_pc_ld_init_var: std_logic;
110
begin
111
   if rising_edge(clk) then
112
      -- Program start:
113
      avuc_start_d(0) <= avuc_start;
114
      avuc_start_d(1) <= avuc_start_d(0);
115
      avuc_start_d(2) <= avuc_start_d(1);
116
      usm_pc_ld_init_var := avuc_start_d(1) and not avuc_start_d(2);
117
      usm_pc_ldini_init_d1 <= usm_pc_ld_init_var;
118
      usm_pc_ldini <= usm_pc_ld_init_var or usm_pc_ldini_init_d1;          -- 2 clocks long
119
      -- Program stop:
120
      if stup_rst = '1' then
121
         stup_rst_cnt <= stup_rst_cnt + 1;
122
      end if;
123
      stup_rst <= '0';
124
      if stup_rst_cnt(5 downto 4) /= 2 then
125
         stup_rst <= '1';
126
      end if;
127
      stup_rst_d1 <= stup_rst;
128
      usm_pc_gt_end <= '0';
129
      if usm_pc > USML_END and usm_pc_gt_end = '0' then
130
         usm_pc_gt_end <= '1';
131
      end if;
132
      avuc_rst_d(0) <= avuc_rst;
133
      avuc_rst_d(1) <= avuc_rst_d(0);
134
      avuc_rst_d(2) <= avuc_rst_d(1);
135
      usm_pc_ld_init_var := usm_pc_gt_end or (not stup_rst and stup_rst_d1) or
136
                                             ( avuc_rst_d(1) and not avuc_rst_d(2) );
137
      usm_pc_ldend_init_d1 <= usm_pc_ld_init_var;
138
      usm_pc_ldend <= usm_pc_ld_init_var or usm_pc_ldend_init_d1;          -- 2 clocks long
139
      -- Program state:
140
      avuc_state <= AVUC_STATE_RUNNING;
141
      if usm_pc = USML_END then
142
         avuc_state <= AVUC_STATE_STOPPED;
143
      end if;
144
   end if;
145
end process p_prog_init;
146
 
147
p_usm_prog_code: process(usm_pc)
148
begin
149
   usm_data <= (others => '-');
150
   case usm_pc is
151
   when "000" =>
152
      usm_opcode <= USMO_MEM_ADDR_INI;
153
      usm_cyclesno <= (0 => '1', others => '0');
154
   when "001" =>
155
      usm_opcode <= USMO_MAX_NUMBER_INI;
156
      usm_cyclesno <= (0 => '1', others => '0');
157
   when "010" =>
158
      usm_opcode <= USMO_JUMP_IF_MEM_DATA_LT_MAX;
159
      usm_cyclesno <= (0 => '1', others => '0');
160
      usm_data <= "100";
161
   when "011" =>
162
      usm_opcode <= USMO_MAX_NUMBER_ASSIGN;
163
      usm_cyclesno <= (0 => '1', others => '0');
164
   when "100" =>
165
      usm_opcode <= USMO_JUMP_IF_MEM_ADDR_EQ_LAST;
166
      usm_cyclesno <= (0 => '1', others => '0');
167
      usm_data <= "111";
168
   when "101" =>
169
      usm_opcode <= USMO_MEM_ADDR_INC;
170
      usm_cyclesno <= (0 => '1', others => '0');
171
   when "110" =>
172
      usm_opcode <= USMO_JUMP;
173
      usm_cyclesno <= (0 => '1', others => '0');
174
      usm_data <= "010";
175
   when "111" =>
176
      usm_opcode <= USMO_JUMP;
177
      usm_cyclesno <= (0 => '1', others => '0');
178
      usm_data <= "111";
179
   when others =>
180
      usm_opcode <= (others => '-');
181
      usm_cyclesno <= (others => '-');
182
   end case;
183
end process p_usm_prog_code;
184
 
185
--************************** Jump & cycle processes ***************************--
186
p_usm_pc_drv: process(clk)
187
variable var_aux: std_logic_vector(3 downto 0);
188
begin
189
   if rising_edge(clk) then
190
      -- usm_pc_inc (increment usm_pc):
191
      usm_pc_inc <= '0';
192
      if usm_cy = usm_cyclesno and usm_pc_ldini_init_d1 = '0' then
193
         usm_pc_inc <= '1';
194
      end if;
195
      -- usm_pc_ldjmp (load usm_pc with usm_data):
196
      usm_pc_ldjmp <= '0';
197
      case usm_opcode is
198
      when USMO_JUMP =>
199
         usm_pc_ldjmp <= '1';
200
      when USMO_JUMP_IF_MEM_ADDR_EQ_LAST =>
201
         if mem_addr_s = (mem_addr_s'range => '1')
202
 then
203
            usm_pc_ldjmp <= '1';
204
         end if;
205
      when USMO_JUMP_IF_MEM_DATA_LT_MAX =>
206
         if mem_data < max_number
207
   then
208
            usm_pc_ldjmp <= '1';
209
         end if;
210
      when others =>
211
         usm_pc_ldjmp <= '0';
212
      end case;
213
      -- usm_pc:
214
      usm_cy_0_d1 <= usm_cy(0) and not usm_pc_ldini_init_d1;
215
      var_aux := usm_pc_ldini & usm_pc_ldend & (usm_pc_ldjmp and usm_cy_0_d1) & usm_pc_inc;
216
      case var_aux is
217
      when "0000" =>
218
         null;
219
      when "0001" =>
220
         usm_pc <= usm_pc + 1;
221
      when "0010" | "0011" =>
222
         usm_pc <= usm_data(usm_pc'range);
223
      when "0100" | "0101" | "0110" | "0111" =>
224
         usm_pc <= USML_END;
225
      when "1000" | "1001" | "1010" | "1011" | "1100" | "1101" | "1110" | "1111" =>       -- 1XXX
226
         usm_pc <= USML_BEGIN;
227
      when others =>
228
            null;
229
--          usm_pc <= USML_BEGIN;
230
      end case;
231
   end if;
232
end process p_usm_pc_drv;
233
 
234
p_usm_cy_drv: process(clk)
235
begin
236
   if rising_edge(clk) then
237
      usm_cy_rst <= '0';
238
      if usm_cy = 0 then
239
         usm_cy_rst <= '1';
240
      end if;
241
      -- usm_cy:
242
      if usm_pc_inc = '1' or (usm_pc_ldjmp = '1' and usm_cy_0_d1 = '1') or
243
                                    usm_pc_ldini_init_d1 = '1' or usm_cy_rst = '1' then
244
         usm_cy <= (0 => '1', others => '0');
245
      else
246
         usm_cy(0) <= '0';
247
         for i in usm_cy'range loop
248
            if i /= 0 then
249
               usm_cy(i) <= usm_cy(i-1);
250
            end if;
251
         end loop;
252
      end if;
253
   end if;
254
end process p_usm_cy_drv;
255
 
256
--**************************** Drivers processes ******************************--
257
 
258
p_usm_max_number_drv: process(clk)
259
variable max_number_var: std_logic_vector(1 downto 0);
260
begin
261
   if rising_edge(clk) then
262
      -- max_number_assign:
263
      usm_max_number_assign_0 <= '0';
264
      if usm_opcode = USMO_MAX_NUMBER_ASSIGN then
265
         if usm_cy(0) = '1' then
266
            usm_max_number_assign_0 <= '1';
267
         end if;
268
      end if;
269
      -- max_number_ini:
270
      usm_max_number_ini_0 <= '0';
271
      if usm_opcode = USMO_MAX_NUMBER_INI then
272
         if usm_cy(0) = '1' then
273
            usm_max_number_ini_0 <= '1';
274
         end if;
275
      end if;
276
      -- Actions:
277
      max_number_var := usm_max_number_assign_0 & usm_max_number_ini_0;
278
      case max_number_var is
279
      when "00" => null;
280
      when "10" =>
281 5 fblanco
         max_number <= mem_data;
282 6 fblanco
      when "01" =>
283 5 fblanco
         max_number <= (others => '0');
284 6 fblanco
      when others => null;
285
      end case;
286
   end if;
287
end process p_usm_max_number_drv;
288
 
289
 
290
p_usm_mem_addr_s_drv: process(clk)
291
variable mem_addr_s_var: std_logic_vector(1 downto 0);
292
begin
293
   if rising_edge(clk) then
294
      -- mem_addr_ini:
295
      usm_mem_addr_ini_0 <= '0';
296
      if usm_opcode = USMO_MEM_ADDR_INI then
297
         if usm_cy(0) = '1' then
298
            usm_mem_addr_ini_0 <= '1';
299
         end if;
300
      end if;
301
      -- mem_addr_inc:
302
      usm_mem_addr_inc_0 <= '0';
303
      if usm_opcode = USMO_MEM_ADDR_INC then
304
         if usm_cy(0) = '1' then
305
            usm_mem_addr_inc_0 <= '1';
306
         end if;
307
      end if;
308
      -- Actions:
309
      mem_addr_s_var := usm_mem_addr_inc_0 & usm_mem_addr_ini_0;
310
      case mem_addr_s_var is
311
      when "00" => null;
312
      when "10" =>
313 5 fblanco
         mem_addr_s <= mem_addr_s + 1;
314 6 fblanco
      when "01" =>
315 5 fblanco
         mem_addr_s <= (others => '0');
316 6 fblanco
      when others => null;
317
      end case;
318
   end if;
319
end process p_usm_mem_addr_s_drv;
320
 
321
--******************************** Extra code *********************************--
322 5 fblanco
   mem_addr <= mem_addr_s;
323
 
324
 
325 6 fblanco
 
326
end program;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.