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

Subversion Repositories lem1_9min

[/] [lem1_9min/] [trunk/] [lem1_9min.vhd] - Blame information for rev 7

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 7 marcus.erl
-- lem1_9min.vhd        9-bit instruction block memory, 64x1 distributed data memory
2
--      targets Spartan-2/3 on Digilent board
3
--      uses distributed RAM for data RAM, block RAM for instruction ROM & LUT tables
4
--      single clock cycle instruction execution, 9-bit fixed instruction format
5
--      Processing cycle: sync instruction read, async data RAM read, ALU, sync data RAM write  15-20ns
6
--      one clock per instruction
7
 
8
------          64x1 single port RAM with async read (distributed RAM)
9
library ieee;
10
use IEEE.STD_LOGIC_1164.ALL;
11
use IEEE.std_logic_unsigned.all;
12
entity async_ram64x1 is port(
13
    clk: in std_logic;
14
--    en: in std_logic;
15
    we: in std_logic;
16
    a: in std_logic_vector(5 downto 0);
17
    di: in std_logic;
18
    do: out std_logic);
19
end async_ram64x1;
20
architecture arch3 of async_ram64x1 is
21
    type ram_type is array(63 downto 0) of std_logic;
22
    signal RAM: ram_type;
23
begin
24
    process(clk)
25
    begin
26
        if clk'event and clk='1' then
27
--            if en = '1' then 
28
                if we='1' then RAM(conv_integer(a))<=di; end if;
29
--            end if;
30
        end if;
31
    end process;
32
    do <= RAM(conv_integer(a));
33
end arch3;
34
 
35
 
36
------          2048x9 single port RAM with sync read (block RAM)
37
library ieee;
38
use IEEE.STD_LOGIC_1164.ALL;
39
use IEEE.std_logic_unsigned.all;
40
entity sync_ram2048x9 is port(
41
    clk: in std_logic;
42
--    en: in std_logic;
43
    we: in std_logic;
44
    a: in std_logic_vector(10 downto 0);
45
    di: in std_logic_vector(8 downto 0);
46
    do: out std_logic_vector(8 downto 0));
47
end sync_ram2048x9;
48
architecture arch4 of sync_ram2048x9 is
49
    type ram_type is array(2047 downto 0) of std_logic_vector(8 downto 0);
50
    signal RAM: ram_type;
51
    signal read_a: std_logic_vector(10 downto 0);
52
begin
53
    process(clk)
54
    begin
55
        if clk'event and clk='1' then
56
--            if en = '1' then 
57
                if we='1' then RAM(conv_integer(a))<=di; end if;
58
--            end if;
59
        read_a <= a;
60
        end if;
61
    end process;
62
    do <= RAM(conv_integer(read_a));
63
end arch4;
64
 
65
 
66
------                  processor definition
67
library ieee;
68
use IEEE.STD_LOGIC_1164.ALL;
69
use IEEE.std_logic_arith.all;
70
use IEEE.std_logic_misc.all;
71
use IEEE.std_logic_signed.all;
72
use work.definitions.all;
73
 
74
entity lem1_9 is port(
75
    clk:                in std_logic;
76
    reset:      in std_logic;
77
    start:      in std_logic;
78
    pc_reg:     out std_logic_vector(10 downto 0);
79
    mem_rd:     out std_logic_vector(8 downto 0);
80
    nxdata:     out std_logic;
81
    data_we:    out std_logic;
82
    acc_cpy:    out std_logic;
83
    cry_cpy:    out std_logic
84
        );
85
end entity lem1_9;
86
 
87
architecture arch of lem1_9 is
88
-- signal naming: nx prefix: new value, x prefix: new value enable
89
type dly_type is (run, hlt);            -- states: run, halt
90
signal dly, nxdly: dly_type;            -- processing state variable & next dly
91
 
92
--      instruction register & renamings
93
signal ir: std_logic_vector(8 downto 0);         -- instruction register
94
signal inst: std_logic_vector(2 downto 0);               -- ir(8..6), op-code field
95
signal pc, nxpc: std_logic_vector(10 downto 0);  -- program counter & next pc
96
signal xpc: std_logic;                                          -- pc update enable
97
signal acc, nxacc: std_logic;                                   -- accumulator & next acc
98
signal xacc: std_logic;                                         -- acc update enable
99
signal cry, nxcry: std_logic;                                   -- carry & next carry
100
signal xcry: std_logic;                                         -- carry update enable
101
signal nxadr: std_logic_vector(5 downto 0);              -- ir(5..0), data read/write address
102
signal nxmem: std_logic;                                                -- write data
103
signal memrd: std_logic;                                                -- read data
104
signal nxwe: std_logic;                                         -- data write enable
105
 
