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

Subversion Repositories avuc

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

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

Line No. Rev Author Line
1 5 fblanco
-- File generated by avuc.pl (7/8/2009)
2
--
3
---------------------------------------------------------------------------------------
4
-- Copyright 2008 by USM
5
-- Description: Search for the maximum number in a memory.
6
---------------------------------------------------------------------------------------
7
 
8
 
9
library ieee;
10
use ieee.std_logic_1164.all;
11
use ieee.std_logic_unsigned.all;
12
 
13
library work;
14
use work.usm_pkg.all;
15
 
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
      -- 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
      -- 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
-- 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
 
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') then
202
            usm_pc_ldjmp <= '1';
203
         end if;
204
      when USMO_JUMP_IF_MEM_DATA_LT_MAX =>
205
         if mem_data < max_number   then
206
            usm_pc_ldjmp <= '1';
207
         end if;
208
      when others =>
209
         usm_pc_ldjmp <= '0';
210
      end case;
211
      -- usm_pc:
212
      usm_cy_0_d1 <= usm_cy(0) and not usm_pc_ldini_init_d1;
213
      var_aux := usm_pc_ldini & usm_pc_ldend & (usm_pc_ldjmp and usm_cy_0_d1) & usm_pc_inc;
214
      case var_aux is
215
      when "0000" =>
216
         null;
217
      when "0001" =>
218
         usm_pc <= usm_pc + 1;
219
      when "0010" | "0011" =>
220
         usm_pc <= usm_data(usm_pc'range);
221
      when "0100" | "0101" | "0110" | "0111" =>
222
         usm_pc <= USML_END;
223
      when "1000" | "1001" | "1010" | "1011" | "1100" | "1101" | "1110" | "1111" =>       -- 1XXX
224
         usm_pc <= USML_BEGIN;
225
      when others =>
226
            null;
227
--          usm_pc <= USML_BEGIN;
228
      end case;
229
   end if;
230
end process p_usm_pc_drv;
231
 
232
p_usm_cy_drv: process(clk)
233
begin
234
   if rising_edge(clk) then
235
      usm_cy_rst <= '0';
236
      if usm_cy = 0 then
237
         usm_cy_rst <= '1';
238
      end if;
239
      -- usm_cy:
240
      if usm_pc_inc = '1' or (usm_pc_ldjmp = '1' and usm_cy_0_d1 = '1') or
241
                                    usm_pc_ldini_init_d1 = '1' or usm_cy_rst = '1' then
242
         usm_cy <= (0 => '1', others => '0');
243
      else
244
         usm_cy(0) <= '0';
245
         for i in usm_cy'range loop
246
            if i /= 0 then
247
               usm_cy(i) <= usm_cy(i-1);
248
            end if;
249
         end loop;
250
      end if;
251
   end if;
252
end process p_usm_cy_drv;
253
 
254
--**************************** Drivers processes ******************************--
255
 
256
p_usm_max_number_drv: process(clk)
257
variable max_number_var: std_logic_vector(1 downto 0);
258
begin
259
   if rising_edge(clk) then
260
      -- max_number_assign:
261
      usm_max_number_assign_0 <= '0';
262
      if usm_opcode = USMO_MAX_NUMBER_ASSIGN then
263
         if usm_cy(0) = '1' then
264
            usm_max_number_assign_0 <= '1';
265
         end if;
266
      end if;
267
      -- max_number_ini:
268
      usm_max_number_ini_0 <= '0';
269
      if usm_opcode = USMO_MAX_NUMBER_INI then
270
         if usm_cy(0) = '1' then
271
            usm_max_number_ini_0 <= '1';
272
         end if;
273
      end if;
274
      -- Actions:
275
      max_number_var := usm_max_number_assign_0 & usm_max_number_ini_0;
276
      case max_number_var is
277
      when "00" => null;
278
      when "10" =>
279
         max_number <= mem_data;
280
      when "01" =>
281
         max_number <= (others => '0');
282
      when others => null;
283
      end case;
284
   end if;
285
end process p_usm_max_number_drv;
286
 
287
 
288
p_usm_mem_addr_s_drv: process(clk)
289
variable mem_addr_s_var: std_logic_vector(1 downto 0);
290
begin
291
   if rising_edge(clk) then
292
      -- mem_addr_ini:
293
      usm_mem_addr_ini_0 <= '0';
294
      if usm_opcode = USMO_MEM_ADDR_INI then
295
         if usm_cy(0) = '1' then
296
            usm_mem_addr_ini_0 <= '1';
297
         end if;
298
      end if;
299
      -- mem_addr_inc:
300
      usm_mem_addr_inc_0 <= '0';
301
      if usm_opcode = USMO_MEM_ADDR_INC then
302
         if usm_cy(0) = '1' then
303
            usm_mem_addr_inc_0 <= '1';
304
         end if;
305
      end if;
306
      -- Actions:
307
      mem_addr_s_var := usm_mem_addr_inc_0 & usm_mem_addr_ini_0;
308
      case mem_addr_s_var is
309
      when "00" => null;
310
      when "10" =>
311
         mem_addr_s <= mem_addr_s + 1;
312
      when "01" =>
313
         mem_addr_s <= (others => '0');
314
      when others => null;
315
      end case;
316
   end if;
317
end process p_usm_mem_addr_s_drv;
318
 
319
--******************************** Extra code *********************************--
320
   mem_addr <= mem_addr_s;
321
 
322
 
323
 
324
end program;

powered by: WebSVN 2.1.0

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