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

Subversion Repositories leros

[/] [leros/] [trunk/] [vhdl/] [core/] [leros_ex.vhd] - Rev 4

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

--
--  Copyright 2011 Martin Schoeberl <masca@imm.dtu.dk>,
--                 Technical University of Denmark, DTU Informatics. 
--  All rights reserved.
--
-- Redistribution and use in source and binary forms, with or without
-- modification, are permitted provided that the following conditions are met:
-- 
--    1. Redistributions of source code must retain the above copyright notice,
--       this list of conditions and the following disclaimer.
-- 
--    2. Redistributions in binary form must reproduce the above copyright
--       notice, this list of conditions and the following disclaimer in the
--       documentation and/or other materials provided with the distribution.
-- 
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY EXPRESS
-- OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-- OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
-- NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
-- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-- THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-- 
-- The views and conclusions contained in the software and documentation are
-- those of the authors and should not be interpreted as representing official
-- policies, either expressed or implied, of the copyright holder.
-- 
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
use work.leros_types.all;
 
-- Some fmax number with Cyclone EP1C12C6
--
--	Memory is with rdaddr in clock process, rddata combinational
--		which is the 'normal' memory configuration, but Quartus
--		adds path through logic for read during write
--	fully registered on-chip memory 256 MHz
--	only input registers, output goes to a LC register (with reset): 165 MHz
--	plus a 16-bit adder: 147 MHz
--	more in ALU + opd mux: 135 MHz
--
--	Memory with rddata in clock process, rdaddr combinational
--		what does this model in read during write? Probably the
--		old value.
--	only input registers, output goes to a LC register (with reset): 256 MHz
--	plus a 16-bit adder: 166 MHz
--	more in ALU (add/sub) and opd mux between imm and DM output: 148 MHz
 
 
entity leros_ex is
	port  (
		clk : in std_logic;
		reset : in std_logic;
		din : in fedec_out_type;
		ioin : in io_in_type;
		dout : out ex_out_type
	);
end leros_ex;
 
architecture rtl of leros_ex is
 
	-- the accu
	signal accu, opd  : unsigned(15 downto 0);
	signal log, arith, a_mux : unsigned (15 downto 0);
 
	-- the data ram
	constant nwords : integer := 2 ** DM_BITS;
	type ram_type is array(0 to nwords-1) of std_logic_vector(15 downto 0);
 
	-- 0 initialization is for simulation only
	-- Xilinx and Altera FPGA initialize memory blocks to 0
	signal dm : ram_type := (others => (others => '0'));
 
	signal wrdata, rddata : std_logic_vector(15 downto 0);
	signal wraddr, rdaddr : std_logic_vector(DM_BITS-1 downto 0);
 
	signal wraddr_dly : std_logic_vector(DM_BITS-1 downto 0);
	signal pc_dly : std_logic_vector(IM_BITS-1 downto 0);
 
 
begin
 
	dout.accu <= std_logic_vector(accu);
	dout.dm_data <= rddata;
	rdaddr <= din.dm_addr;
	-- address for the write needs one cycle delay
	wraddr <= wraddr_dly;
 
 
process(din, rddata)
begin
	if din.dec.sel_imm='1' then
		opd <= unsigned(din.imm);
	else
		-- a MUX for IO will be added
		opd <= unsigned(rddata);
	end if;
end process;
 
-- that's the ALU	
process(din, accu, opd, log, arith, ioin)
begin
	if din.dec.add_sub='0' then
		arith <= accu + opd;
	else
		arith <= accu - opd;
	end if;
 
	case din.dec.op is
		when op_ld =>
			log <= opd;
		when op_and =>
			log <= accu and opd;
		when op_or =>
			log <= accu or opd;
		when op_xor =>
			log <= accu xor opd;
		when others =>
			null;
	end case;
 
	if din.dec.log_add='0' then
		if din.dec.shr='1' then
			a_mux <= '0' & accu(15 downto 1);
		else
			if din.dec.inp='1' then
				a_mux <= unsigned(ioin.rddata);
			else
				a_mux <= log;
			end if;
		end if;
	else
		a_mux <= arith;
	end if;
 
end process;
 
-- a MUX between 'normal' data and the PC for jal
process(din, accu, pc_dly)
begin
	if din.dec.jal='1' then
		wrdata(IM_BITS-1 downto 0) <= pc_dly;
		wrdata(15 downto IM_BITS) <= (others => '0');
	else
		wrdata <= std_logic_vector(accu);
	end if;
end process;	
 
 
process(clk, reset)
begin
	if reset='1' then
		accu <= (others => '0');
--		dout.outp <= (others => '0');
	elsif rising_edge(clk) then
		if din.dec.al_ena = '1' then
			accu(7 downto 0) <= a_mux(7 downto 0);
		end if;
		if din.dec.ah_ena = '1' then
			accu(15 downto 8) <= a_mux(15 downto 8);
		end if;
		wraddr_dly <= din.dm_addr;
		pc_dly <= din.pc;
		-- a simple output port for the hello world example
--		if din.dec.outp='1' then
--			dout.outp <= std_logic_vector(accu);
--		end if;
	end if;
end process;
 
-- the data memory (DM)
-- read during write is usually undefined in an FPGA,
-- but that is not modelled
process (clk)
begin
	if rising_edge(clk) then
		-- is store overloaded?
		-- now we have only 'register' read and write
		if din.dec.store='1' then
			dm(to_integer(unsigned(wraddr))) <= wrdata;
		end if;
		rddata <= dm(to_integer(unsigned(rdaddr)));
 
	end if;
end process;
 
 
end rtl;

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

powered by: WebSVN 2.1.0

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