106
--              Block RAM with parity bits
107
component RAMB16_S9 is
108
  generic (
109
       WRITE_MODE : string := "WRITE_FIRST";
110
       INIT  : bit_vector  := X"000";
111
       SRVAL : bit_vector  := X"000";
112
          -- use hexidecimal encoding
113
          --    little endian: right most bit of INIT_00 is bit 0 of location 0
114
       INIT_00 : bit_vector(255 downto 0) := X"000000000000000000000000000000000000000000000000000000000000000F";
115
       INIT_01 : bit_vector(255 downto 0) := X"0000000000000000000000000000000000000000000000000000000000000000";
116
       INIT_02 : bit_vector(255 downto 0) := X"0000000000000000000000000000000000000000000000000000000000000000";
117
       INIT_03 : bit_vector(255 downto 0) := X"0000000000000000000000000000000000000000000000000000000000000000";
118
       INIT_04 : bit_vector(255 downto 0) := X"000000000000000000000000000000000000000000000000000000000000000F";
119
       INIT_05 : bit_vector(255 downto 0) := X"0000000000000000000000000000000000000000000000000000000000000000";
120
       INIT_06 : bit_vector(255 downto 0) := X"0000000000000000000000000000000000000000000000000000000000000000";
121
       INIT_07 : bit_vector(255 downto 0) := X"0000000000000000000000000000000000000000000000000000000000000000";
122
          -- little endian: right most bit of INITP_00 is bit9 of location 0
123
       INITP_00 : bit_vector(255 downto 0) := X"0000000000000000000000000000000000000000000000000000000000000001";
124
       INITP_01 : bit_vector(255 downto 0) := X"0000000000000000000000000000000000000000000000000000000000000000";
125
       INITP_02 : bit_vector(255 downto 0) := X"0000000000000000000000000000000000000000000000000000000000000000";
126
       INITP_03 : bit_vector(255 downto 0) := X"0000000000000000000000000000000000000000000000000000000000000000"
127
  );
128
  port (DI    : in STD_LOGIC_VECTOR (7 downto 0);
129
        DIP   : in STD_LOGIC_VECTOR (0 downto 0);
130
        EN    : in STD_logic;
131
        WE    : in STD_logic;
132
        SSR   : in STD_logic;
133
        CLK   : in STD_logic;
134
        ADDR  : in STD_LOGIC_VECTOR (10 downto 0);
135
        DO    : out STD_LOGIC_VECTOR (7 downto 0);
136
        DOP   : out STD_LOGIC_VECTOR (0 downto 0));
137
end component;
138
 
139
begin
140
--      renamings
141
inst  <= ir(8 downto 6);
142
nxadr <= ir(5 downto 0);
143
 
144
--      monitoring signals
145
--pc_reg        <= pc; 
146
--acc_cpy       <= acc; 
147
--cry_cpy       <= cry;
148
--nxdata        <= nxmem;
149
--data_we       <= nxwe;
150
--mem_rd        <= inst & nxadr;
151
 
152
-- port maps
153
data_bit:       entity work.async_ram64x1 port map(
154
        clk  => clk,
155
--   en   => sig1,
156
        we   => nxwe,
157
        a    => nxadr(5 downto 0),
158
        di   => nxmem,
159
        do   => memrd);
160
 
161
memory: RAMB16_S9 generic map(
162
--      toggle ACC & CRY (clear ACC & CRY; set ACC & CRY; HALT)
163
--      INIT_00  => X"00000000000000000000000000000000000000000000000000000000007F1A1F",
164
--      INITP_00 => X"0000000000000000000000000000000000000000000000000000000000000000")
165
--      increment 24-bit counter at memory locations 23..0
166
--      INIT_00  => X"CD164ECE164FCF1650D01651D11652D21653D31654D41655D51656D61657D711",
167
--      INIT_01  => X"1643C31644C41645C51646C61647C71648C81649C9164ACA164BCB164CCC164D",
168
--      INIT_02  => X"00000000000000000000000000000000000000000000000040C01641C11642C2",
169
--      INITP_00 => X"0000000000000000000000000000000000000000000000492492492492492492")
170
--      four-bit adder at memory locations 59..56 (mem loc 7..4 + "00" & loc 15..14)
171
--      mem loc 63..60: active low decode of loc 15..14
172
--      mem loc 55..48: active low drive of 7-seg display
173
--      HELLO UJOrLd
174
        INIT_00  => X"CD164ECE164FCF1650D01651D11652D21653D31654D41655D51656D61657D711",
175
        INIT_01  => X"1643C31644C41645C51646C61647C71648C81649C9164ACA164BCB164CCC164D",
