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

Subversion Repositories leros

[/] [leros/] [trunk/] [vhdl/] [core/] [leros_ex.vhd] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 martin
--
2
--  Copyright 2011 Martin Schoeberl <masca@imm.dtu.dk>,
3
--                 Technical University of Denmark, DTU Informatics. 
4
--  All rights reserved.
5
--
6
-- Redistribution and use in source and binary forms, with or without
7
-- modification, are permitted provided that the following conditions are met:
8
-- 
9
--    1. Redistributions of source code must retain the above copyright notice,
10
--       this list of conditions and the following disclaimer.
11
-- 
12
--    2. Redistributions in binary form must reproduce the above copyright
13
--       notice, this list of conditions and the following disclaimer in the
14
--       documentation and/or other materials provided with the distribution.
15
-- 
16
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY EXPRESS
17
-- OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18
-- OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
19
-- NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
20
-- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21
-- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22
-- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23
-- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25
-- THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
-- 
27
-- The views and conclusions contained in the software and documentation are
28
-- those of the authors and should not be interpreted as representing official
29
-- policies, either expressed or implied, of the copyright holder.
30
-- 
31
 
32
library ieee;
33
use ieee.std_logic_1164.all;
34
use ieee.numeric_std.all;
35
 
36
use work.leros_types.all;
37
 
38
-- Some fmax number with Cyclone EP1C12C6
39
--
40
--      Memory is with rdaddr in clock process, rddata combinational
41
--              which is the 'normal' memory configuration, but Quartus
42
--              adds path through logic for read during write
43
--      fully registered on-chip memory 256 MHz
44
--      only input registers, output goes to a LC register (with reset): 165 MHz
45
--      plus a 16-bit adder: 147 MHz
46
--      more in ALU + opd mux: 135 MHz
47
--
48
--      Memory with rddata in clock process, rdaddr combinational
49
--              what does this model in read during write? Probably the
50
--              old value.
51
--      only input registers, output goes to a LC register (with reset): 256 MHz
52
--      plus a 16-bit adder: 166 MHz
53
--      more in ALU (add/sub) and opd mux between imm and DM output: 148 MHz
54
 
55
 
56
entity leros_ex is
57
        port  (
58
                clk : in std_logic;
59
                reset : in std_logic;
60
                din : in fedec_out_type;
61
                ioin : in io_in_type;
62
                dout : out ex_out_type
63
        );
64
end leros_ex;
65
 
66
architecture rtl of leros_ex is
67
 
68
        -- the accu
69
        signal accu, opd  : unsigned(15 downto 0);
70
        signal log, arith, a_mux : unsigned (15 downto 0);
71
 
72
        -- the data ram
73
        constant nwords : integer := 2 ** DM_BITS;
74
        type ram_type is array(0 to nwords-1) of std_logic_vector(15 downto 0);
75
 
76
        -- 0 initialization is for simulation only
77
        -- Xilinx and Altera FPGA initialize memory blocks to 0
78
        signal dm : ram_type := (others => (others => '0'));
79
 
80
        signal wrdata, rddata : std_logic_vector(15 downto 0);
81
        signal wraddr, rdaddr : std_logic_vector(DM_BITS-1 downto 0);
82
 
83
        signal wraddr_dly : std_logic_vector(DM_BITS-1 downto 0);
84
        signal pc_dly : std_logic_vector(IM_BITS-1 downto 0);
85
 
86
 
87
begin
88
 
89
        dout.accu <= std_logic_vector(accu);
90
        dout.dm_data <= rddata;
91
        rdaddr <= din.dm_addr;
92
        -- address for the write needs one cycle delay
93
        wraddr <= wraddr_dly;
94
 
95
 
96
process(din, rddata)
97
begin
98
        if din.dec.sel_imm='1' then
99
                opd <= unsigned(din.imm);
100
        else
101
                -- a MUX for IO will be added
102
                opd <= unsigned(rddata);
103
        end if;
104
end process;
105
 
106
-- that's the ALU       
107
process(din, accu, opd, log, arith, ioin)
108
begin
109
        if din.dec.add_sub='0' then
110
                arith <= accu + opd;
111
        else
112
                arith <= accu - opd;
113
        end if;
114
 
115
        case din.dec.op is
116
                when op_ld =>
117
                        log <= opd;
118
                when op_and =>
119
                        log <= accu and opd;
120
                when op_or =>
121
                        log <= accu or opd;
122
                when op_xor =>
123
                        log <= accu xor opd;
124
                when others =>
125
                        null;
126
        end case;
127
 
128
        if din.dec.log_add='0' then
129
                if din.dec.shr='1' then
130
                        a_mux <= '0' & accu(15 downto 1);
131
                else
132
                        if din.dec.inp='1' then
133
                                a_mux <= unsigned(ioin.rddata);
134
                        else
135
                                a_mux <= log;
136
                        end if;
137
                end if;
138
        else
139
                a_mux <= arith;
140
        end if;
141
 
142
end process;
143
 
144
-- a MUX between 'normal' data and the PC for jal
145
process(din, accu, pc_dly)
146
begin
147
        if din.dec.jal='1' then
148
                wrdata(IM_BITS-1 downto 0) <= pc_dly;
149
                wrdata(15 downto IM_BITS) <= (others => '0');
150
        else
151
                wrdata <= std_logic_vector(accu);
152
        end if;
153
end process;
154
 
155
 
156
process(clk, reset)
157
begin
158
        if reset='1' then
159
                accu <= (others => '0');
160
--              dout.outp <= (others => '0');
161
        elsif rising_edge(clk) then
162
                if din.dec.al_ena = '1' then
163
                        accu(7 downto 0) <= a_mux(7 downto 0);
164
                end if;
165
                if din.dec.ah_ena = '1' then
166
                        accu(15 downto 8) <= a_mux(15 downto 8);
167
                end if;
168
                wraddr_dly <= din.dm_addr;
169
                pc_dly <= din.pc;
170
                -- a simple output port for the hello world example
171
--              if din.dec.outp='1' then
172
--                      dout.outp <= std_logic_vector(accu);
173
--              end if;
174
        end if;
175
end process;
176
 
177
-- the data memory (DM)
178
-- read during write is usually undefined in an FPGA,
179
-- but that is not modelled
180
process (clk)
181
begin
182
        if rising_edge(clk) then
183
                -- is store overloaded?
184
                -- now we have only 'register' read and write
185
                if din.dec.store='1' then
186
                        dm(to_integer(unsigned(wraddr))) <= wrdata;
187
                end if;
188
                rddata <= dm(to_integer(unsigned(rdaddr)));
189
 
190
        end if;
191
end process;
192
 
193
 
194
end rtl;

powered by: WebSVN 2.1.0

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