176
        INIT_02  => X"177E8F7C8E7D4FCE7F4F8E7BC2167AC31679C48E78C58F1040C01641C11642C2",
177
        INIT_03  => X"6C38AA776F6E6D792AF86939F86A197ABB6B3A6C38F96D38BA6E38BB6F3ABB70",
178
        INIT_04  => X"39FB726F6EAD736FAB746F6B682CBB682A1978B9756F6C6829FA6839AA766F69",
179
        INIT_05  => X"000000000000000000000000000000000000000000000000000071687A3BF868",
180
        INITP_00 => X"00000000000000000000001C993CA793CF9129242A4924492492492492492492")
181
 
182
--      HEllo UJorld
183
--      INIT_00  => X"CD164ECE164FCF1650D01651D11652D21653D31654D41655D51656D61657D711",
184
--      INIT_01  => X"1643C31644C41645C51646C61647C71648C81649C9164ACA164BCB164CCC164D",
185
--      INIT_02  => X"177E8F7C8E7D4FCE7F4F8E7BC2167AC31679C48E78C58F1040C01641C11642C2",
186
--      INIT_03  => X"79BA6E7B1939BA762F7A193839BB6F2F7B193839BA6F78797ABB77797A7BF870",
187
--      INIT_04  => X"BB6D2D78797AFB6D2D7B1939BA6D787BFA752E7879BB6E2E7A193839BB6E2E78",
188
--      INIT_05  => X"BB6A79BA722B787AF96B2B787BF96B7ABB733A2C7BF96C78BB74372D7A193839",
189
--      INIT_06  => X"00000000000000000000000000000000000000000000712A7A1938BB6A2A7879",
190
--      INITP_00 => X"00000000000001A72739393B3CD339B394D9B39C2A4924492492492492492492")
191
--      
192
                port map(
193
        DI      => (others => '0'),
194
        DIP     => (others => '0'),
195
        EN      => '1',
196
        WE      => '0',
197
        SSR     => '0',
198
        CLK     => clk,
199
        ADDR    => nxpc(10 downto 0),
200
        DO      => ir(7 downto 0),
201
        DOP     => ir(8 downto 8));
202
 
203
--memory: entity work.sync_ram2048x9 port map(
204
--      clk => clk,
205
----    en  => vcc,
206
--      we  => gnd,
207
--      a   => nxpc(10 downto 0),
208
--      di  => (others => '0'),
209
--      do  => ir);
210
 
211
-- instruction processing       
212
decode: process(dly,start,memrd,acc,cry,inst,pc,ir) begin
213
--      default values for update enables & "nx" signals
214
nxdly   <= hlt;
215
xpc             <= '-';
216
nxpc            <= (others => '-');
217
nxwe            <= '-';
218
nxmem   <= '-';
219
xacc            <= '-';
220
nxacc   <= '-';
221
xcry            <= '-';
222
nxcry   <= '-';
223
 
224
--      state dispatch
225
        case dly is
226
        when hlt        =>
227
                if start = '1' then nxdly <= run; else nxdly <= hlt; end if;
228
                xacc    <= '1'; nxacc   <= '0';
229
                xpc     <= '1'; nxpc            <= (others => '0');      -- keep PC reset 
230
                xcry    <= '1'; nxcry   <= '0';
231
                nxwe    <= '0';
232
 
233
        when run        =>
234
--      op-code dispatch 
235
case inst is
236
 
237
when opMSC =>
238
        case ir(5 downto 4) is
239
        when opHLT =>
240
                nxdly <= hlt;
241
 
242
        when opAnC =>
243
                nxdly <= run;
244
                case ir(3 downto 0) is
245
                when "0000" => xacc <= '1';     nxacc <= '0';            xcry <= '1';    nxcry <= '0';    -- A,C = 0,0
246
                when "0001" => xacc <= '1';     nxacc <= '0';            xcry <= '1';    nxcry <= '1';   -- A,C = 0,1
247
                when "0010" => xacc <= '1';     nxacc <= '1';           xcry <= '1';    nxcry <= '0';    -- A,C = 1,0
248
                when "0011" => xacc <= '1';     nxacc <= '1';           xcry <= '1';    nxcry <= '1';   -- A,C = 1,1
249
                when "0100" => xacc <= '0';                                      xcry <= '1';    nxcry <= '0';    -- C = 0
250
                when "0101" => xacc <= '0';                                      xcry <= '1';    nxcry <= '1';   -- C = 1
251
                when "0110" => xacc <= '1';     nxacc <= '0';            xcry <= '0';     -- A = 0
252
                when "0111" => xacc <= '1';     nxacc <= '1';           xcry <= '0';     -- A = 1
253
                when "1000" => xacc <= '0';                                      xcry <= '1';    nxcry <= acc OR cry;    -- C = A | C
254
                when "1001" => xacc <= '1';     nxacc <= not acc;       xcry <= '0';     -- A = not A
255
                when "1010" => xacc <= '0';                                      xcry <= '1';    nxcry <= not cry;       -- C = not C
256
                when "1011" => xacc <= '1';     nxacc <= not acc;       xcry <= '1';    nxcry <= not cry;       -- A,C = not A, not C
257
                when "1100" => xacc <= '0';                                      xcry <= '1';    nxcry <= acc AND cry;   -- C = A & C
258
                when "1101" => xacc <= '1';     nxacc <= cry;           xcry <= '0';     -- A = C
259
                when "1110" => xacc <= '0';                                      xcry <= '1';    nxcry <= acc;   -- C = A
260
                when "1111" => xacc <= '1';     nxacc <= cry;           xcry <= '1';    nxcry <= acc;   -- A,C = C,A
261
                when others => xacc <= '0';                                      xcry <= '0';
262
                end case;
263
                xpc     <= '1'; nxpc    <= pc + 1;
264
                nxwe    <= '0';
265
        when others =>  null;
266
        end case;
267
 
268
when opST  =>
269
        nxdly<= run;
270
        xacc    <= '0';
271
        xpc     <= '1'; nxpc            <= pc + 1;
272
        xcry    <= '0';
273
        nxwe    <= '1'; nxmem   <= acc;
274
 
275
when opLD  =>
276
        nxdly<= run;
277
        xacc    <= '1'; nxacc   <= memrd;
278
        xpc     <= '1'; nxpc            <= pc + 1;
279
        xcry    <= '0';
280
        nxwe    <= '0';
281
 
282
when opLDC =>
283
        nxdly<= run;
284
        xacc    <= '1'; nxacc   <= not memrd;
285
        xpc     <= '1'; nxpc            <= pc + 1;
286
        xcry    <= '0';
287
        nxwe    <= '0';
288
 
289
when opAND =>
290
        nxdly<= run;
291
        xacc    <= '1'; nxacc   <= acc and memrd;
292
        xpc     <= '1'; nxpc            <= pc + 1;
293
        xcry    <= '0';
294
        nxwe    <= '0';
295
 
296
when opOR  =>
297
        nxdly<= run;
298
        xacc    <= '1'; nxacc   <= acc or memrd;
299
        xpc     <= '1'; nxpc            <= pc + 1;
300
        xcry    <= '0';
301
        nxwe    <= '0';
302
 
303
when opXOR =>
304
        nxdly<= run;
305
        xacc    <= '1'; nxacc   <= acc xor memrd;
306
        xpc     <= '1'; nxpc            <= pc + 1;
307
        xcry    <= '0';
308
        nxwe    <= '0';
309
 
310
when opADC =>
311
        nxdly<= run;
312
        xacc    <= '1'; nxacc   <= acc xor memrd xor cry;
313
        xpc     <= '1'; nxpc            <= pc + 1;
314
        xcry    <= '1'; nxcry   <= (acc and cry) or (acc and memrd) or (cry and memrd);
315
        nxwe    <= '0';
316
 
317
when others => null;
318
end case;
319
        when others => null;
320
        end case;
321
 
322
end process decode;
323
 
324
--              all processor register updates 
325
update: process(clk,reset) begin
326
if reset='1'            -- master reset
327
then    dly             <= hlt;
328
        acc             <= '0';
329
        cry             <= '0';
330
        pc              <= (others => '0');
331
--              monitoring signals
332
        acc_cpy <= '0';
333
        cry_cpy <= '0';
334
        nxdata  <= '0';
335
        data_we <= '0';
336
        pc_reg  <= (others => '0');
337
        mem_rd  <= (others => '0');
338
elsif (clk'event and clk='1')
339
then
340
--              state variable update
341
        dly             <= nxdly;
342
--              accumulator update
343
        if xacc = '1'   then acc        <= nxacc; end if;
344
--              update carry bit
345
        if xcry = '1'   then cry        <= nxcry; end if;
346
--              Program counter update
347
        if xpc = '1'    then pc <= nxpc; end if;
348
----    monitoring signals
349
        acc_cpy <= acc;
350
        cry_cpy <= cry;
351
        nxdata  <= nxmem;
352
        data_we <= nxwe;
353
        pc_reg  <= pc;
354
        mem_rd  <= inst & nxadr;
355
end if;
356
end process update;
357
 
358
end arch;

powered by: WebSVN 2.1.0

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