|
Message
From: OpenCores CVS Agent<cvs@o...>
Date: Sun Jan 30 21:41:42 CET 2005
Subject: [cvs-checkins] MODIFIED: risc5x ...
Date: 00/05/01 30:21:41 Added: risc5x add_sub.vhd alu.vhd alubit.vhd cpu.vhd cpu_tb.vhd idec.vhd jumptest.asm jumptest.hex mux2.vhd mux2_add_reg.vhd mux4.vhd mux8.vhd pkg_prims.vhd pkg_risc5x.vhd pkg_xilinx_prims.vhd readme.txt regs.vhd risc5x_xil.ucf risc5x_xil.vhd Log: Revision Changes Path 1.1 risc5x/add_sub.vhd http://www.opencores.org/cvsweb.shtml/risc5x/add_sub.vhd?rev=1.1&content-type=text/x-cvsweb-markup Index: add_sub.vhd =================================================================== -- -- Risc5x -- www.OpenCores.Org - November 2001 -- -- -- This library is free software; you can distribute it and/or modify it -- under the terms of the GNU Lesser General Public License as published -- by the Free Software Foundation; either version 2.1 of the License, or -- (at your option) any later version. -- -- This library is distributed in the hope that it will be useful, but -- WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -- See the GNU Lesser General Public License for more details. -- -- A RISC CPU core. -- -- (c) Mike Johnson 2001. All Rights Reserved. -- mikej@o... for support or any other issues. -- -- Revision list -- -- version 1.0 initial opencores release -- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; -- -- op <= A +/- B or A -- entity ADD_SUB is generic ( WIDTH : in natural := 8 ); port ( A : in std_logic_vector(WIDTH-1 downto 0); B : in std_logic_vector(WIDTH-1 downto 0); ADD_OR_SUB : in std_logic; -- high for DOUT <= A +/- B, low for DOUT <= A DO_SUB : in std_logic; -- high for DOUT <= A - B, low for DOUT <= A + B CARRY_OUT : out std_logic_vector(WIDTH-1 downto 0); DOUT : out std_logic_vector(WIDTH-1 downto 0) ); end; use work.pkg_xilinx_prims.all; library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; architecture VIRTEX of ADD_SUB is signal lut_op : std_logic_vector(WIDTH-1 downto 0); signal mult_and_op : std_logic_vector(WIDTH-1 downto 0); signal carry : std_logic_vector(WIDTH downto 0); signal op_int : std_logic_vector(WIDTH-1 downto 0); function loc(i : integer) return integer is begin return (((WIDTH+1)/2)-1) - i/2; end loc; begin carry(0) <= DO_SUB; INST : for i in 0 to WIDTH-1 generate attribute RLOC of u_lut : label is "R" & integer'image(loc(i)) & "C0.S1"; attribute RLOC of u_1 : label is "R" & integer'image(loc(i)) & "C0.S1"; attribute RLOC of u_2 : label is "R" & integer'image(loc(i)) & "C0.S1"; attribute RLOC of u_3 : label is "R" & integer'image(loc(i)) & "C0.S1"; attribute INIT of u_lut : label is "C66C"; begin u_lut : LUT4 --pragma translate_off generic map ( INIT => str2slv(u_lut'INIT) ) --pragma translate_on port map ( I0 => ADD_OR_SUB, I1 => A(i), I2 => B(i),
I3 => DO_SUB,
O => lut_op(i)
);
u_1 : MULT_AND
port map (
I0 => ADD_OR_SUB,
I1 => A(i),
LO => mult_and_op(i)
);
u_2 : MUXCY
port map (
DI => mult_and_op(i),
CI => carry(i),
S => lut_op(i),
O => carry(i+1)
);
u_3 : XORCY
port map (
LI => lut_op(i),
CI => carry(i),
O => op_int(i)
);
end generate;
CARRY_OUT <= carry(WIDTH downto 1);
DOUT <= op_int;
end Virtex;
--pragma translate_off
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
architecture RTL of ADD_SUB is
signal a_plus_b : std_logic_vector(9 downto 0) := (others => '0');
signal a_minus_b : std_logic_vector(9 downto 0) := (others => '0');
begin -- architecture
p_addsub_comb : process(A,B,a_plus_b,a_minus_b)
begin
a_plus_b(4 downto 0) <= ('0' & A(3 downto 0)) + ('0' & B(3 downto 0));
a_plus_b(9 downto 5) <= ('0' & A(7 downto 4)) + ('0' & B(7 downto 4)) + ("0000" & a_plus_b(4));
a_minus_b(4 downto 0) <= ('0' & A(3 downto 0)) - ('0' & B(3 downto 0));
a_minus_b(9 downto 5) <= ('0' & A(7 downto 4)) - ('0' & B(7 downto 4)) - ("0000" & a_minus_b(4));
end process;
p_add_sub_comb : process(A,B,ADD_OR_SUB,DO_SUB,a_minus_b,a_plus_b)
begin
DOUT <= A;
CARRY_OUT <= (others => '0');
if (ADD_OR_SUB = '1') then
if (DO_SUB = '1') then
DOUT <= a_minus_b(8 downto 5) & a_minus_b(3 downto 0);
CARRY_OUT(7) <= not a_minus_b(9);
CARRY_OUT(3) <= not a_minus_b(4);
else
DOUT <= a_plus_b(8 downto 5) & a_plus_b(3 downto 0);
CARRY_OUT(7) <= a_plus_b(9);
CARRY_OUT(3) <= a_plus_b(4);
end if;
end if;
end process;
end RTL;
--pragma translate_on
1.1 risc5x/alu.vhd
http://www.opencores.org/cvsweb.shtml/risc5x/alu.vhd?rev=1.1&content-type=text/x-cvsweb-markup
Index: alu.vhd
===================================================================
--
-- Risc5x
-- www.OpenCores.Org - November 2001
--
--
-- This library is free software; you can distribute it and/or modify it
-- under the terms of the GNU Lesser General Public License as published
-- by the Free Software Foundation; either version 2.1 of the License, or
-- (at your option) any later version.
--
-- This library is distributed in the hope that it will be useful, but
-- WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-- See the GNU Lesser General Public License for more details.
--
-- A RISC CPU core.
--
-- (c) Mike Johnson 2001. All Rights Reserved.
-- mikej@o... for support or any other issues.
--
-- Revision list
--
-- version 1.0 initial opencores release
--
use work.pkg_prims.all;
use work.pkg_risc5x.all;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity ALU is
port (
ADDSUB : in std_logic_vector(1 downto 0);
BIT : in std_logic_vector(1 downto 0);
SEL : in std_logic_vector(1 downto 0);
A : in std_logic_vector(7 downto 0);
B : in std_logic_vector(7 downto 0);
Y : out std_logic_vector(7 downto 0);
CIN : in std_logic;
COUT : out std_logic;
DCOUT : out std_logic;
ZOUT : out std_logic
);
end;
architecture RTL of ALU is
-- signal definitions
signal add_sub_dout : std_logic_vector(7 downto 0) := (others => '0');
signal add_sub_result : std_logic_vector(8 downto 0) := (others => '0');
signal alubit_dout : std_logic_vector(7 downto 0) := (others => '0');
signal alubit_result : std_logic_vector(8 downto 0) := (others => '0');
signal a_rol : std_logic_vector(8 downto 0) := (others => '0');
signal a_ror : std_logic_vector(8 downto 0) := (others => '0');
signal carry : std_logic_vector(7 downto 0) := (others => '0');
signal alu_result : std_logic_vector(8 downto 0) := (others => '0');
begin -- architecture
u_add_sub : ADD_SUB
generic map (
WIDTH => 8
)
port map (
A => A,
B => B,
ADD_OR_SUB => ADDSUB(1),
DO_SUB => ADDSUB(0),
CARRY_OUT => carry,
DOUT => add_sub_dout
);
add_sub_result <= carry(7) & add_sub_dout(7 downto 0);
a_ror <= A(0) & CIN & A(7 downto 1);
a_rol <= A(7) & A(6 downto 0) & CIN;
u_alubit : ALUBIT
generic map (
WIDTH => 8
)
port map (
A => A,
B => B,
OP => BIT,
DOUT => alubit_dout
);
alubit_result <= '0' & alubit_dout;
u_mux4 : MUX4
generic map (
WIDTH => 9,
SLICE => 0,
OP_REG => FALSE
)
port map (
DIN3 => a_rol,
DIN2 => a_ror,
DIN1 => alubit_result,
DIN0 => add_sub_result,
SEL => SEL,
ENA => '0',
CLK => '0',
DOUT => alu_result
);
p_zout_comb : process(alu_result)
begin
ZOUT <= '0';
if (alu_result(7 downto 0) = "00000000") then ZOUT <= '1'; end if;
end process;
COUT <= alu_result(8);
DCOUT <= carry(3);
Y <= alu_result(7 downto 0);
end rtl;
1.1 risc5x/alubit.vhd
http://www.opencores.org/cvsweb.shtml/risc5x/alubit.vhd?rev=1.1&content-type=text/x-cvsweb-markup
Index: alubit.vhd
===================================================================
--
-- Risc5x
-- www.OpenCores.Org - November 2001
--
--
-- This library is free software; you can distribute it and/or modify it
-- under the terms of the GNU Lesser General Public License as published
-- by the Free Software Foundation; either version 2.1 of the License, or
-- (at your option) any later version.
--
-- This library is distributed in the hope that it will be useful, but
-- WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-- See the GNU Lesser General Public License for more details.
--
-- A RISC CPU core.
--
-- (c) Mike Johnson 2001. All Rights Reserved.
-- mikej@o... for support or any other issues.
--
-- Revision list
--
-- version 1.0 initial opencores release
--
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity ALUBIT is
generic (
WIDTH : in natural := 8
);
port (
A : in std_logic_vector(WIDTH-1 downto 0);
B : in std_logic_vector(WIDTH-1 downto 0);
OP : in std_logic_vector(1 downto 0);
DOUT : out std_logic_vector(WIDTH-1 downto 0)
);
end;
--
-- USE THIS ARCHITECTURE FOR XILINX
--
use work.pkg_xilinx_prims.all;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
architecture VIRTEX of ALUBIT is
function loc(i : integer) return integer is
begin
return (((WIDTH+1)/2)-1) - i/2;
end loc;
begin -- architecture
ram_bit : for i in 0 to WIDTH-1 generate
attribute RLOC of u_lut : label is "R" & integer'image(loc(i)) & "C0.S1";
attribute INIT of u_lut : label is "56E8";
begin
u_lut: LUT4
--pragma translate_off
generic map (
INIT => str2slv(u_lut'INIT)
)
--pragma translate_on
port map (
I0 => A(i),
I1 => B(i),
I2 => OP(0),
I3 => OP(1),
O => DOUT(i));
end generate;
end VIRTEX;
--pragma translate_off
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
architecture RTL of ALUBIT is
begin -- architecture
p_bit_comb : process(A,B,OP)
begin
DOUT <= (others => '0');
case OP is
when "00" => DOUT <= (A and B);
when "01" => DOUT <= (A or B);
when "10" => DOUT <= (A xor B);
when "11" => DOUT <= ( not A);
when others => null;
end case;
end process;
end RTL;
--pragma translate_on
1.1 risc5x/cpu.vhd
http://www.opencores.org/cvsweb.shtml/risc5x/cpu.vhd?rev=1.1&content-type=text/x-cvsweb-markup
Index: cpu.vhd
===================================================================
--
-- Risc5x
-- www.OpenCores.Org - November 2001
--
--
-- This library is free software; you can distribute it and/or modify it
-- under the terms of the GNU Lesser General Public License as published
-- by the Free Software Foundation; either version 2.1 of the License, or
-- (at your option) any later version.
--
-- This library is distributed in the hope that it will be useful, but
-- WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-- See the GNU Lesser General Public License for more details.
--
-- A RISC CPU core.
--
-- (c) Mike Johnson 2001. All Rights Reserved.
-- mikej@o... for support or any other issues.
--
-- Revision list
--
-- version 1.1 bug fix: Used wrong bank select bits in direct addressing mode
-- INDF register returns 0 when indirectly read
-- FSR bit 8 always set
-- version 1.0 initial opencores release
--
use work.pkg_risc5x.all;
use work.pkg_prims.all;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity CPU is
port (
PADDR : out std_logic_vector(10 downto 0);
PDATA : in std_logic_vector(11 downto 0);
PORTA_IN : in std_logic_vector(7 downto 0);
PORTA_OUT : out std_logic_vector(7 downto 0);
PORTA_OE_L : out std_logic_vector(7 downto 0);
PORTB_IN : in std_logic_vector(7 downto 0);
PORTB_OUT : out std_logic_vector(7 downto 0);
PORTB_OE_L : out std_logic_vector(7 downto 0);
PORTC_IN : in std_logic_vector(7 downto 0);
PORTC_OUT : out std_logic_vector(7 downto 0);
PORTC_OE_L : out std_logic_vector(7 downto 0);
DEBUG_W : out std_logic_vector(7 downto 0);
DEBUG_PC : out std_logic_vector(10 downto 0);
DEBUG_INST : out std_logic_vector(11 downto 0);
DEBUG_STATUS : out std_logic_vector(7 downto 0);
RESET : in std_logic;
CLK : in std_logic
);
end;
architecture RTL of CPU is
-- component definitions
component IDEC is
port (
INST : in std_logic_vector(11 downto 0);
ALU_ASEL : out std_logic_vector(1 downto 0);
ALU_BSEL : out std_logic_vector(1 downto 0);
ALU_ADDSUB : out std_logic_vector(1 downto 0);
ALU_BIT : out std_logic_vector(1 downto 0);
ALU_SEL : out std_logic_vector(1 downto 0);
WWE_OP : out std_logic;
FWE_OP : out std_logic;
ZWE : out std_logic;
DCWE : out std_logic;
CWE : out std_logic;
BDPOL : out std_logic;
OPTION : out std_logic;
TRIS : out std_logic
);
end component;
component ALU is
port (
ADDSUB : in std_logic_vector(1 downto 0);
BIT : in std_logic_vector(1 downto 0);
SEL : in std_logic_vector(1 downto 0);
A : in std_logic_vector(7 downto 0);
B : in std_logic_vector(7 downto 0);
Y : out std_logic_vector(7 downto 0);
CIN : in std_logic;
COUT : out std_logic;
DCOUT : out std_logic;
ZOUT : out std_logic
);
end component;
component REGS is
port (
WE : in std_logic;
RE : in std_logic;
BANK : in std_logic_vector(1 downto 0);
LOCATION : in std_logic_vector(4 downto 0);
DIN : in std_logic_vector(7 downto 0);
DOUT : out std_logic_vector(7 downto 0);
RESET : in std_logic;
CLK : in std_logic
);
end component;
-- type/constant definitions
constant STATUS_RESET_VALUE : std_logic_vector(7 downto 0) := x"18";
constant OPTION_RESET_VALUE : std_logic_vector(7 downto 0) := x"3F";
constant INDF_ADDR : std_logic_vector(2 downto 0) := "000";
constant TMR0_ADDR : std_logic_vector(2 downto 0) := "001";
constant PCL_ADDR : std_logic_vector(2 downto 0) := "010";
constant STATUS_ADDR : std_logic_vector(2 downto 0) := "011";
constant FSR_ADDR : std_logic_vector(2 downto 0) := "100";
constant PORTA_ADDR : std_logic_vector(2 downto 0) := "101";
constant PORTB_ADDR : std_logic_vector(2 downto 0) := "110";
constant PORTC_ADDR : std_logic_vector(2 downto 0) := "111";
-- signal definitions
signal inst : std_logic_vector(11 downto 0);
signal inst_k : std_logic_vector(7 downto 0);
signal inst_fsel : std_logic_vector(4 downto 0);
signal inst_d : std_logic;
signal inst_b : std_logic_vector(2 downto 0);
signal pc,next_pc : std_logic_vector(10 downto 0);
signal pc_load_stack : std_logic_vector(10 downto 0);
signal pc_write : std_logic_vector(10 downto 0);
signal pc_call : std_logic_vector(10 downto 0);
signal pc_goto : std_logic_vector(10 downto 0);
signal pc_load : std_logic_vector(10 downto 0);
signal pc_load_sel : std_logic_vector(1 downto 0);
signal pc_inc : std_logic;
signal stacklevel : std_logic_vector(1 downto 0);
signal stack1,stack2 : std_logic_vector(10 downto 0);
signal w_reg,status,fsr,tmr0 : std_logic_vector(7 downto 0);
signal prescaler,option : std_logic_vector(7 downto 0);
signal trisa,trisb,trisc : std_logic_vector(7 downto 0);
signal porta_dout : std_logic_vector(7 downto 0);
signal portb_dout : std_logic_vector(7 downto 0);
signal portc_dout : std_logic_vector(7 downto 0);
signal porta_din : std_logic_vector(7 downto 0);
signal portb_din : std_logic_vector(7 downto 0);
signal portc_din : std_logic_vector(7 downto 0);
signal dbus,sbus : std_logic_vector(7 downto 0);
signal sbus_swap : std_logic_vector(7 downto 0);
signal sbus_mux_out : std_logic_vector(7 downto 0);
-- inst decode
signal regfile_sel,special_sel : std_logic;
signal fileaddr_indirect : std_logic;
signal fileaddr_mux1 : std_logic_vector(6 downto 0);
signal fileaddr_mux0 : std_logic_vector(6 downto 0);
signal istris,isoption : std_logic;
signal fwe,wwe,zwe,dcwe,cwe : std_logic;
signal bdpol : std_logic;
signal bd : std_logic_vector(7 downto 0);
signal skip : std_logic;
-- alu
signal alu_asel,alu_bsel : std_logic_vector(1 downto 0) := (others => '0');
signal alu_addsub : std_logic_vector(1 downto 0) := (others => '0');
signal alu_bit : std_logic_vector(1 downto 0) := (others => '0');
signal alu_sel : std_logic_vector(1 downto 0) := (others => '0');
signal alu_z,alu_dcout,alu_cout : std_logic := '0';
signal alu_a,alu_b : std_logic_vector(7 downto 0) := (others => '0');
signal alu_out : std_logic_vector(7 downto 0);
signal regfile_we,regfile_re : std_logic;
signal regfile_in,regfile_out : std_logic_vector(7 downto 0);
signal fileaddr : std_logic_vector(6 downto 0);
begin -- architecture
u_idec : IDEC
port map (
INST => inst,
ALU_ASEL => alu_asel,
ALU_BSEL => alu_bsel,
ALU_ADDSUB => alu_addsub,
ALU_BIT => alu_bit,
ALU_SEL => alu_sel,
WWE_OP => wwe,
FWE_OP => fwe,
ZWE => zwe,
DCWE => dcwe,
CWE => cwe,
BDPOL => bdpol,
OPTION => isoption,
TRIS => istris
);
u_alu : ALU
port map (
ADDSUB => alu_addsub,
BIT => alu_bit,
SEL => alu_sel,
A => alu_a,
B => alu_b,
Y => alu_out,
CIN => status(0),
COUT => alu_cout,
DCOUT => alu_dcout,
ZOUT => alu_z
);
u_regs : REGS
port map (
WE => regfile_we,
RE => regfile_re,
BANK => fileaddr(6 downto 5),
LOCATION => fileaddr(4 downto 0),
DIN => regfile_in,
DOUT => regfile_out,
RESET => RESET,
CLK => CLK
);
DEBUG_W <= w_reg;
DEBUG_PC <= pc(10 downto 0);
DEBUG_INST <= inst;
DEBUG_STATUS <= status;
-- *********** REGISTER FILE Addressing ****************
p_addr_dec_comb : process(inst_fsel,fsr)
begin
if (inst_fsel = ("00" & INDF_ADDR)) then
fileaddr_indirect <= '1';
else
fileaddr_indirect <= '0';
end if;
fileaddr_mux1 <= fsr(6 downto 0);
fileaddr_mux0 <= (fsr(6 downto 5) & inst_fsel);
end process;
fileaddr_mux : MUX2
generic map (
WIDTH => 7,
SLICE => 1,
OP_REG => FALSE
)
port map (
DIN1 => fileaddr_mux1,
DIN0 => fileaddr_mux0,
SEL => fileaddr_indirect,
ENA => '0', -- not used
CLK => '0', -- not used
DOUT => fileaddr
);
p_regfile_we_comb : process(regfile_sel,fwe,alu_asel,alu_bsel)
begin
regfile_we <= regfile_sel and fwe;
regfile_re <= '1'; -- not used
end process;
p_fileaddr_dec_comb : process(fileaddr,isoption,istris)
begin
regfile_sel <= '1'; -- everything else;
special_sel <= '0';
if (fileaddr(4 downto 3) = "00") and (isoption = '0') and (istris = '0') then
special_sel <= '1'; -- lower 8 addresses in ALL BANKS 1 lut
end if;
end process;
sbus_muxa : MUX8
generic map (
WIDTH => 8,
OP_REG => FALSE
)
port map (
DIN7 => portc_din,
DIN6 => portb_din,
DIN5 => porta_din,
DIN4 => fsr,
DIN3 => status,
DIN2 => pc(7 downto 0),
DIN1 => tmr0,
DIN0 => x"00", -- INDF returns 0
SEL => inst_fsel(2 downto 0),
ENA => '0',
CLK => '0',
DOUT => sbus_mux_out
);
sbus_muxb : MUX2
generic map (
WIDTH => 8,
SLICE => 1,
OP_REG => FALSE
)
port map (
DIN1 => sbus_mux_out,
DIN0 => regfile_out,
SEL => special_sel,
ENA => '0',
CLK => '0',
DOUT => sbus
);
p_dbus_comb : process(alu_out)
begin
dbus <= alu_out;
regfile_in <= alu_out;
end process;
p_paddr_comb : process(next_pc)
begin
PADDR <= next_pc(10 downto 0);
end process;
p_inst_assign_comb : process(inst)
begin
inst_k <= inst(7 downto 0);
inst_fsel <= inst(4 downto 0);
inst_d <= inst(5);
inst_b <= inst(7 downto 5);
end process;
p_bdec_assign_comb : process(inst_b,bdpol)
variable bdec : std_logic_vector(7 downto 0);
begin
-- 1 lut
bdec := "00000001";
case inst_b is
when "000" => bdec := "00000001";
when "001" => bdec := "00000010";
when "010" => bdec := "00000100";
when "011" => bdec := "00001000";
when "100" => bdec := "00010000";
when "101" => bdec := "00100000";
when "110" => bdec := "01000000";
when "111" => bdec := "10000000";
when others => null;
end case;
if (bdpol = '1') then
bd <= not bdec;
else
bd <= bdec;
end if;
end process;
p_inst : process(CLK,RESET)
begin
if (RESET = '1') then
inst <= x"000";
elsif CLK'event and (CLK = '1') then
if (skip = '1') then
inst <= x"000"; -- force NOP
else
inst <= PDATA;
end if;
end if;
end process;
p_skip_comb : process(inst,alu_z,fwe,special_sel,fileaddr)
begin
-- SKIP signal.
-- We want to insert the NOP instruction for the following conditions:
-- we have modified PCL
-- GOTO,CALL and RETLW instructions
-- BTFSS instruction when aluz is HI
-- BTFSC instruction when aluz is LO
skip <= '0';
if (fwe = '1') and (special_sel = '1') and (fileaddr(2 downto 0) = PCL_ADDR) then skip <= '1'; end if;
if (inst(11 downto 10) = "10") then skip <= '1'; end if;
if (inst(11 downto 8) = "0110") and (alu_z = '1') then skip <= '1'; end if; -- BTFSC
if (inst(11 downto 8) = "0111") and (alu_z = '0') then skip <= '1'; end if; -- BTFSS
if (inst(11 downto 6) = "001011") and (alu_z = '1') then skip <= '1'; end if; -- DECFSZ
if (inst(11 downto 6) = "001111") and (alu_z = '1') then skip <= '1'; end if; -- INCFSZ
end process;
sbus_swap <= sbus(3 downto 0) & sbus(7 downto 4);
alua_mux : MUX4
generic map (
WIDTH => 8,
SLICE => 1,
OP_REG => FALSE
)
port map (
DIN3 => sbus_swap,
DIN2 => inst_k,
DIN1 => sbus,
DIN0 => w_reg,
SEL => alu_asel,
ENA => '0',
CLK => '0',
DOUT => alu_a
);
alub_mux : MUX4
generic map (
WIDTH => 8,
SLICE => 0,
OP_REG => FALSE
)
port map (
DIN3 => x"01",
DIN2 => bd,
DIN1 => sbus,
DIN0 => w_reg,
SEL => alu_bsel,
ENA => '0',
CLK => '0',
DOUT => alu_b
);
p_w_reg : process(CLK,RESET)
begin
if (RESET = '1') then
w_reg <= x"00";
elsif CLK'event and (CLK = '1') then
if (wwe = '1') then
w_reg <= dbus;
end if;
end if;
end process;
p_tmr0 : process(CLK,RESET)
variable mask : std_logic_vector(7 downto 0);
begin
if (RESET = '1') then
tmr0 <= x"00";
elsif CLK'event and (CLK = '1') then
-- See if the timer register is actually being written to
if (fwe = '1') and (special_sel = '1') and (fileaddr(2 downto 0) = TMR0_ADDR) then
tmr0 <= dbus;
else
mask := "00000001";
case option(2 downto 0) is
when "000" => mask := "00000001";
when "001" => mask := "00000011";
when "010" => mask := "00000111";
when "011" => mask := "00001111";
when "100" => mask := "00011111";
when "101" => mask := "00111111";
when "110" => mask := "01111111";
when "111" => mask := "11111111";
when others => null;
end case;
if ((prescaler and mask) = "00000000") or (option(3) = '1') then
tmr0 <= tmr0 + "1";
end if;
end if;
end if;
end process;
p_prescaler : process(CLK,RESET)
begin
if (RESET = '1') then
prescaler <= x"00";
elsif CLK'event and (CLK = '1') then
if not (option(5) = '1') then
prescaler <= prescaler + "1";
end if;
end if;
end process;
p_status_reg : process(CLK,RESET)
variable new_z,new_dc,new_c : std_logic;
begin
if (RESET = '1') then
status <= STATUS_RESET_VALUE;
elsif CLK'event and (CLK = '1') then
-- See if the status register is actually being written to
-- this is not accurate, bits 4 & 3 should be read only
-- additionally, zwe,cwe and dcwe should override fwe
if (fwe = '1') and (special_sel = '1') and (fileaddr(2 downto 0) = STATUS_ADDR) then
status <= dbus;
else
-- For the carry and zero flags, each instruction has its own rule as
-- to whether to update this flag or not. The instruction decoder is
-- providing us with an enable for C and Z. Use this to decide whether
-- to retain the existing value, or update with the new alu status output.
if (zwe = '1') then new_z := alu_z; else new_z := status(2); end if;
if (dcwe = '1') then new_dc := alu_dcout; else new_dc := status(1); end if;
if (cwe = '1') then new_c := alu_cout; else new_c := status(0); end if;
status <= (
status(7) & -- BIT 7: Undefined.. (maybe use for debugging)
status(6) & -- BIT 6: Program Page, HI bit
status(5) & -- BIT 5: Program Page, LO bit
status(4) & -- BIT 4: Time Out bit (not implemented at this time)
status(3) & -- BIT 3: Power Down bit (not implemented at this time)
new_z & -- BIT 2: Z
new_dc & -- BIT 1: DC
new_c); -- BIT 0: C
end if;
end if;
end process;
p_fsr_reg : process(CLK,RESET)
begin
if (RESET = '1') then
fsr <= x"80";
elsif CLK'event and (CLK = '1') then
if (fwe = '1') and (special_sel = '1') and (fileaddr(2 downto 0) = FSR_ADDR) then
fsr <= dbus;
end if;
fsr(7) <= '1'; --always set in real chip
end if;
end process;
p_option_reg : process(CLK,RESET)
begin
if (RESET = '1') then
option <= OPTION_RESET_VALUE;
elsif CLK'event and (CLK = '1') then
if (isoption = '1') then
option <= dbus;
end if;
end if;
end process;
p_drive_ports_comb : process(porta_dout,trisa,portb_dout,trisb,portc_dout,trisc)
begin
PORTA_OE_L <= trisa;
PORTB_OE_L <= trisb;
PORTC_OE_L <= trisc;
PORTA_OUT <= porta_dout;
PORTB_OUT <= portb_dout;
PORTC_OUT <= portc_dout;
end process;
port_in : process(CLK,RESET,PORTA_IN,PORTB_IN,PORTC_IN)
begin
-- the input registers don't exist in the real device,
-- so if you read an output we have introduced a clock delay.
if (RESET = '1') then
porta_din <= (others => '0');
portb_din <= (others => '0');
portc_din <= (others => '0');
elsif CLK'event and (CLK = '1') then -- comment this out for combinatorial ip
--else -- or comment this for registered ip
porta_din <= PORTA_IN;
portb_din <= PORTB_IN;
portc_din <= PORTC_IN;
end if;
end process;
p_port_reg : process(CLK,RESET)
begin
if (RESET = '1') then
trisa <= x"FF"; -- default tristate
trisb <= x"FF"; -- default tristate
trisc <= x"FF"; -- default tristate
porta_dout <= x"00";
portb_dout <= x"00";
portc_dout <= x"00";
elsif CLK'event and (CLK = '1') then
if (fwe = '1') and (fileaddr(2 downto 0) = PORTA_ADDR) then
if (istris = '0') and (special_sel = '1') then
porta_dout <= dbus;
elsif (istris = '1') then
trisa <= dbus;
end if;
end if;
if (fwe = '1') and (fileaddr(2 downto 0) = PORTB_ADDR) then
if (istris = '0') and (special_sel = '1') then
portb_dout <= dbus;
elsif (istris = '1') then
trisb <= dbus;
end if;
end if;
if (fwe = '1') and (fileaddr(2 downto 0) = PORTC_ADDR) then
if (istris = '0') and (special_sel = '1') then
portc_dout <= dbus;
elsif (istris = '1') then
trisc <= dbus;
end if;
end if;
end if;
end process;
-- ********** PC AND STACK *************************
p_next_pc_comb : process(pc,inst,status,stacklevel,stack1,stack2,dbus,fileaddr,special_sel,fwe)
begin
pc_goto <= ( status(6 downto 5) & inst(8 downto 0));
pc_call <= ( status(6 downto 5) & '0' & inst(7 downto 0));
pc_write <= (pc(10) & '0' & pc(8) & dbus); -- set bit 9 to zero
pc_inc <= '1'; -- default
pc_load_sel <= "00"; -- pc write
if (fwe = '1') and (special_sel = '1') and (fileaddr(2 downto 0) = PCL_ADDR) then
--pc_load_sel <= "00"; default
pc_inc <= '0'; -- as we have modified next_pc, must skip next instruction
end if;
if (inst(11 downto 9) = "101") then pc_load_sel <= "01"; pc_inc <= '0'; end if; -- goto
if (inst(11 downto 8) = "1001") then pc_load_sel <= "10"; pc_inc <= '0'; end if; -- call
if (inst(11 downto 8) = "1000") then pc_load_sel <= "11"; pc_inc <= '0'; end if; -- ret
end process;
pc_load_mux : MUX4
generic map (
WIDTH => 11,
SLICE => 0,
OP_REG => FALSE
)
port map (
DIN3 => pc_load_stack,
DIN2 => pc_call,
DIN1 => pc_goto,
DIN0 => pc_write,
SEL => pc_load_sel,
ENA => '0',
CLK => '0',
DOUT => pc_load
);
pc_mux2_add_reg : MUX2_ADD_REG
generic map (
WIDTH => 11
)
port map (
ADD_VAL => "00000000001", -- pc = pc + 1
LOAD_VAL => pc_load, -- branch
ADD => pc_inc,
PRESET => RESET,
ENA => '1',
CLK => CLK,
DOUT => next_pc,
REG_DOUT => pc
);
p_stack_comb : process(stacklevel,stack1,stack2)
begin
pc_load_stack <= stack1; -- default
case stacklevel is
when "00" => pc_load_stack <= stack1;
when "01" => pc_load_stack <= stack1;
when "10" => pc_load_stack <= stack2;
when "11" => pc_load_stack <= stack2;
when others => null;
end case;
end process;
p_stack_reg : process(CLK,RESET)
begin
if (RESET = '1') then
stack1 <= (others => '0');
stack2 <= (others => '0');
elsif CLK'event and (CLK = '1') then
if (inst(11 downto 8) = "1001") then
case stacklevel is
when "00" => stack1 <= pc(10 downto 0);
when "01" => stack2 <= pc(10 downto 0);
when "10" => assert false report "Too many CALLs !" severity failure;
when "11" => assert false report "Too many CALLs !" severity failure;
when others => null;
end case;
end if;
end if;
end process;
p_stack_level : process(CLK,RESET)
begin
if (RESET = '1') then
stacklevel <= "00";
elsif CLK'event and (CLK = '1') then
stacklevel <= stacklevel;
if (inst(11 downto 8) = "1001") then
case stacklevel is
when "00" => stacklevel <="01"; -- 1st call
when "01" => stacklevel <="10"; -- 2nd call
when "10" => stacklevel <="10"; -- already 2, ignore
when "11" => stacklevel <="00"; -- broke
when others => null;
end case;
elsif (inst(11 downto 8) = "1000") then
case stacklevel is
when "00" => stacklevel <="00"; -- broke
when "01" => stacklevel <="00"; -- go back to no call
when "10" => stacklevel <="01"; -- go back to 1 call
when "11" => stacklevel <="10"; -- broke
when others => null;
end case;
end if;
end if;
end process;
end rtl;
1.1 risc5x/cpu_tb.vhd
http://www.opencores.org/cvsweb.shtml/risc5x/cpu_tb.vhd?rev=1.1&content-type=text/x-cvsweb-markup
Index: cpu_tb.vhd
===================================================================
--
-- Risc5x
-- www.OpenCores.Org - November 2001
--
--
-- This library is free software; you can distribute it and/or modify it
-- under the terms of the GNU Lesser General Public License as published
-- by the Free Software Foundation; either version 2.1 of the License, or
-- (at your option) any later version.
--
-- This library is distributed in the hope that it will be useful, but
-- WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-- See the GNU Lesser General Public License for more details.
--
-- A RISC CPU core.
--
-- (c) Mike Johnson 2001. All Rights Reserved.
-- mikej@o... for support or any other issues.
--
-- Revision list
--
-- version 1.0 initial opencores release
--
-- NOTE THIS JUST A TOP LEVEL TEST BENCH
use work.pkg_risc5x.all;
use std.textio.ALL;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity cpu_tb is
end;
architecture Sim of cpu_tb is
signal clk : std_logic;
signal reset : std_logic := '1';
signal paddr : std_logic_vector(10 downto 0);
signal pdata : std_logic_vector(11 downto 0) := (others => '0');
signal porta_in : std_logic_vector(7 downto 0);
signal porta_out : std_logic_vector(7 downto 0);
signal porta_oe_l : std_logic_vector(7 downto 0);
signal portb_in : std_logic_vector(7 downto 0);
signal portb_out : std_logic_vector(7 downto 0);
signal portb_oe_l : std_logic_vector(7 downto 0);
signal portc_in : std_logic_vector(7 downto 0);
signal portc_out : std_logic_vector(7 downto 0);
signal portc_oe_l : std_logic_vector(7 downto 0);
signal porta_io : std_logic_vector(7 downto 0) := (others => 'H');
signal portb_io : std_logic_vector(7 downto 0) := (others => 'H');
signal portc_io : std_logic_vector(7 downto 0) := (others => 'H');
signal debug_w : std_logic_vector(7 downto 0);
signal debug_pc : std_logic_vector(10 downto 0);
signal debug_inst : std_logic_vector(11 downto 0);
signal debug_status : std_logic_vector(7 downto 0);
signal test_addr, test_val : integer;
signal inst_string : string(8 downto 1);
signal pc_t1 : std_logic_vector(10 downto 0);
signal cnt : std_logic_vector(7 downto 0) := (others => '0');
constant cDelay : time := 5 ns;
constant ClkPeriod : time := 20 ns;
constant filename : string := "JUMPTEST.HEX";
constant nwords : integer := 2 ** 11;
type ram_type is array (0 to nwords-1) of std_logic_vector(11 downto 0);
shared variable ram :ram_type := (others => (others => '0'));
component CPU is
port (
PADDR : out std_logic_vector(10 downto 0);
PDATA : in std_logic_vector(11 downto 0);
PORTA_IN : in std_logic_vector(7 downto 0);
PORTA_OUT : out std_logic_vector(7 downto 0);
PORTA_OE_L : out std_logic_vector(7 downto 0);
PORTB_IN : in std_logic_vector(7 downto 0);
PORTB_OUT : out std_logic_vector(7 downto 0);
PORTB_OE_L : out std_logic_vector(7 downto 0);
PORTC_IN : in std_logic_vector(7 downto 0);
PORTC_OUT : out std_logic_vector(7 downto 0);
PORTC_OE_L : out std_logic_vector(7 downto 0);
DEBUG_W : out std_logic_vector(7 downto 0);
DEBUG_PC : out std_logic_vector(10 downto 0);
DEBUG_INST : out std_logic_vector(11 downto 0);
DEBUG_STATUS : out std_logic_vector(7 downto 0);
RESET : in std_logic;
CLK : in std_logic
);
end component;
begin
u0 : CPU
port map (
PADDR => paddr,
PDATA => pdata,
PORTA_IN => porta_in,
PORTA_OUT => porta_out,
PORTA_OE_L => porta_oe_l,
PORTB_IN => portb_in,
PORTB_OUT => portb_out,
PORTB_OE_L => portb_oe_l,
PORTC_IN => portc_in,
PORTC_OUT => portc_out,
PORTC_OE_L => portc_oe_l,
DEBUG_W => debug_w,
DEBUG_PC => debug_pc,
DEBUG_INST => debug_inst,
DEBUG_STATUS => debug_status,
RESET => reset,
CLK => clk
);
p_drive_ports_out_comb : process(porta_out,porta_oe_l,portb_out,portb_oe_l,portc_out,portc_oe_l)
begin
for i in 0 to 7 loop
if (porta_oe_l(i) = '0') then
porta_io(i) <= porta_out(i);
else
porta_io(i) <= 'Z';
end if;
if (portb_oe_l(i) = '0') then
portb_io(i) <= portb_out(i);
else
portb_io(i) <= 'Z';
end if;
if (portc_oe_l(i) = '0') then
portc_io(i) <= portc_out(i);
else
portc_io(i) <= 'Z';
end if;
end loop;
end process;
p_pullup : process(porta_io,portb_io,portc_io)
begin
-- stop unknowns in simulation
porta_io <= (others => 'H');
portb_io <= (others => 'H');
portc_io <= (others => 'H');
end process;
p_drive_ports_in_comb : process(porta_io,portb_io,portc_io)
begin
porta_in <= porta_io;
portb_in <= portb_io;
portc_in <= portc_io;
end process;
p_clks : process
begin
CLK <= '0';
wait for ClkPeriod / 2;
CLK <= '1';
wait for ClkPeriod / 2;
end process;
p_prom : process (RESET,CLK)
begin
if (RESET = '1') then
pdata <= (others=>'0');
elsif CLK'event and (CLK ='1') then
pdata <= ram(slv_to_integer(paddr));
end if;
end process;
p_pc : process
begin
wait until CLK'event and (CLK = '1');
pc_t1 <= debug_pc;
end process;
p_drive_a : process
begin
porta_io <= x"02";
wait for ClkPeriod * 50;
porta_io <= x"03";
wait for ClkPeriod * 50;
end process;
p_cpu_top : process
begin
reset <= '1';
wait until CLK'event and CLK = '1';
reset <= '0' after 100 ns;
wait;
end process;
p_readhex : process
function digit_value(c : character) return integer is
begin
if (c >= '0') and (c <= '9') then
return (character'pos(c) - character'pos('0'));
elsif (c >= 'a') and (c <= 'f') THEN
return (character'pos(c) - character'pos('a') + 10);
elsif (c >= 'A') and (c <= 'F') THEN
return (character'pos(c) - character'pos('A') + 10);
else
assert false report "ERROR IN HEX FILE !!" severity note;
return 999;
end if;
end;
file hex_file : TEXT open read_mode is filename;
variable l : line;
variable val, pos : integer := 0;
variable numbytes,addr,ltype : integer := 0;
variable ram_data : std_logic_vector(11 downto 0);
begin
assert false report "Loading hex file" & filename severity note;
while not endfile (hex_file) loop
readline (hex_file, l);
if l'left > l'right then next; end if; -- ignore blanks
--hex file format
--BBAAAATT HH CC
--BB number of HH's, AAAA addr, TT 00 - data (ignore others), CC - checksum
--skip any spaces or :'s
pos := l'low;
for i in l'low TO l'high loop
case l(i) IS
when ' ' | ':' | ht => pos := i + 1;
when others => exit;
end case;
end loop;
numbytes := digit_value(l(pos)) * 16;
numbytes := numbytes + digit_value(l(pos + 1));
addr := digit_value(l(pos+2)) * 16 * 16 * 16;
addr := addr + digit_value(l(pos + 3)) * 16 * 16;
addr := addr + digit_value(l(pos + 4)) * 16;
addr := addr + digit_value(l(pos + 5)) ;
addr := addr /2; -- word address
ltype := digit_value(l(pos+6)) * 16;
ltype := ltype + digit_value(l(pos+7));
if not (ltype = 0) then next; end if;
pos := pos + 8;
for i in 1 to (numbytes/2) loop
val := digit_value(l(pos)) * 16;
val := val + digit_value(l(pos + 1));
val := val + digit_value(l(pos + 2)) * 16 * 16 * 16;
val := val + digit_value(l(pos + 3)) * 16 * 16;
test_val <= val;
test_addr <= addr;
if (addr > nwords-1) then assert false report "ADDRESS TOO BIG !!";
report "(have you included the configuration bits ??)"
severity failure; exit;
end if;
if (val > (2**12)-1) then assert false report "DATA TOO BIG !!"
severity failure; exit;
end if;
-- wait for 10 ns; -- debug
ram_data := integer_to_slv(val,12);
ram(addr) := ram_data;
addr := addr + 1;
pos := pos + 4;
end loop;
end loop;
assert false report "Load hex done" severity note;
wait;
end process;
p_debug_comb : process(DEBUG_INST)
begin
inst_string <= "-XXXXXX-";
if DEBUG_INST(11 downto 0) = "000000000000" then inst_string <= "NOP "; end if;
if DEBUG_INST(11 downto 5) = "0000001" then inst_string <= "MOVWF "; end if;
if DEBUG_INST(11 downto 0) = "000001000000" then inst_string <= "CLRW "; end if;
if DEBUG_INST(11 downto 5) = "0000011" then inst_string <= "CLRF "; end if;
if DEBUG_INST(11 downto 6) = "000010" then inst_string <= "SUBWF "; end if;
if DEBUG_INST(11 downto 6) = "000011" then inst_string <= "DECF "; end if;
if DEBUG_INST(11 downto 6) = "000100" then inst_string <= "IORWF "; end if;
if DEBUG_INST(11 downto 6) = "000101" then inst_string <= "ANDWF "; end if;
if DEBUG_INST(11 downto 6) = "000110" then inst_string <= "XORWF "; end if;
if DEBUG_INST(11 downto 6) = "000111" then inst_string <= "ADDWF "; end if;
if DEBUG_INST(11 downto 6) = "001000" then inst_string <= "MOVF "; end if;
if DEBUG_INST(11 downto 6) = "001001" then inst_string <= "COMF "; end if;
if DEBUG_INST(11 downto 6) = "001010" then inst_string <= "INCF "; end if;
if DEBUG_INST(11 downto 6) = "001011" then inst_string <= "DECFSZ "; end if;
if DEBUG_INST(11 downto 6) = "001100" then inst_string <= "RRF "; end if;
if DEBUG_INST(11 downto 6) = "001101" then inst_string <= "RLF "; end if;
if DEBUG_INST(11 downto 6) = "001110" then inst_string <= "SWAPF "; end if;
if DEBUG_INST(11 downto 6) = "001111" then inst_string <= "INCFSZ "; end if;
-- *** Bit-Oriented File Register Operations
if DEBUG_INST(11 downto 8) = "0100" then inst_string <= "BCF "; end if;
if DEBUG_INST(11 downto 8) = "0101" then inst_string <= "BSF "; end if;
if DEBUG_INST(11 downto 8) = "0110" then inst_string <= "BTFSC "; end if;
if DEBUG_INST(11 downto 8) = "0111" then inst_string <= "BTFSS "; end if;
-- *** Literal and Control Operations
if DEBUG_INST(11 downto 0) = "000000000010" then inst_string <= "OPTION "; end if;
if DEBUG_INST(11 downto 0) = "000000000011" then inst_string <= "SLEEP "; end if;
if DEBUG_INST(11 downto 0) = "000000000100" then inst_string <= "CLRWDT "; end if;
if DEBUG_INST(11 downto 0) = "000000000101" then inst_string <= "TRIS "; end if;
if DEBUG_INST(11 downto 0) = "000000000110" then inst_string <= "TRIS "; end if;
if DEBUG_INST(11 downto 0) = "000000000111" then inst_string <= "TRIS "; end if;
if DEBUG_INST(11 downto 8) = "1000" then inst_string <= "RETLW "; end if;
if DEBUG_INST(11 downto 8) = "1001" then inst_string <= "CALL "; end if;
if DEBUG_INST(11 downto 9) = "101" then inst_string <= "GOTO "; end if;
if DEBUG_INST(11 downto 8) = "1100" then inst_string <= "MOVLW "; end if;
if DEBUG_INST(11 downto 8) = "1101" then inst_string <= "IORLW "; end if;
if DEBUG_INST(11 downto 8) = "1110" then inst_string <= "ANDLW "; end if;
if DEBUG_INST(11 downto 8) = "1111" then inst_string <= "XORLW "; end if;
end process;
end Sim;
1.1 risc5x/idec.vhd
http://www.opencores.org/cvsweb.shtml/risc5x/idec.vhd?rev=1.1&content-type=text/x-cvsweb-markup
Index: idec.vhd
===================================================================
--
-- Risc5x
-- www.OpenCores.Org - November 2001
--
--
-- This library is free software; you can distribute it and/or modify it
-- under the terms of the GNU Lesser General Public License as published
-- by the Free Software Foundation; either version 2.1 of the License, or
-- (at your option) any later version.
--
-- This library is distributed in the hope that it will be useful, but
-- WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-- See the GNU Lesser General Public License for more details.
--
-- A RISC CPU core.
--
-- (c) Mike Johnson 2001. All Rights Reserved.
-- mikej@o... for support or any other issues.
--
-- Revision list
--
-- version 1.0 initial opencores release
--
use work.pkg_risc5x.all;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity IDEC is
port (
INST : in std_logic_vector(11 downto 0);
ALU_ASEL : out std_logic_vector(1 downto 0);
ALU_BSEL : out std_logic_vector(1 downto 0);
ALU_ADDSUB : out std_logic_vector(1 downto 0);
ALU_BIT : out std_logic_vector(1 downto 0);
ALU_SEL : out std_logic_vector(1 downto 0);
WWE_OP : out std_logic;
FWE_OP : out std_logic;
ZWE : out std_logic;
DCWE : out std_logic;
CWE : out std_logic;
BDPOL : out std_logic;
OPTION : out std_logic;
TRIS : out std_logic
);
end;
architecture RTL of IDEC is
-- signal definitions
signal alu : std_logic_vector(9 downto 0) := (others => '0');
signal flags : std_logic_vector(2 downto 0) := (others => '0');
signal fwe : std_logic;
signal wwe : std_logic;
signal we : std_logic;
begin -- architecture
-- aluasel, Select source for ALU A input. 00=W, 01=SBUS, 10=K , 11= SBUS_SWAP
-- alubsel, Select source for ALU B input. 00=W, 01=SBUS, 10=BD, 11= "1"
-- bit 0 : A and B, 1 : A or B, 2 : A xor B, 3 : not A
-- wwe, W register Write Enable
-- fwe, File Register Write Enable
-- zwe, Status register Z bit update
-- dcwe Status register DC bit update
-- cwe, Status register C bit update
-- bdpol, Polarity on bit decode vector (0=no inversion, 1=invert)
-- tris, Instruction is an TRIS instruction
-- option Instruction is an OPTION instruction
p_inst_decode_comb : process(INST)
begin
BDPOL <= '0';
OPTION <= '0';
TRIS <= '0';
alu <= (others => '0');
flags <= (others => '0');
fwe <= '0';
wwe <= '0';
we <= '0';
case INST(11 downto 8) is
when "0000" => --asel bsel +- bit sel
if (INST(7 downto 0) = "00000000") then alu <= "00" & "00" & "00" & "00" & "00"; end if; -- NOP
if (INST(7 downto 0) = "00000010") then alu <= "00" & "00" & "00" & "00" & "00"; fwe <= '1'; OPTION <= '1'; end if; -- OPTION
if (INST(7 downto 0) = "00000011") then alu <= "00" & "00" & "00" & "00" & "00"; end if; -- SLEEP
if (INST(7 downto 0) = "00000100") then alu <= "00" & "00" & "00" & "00" & "00"; end if; -- CLRWDT
if (INST(7 downto 0) = "00000101") then alu <= "00" & "00" & "00" & "00" & "00"; fwe <= '1'; TRIS <= '1'; end if; -- TRIS 5
if (INST(7 downto 0) = "00000110") then alu <= "00" & "00" & "00" & "00" & "00"; fwe <= '1'; TRIS <= '1'; end if; -- TRIS 6
if (INST(7 downto 0) = "00000111") then alu <= "00" & "00" & "00" & "00" & "00"; fwe <= '1'; TRIS <= '1'; end if; -- TRIS 7
if (INST(7 downto 5) = "001" ) then alu <= "00" & "00" & "00" & "00" & "00"; fwe <= '1'; end if; -- MOVWF
if (INST(7 downto 0) = "01000000") then alu <= "00" & "00" & "00" & "10" & "01"; wwe <= '1'; flags <= "100"; end if; -- CLRW
if (INST(7 downto 5) = "011" ) then alu <= "00" & "00" & "00" & "10" & "01"; fwe <= '1'; flags <= "100"; end if; -- CLRF
if (INST(7 downto 6) = "10" ) then alu <= "01" & "00" & "11" & "00" & "00"; we <= '1'; flags <= "111"; end if; -- SUBWF
if (INST(7 downto 6) = "11" ) then alu <= "01" & "11" & "11" & "00" & "00"; we <= '1'; flags <= "100"; end if; -- DECF
when "0001" =>
case INST(7 downto 6) is
when "00" => alu <= "00" & "01" & "00" & "01" & "01"; we <= '1'; flags <= "100"; -- IORWF
when "01" => alu <= "00" & "01" & "00" & "00" & "01"; we <= '1'; flags <= "100"; -- ANDWF
when "10" => alu <= "00" & "01" & "00" & "10" & "01"; we <= '1'; flags <= "100"; -- XORWF
when "11" => alu <= "00" & "01" & "10" & "00" & "00"; we <= '1'; flags <= "111"; -- ADDWF
when others => null;
end case;
when "0010" =>
case INST(7 downto 6) is
when "00" => alu <= "01" & "00" & "00" & "00" & "00"; we <= '1'; flags <= "100"; -- MOVF
when "01" => alu <= "01" & "00" & "00" & "11" & "01"; we <= '1'; flags <= "100"; -- COMF
when "10" => alu <= "01" & "11" & "10" & "00" & "00"; we <= '1'; flags <= "100"; -- INCF
when "11" => alu <= "01" & "11" & "11" & "00" & "00"; we <= '1'; flags <= "000"; -- DECFSZ
when others => null;
end case;
when "0011" =>
case INST(7 downto 6) is
when "00" => alu <= "01" & "00" & "00" & "00" & "10"; we <= '1'; flags <= "001"; -- RRF
when "01" => alu <= "01" & "00" & "00" & "00" & "11"; we <= '1'; flags <= "001"; -- RLF
when "10" => alu <= "11" & "00" & "00" & "00" & "00"; we <= '1'; flags <= "000"; -- SWAPF
when "11" => alu <= "01" & "11" & "10" & "00" & "00"; we <= '1'; flags <= "000"; -- INCFSZ
when others => null;
end case;
when "0100" => alu <= "01" & "10" & "00" & "00" & "01"; fwe <= '1'; flags <= "000"; BDPOL <= '1'; -- BCF
when "0101" => alu <= "01" & "10" & "00" & "01" & "01"; fwe <= '1'; flags <= "000"; -- BSF
when "0110" => alu <= "01" & "10" & "00" & "00" & "01"; -- BTFSC
when "0111" => alu <= "01" & "10" & "00" & "00" & "01"; -- BTFSS
when "1000" => alu <= "10" & "00" & "00" & "00" & "00"; wwe <= '1'; -- RETLW
when "1001" => alu <= "10" & "00" & "00" & "00" & "00"; -- CALL
when "1010" => alu <= "10" & "00" & "00" & "00" & "00"; -- GOTO
when "1011" => alu <= "10" & "00" & "00" & "00" & "00"; -- GOTO
when "1100" => alu <= "10" & "00" & "00" & "00" & "00"; wwe <= '1'; flags <= "000"; -- MOVLW
when "1101" => alu <= "10" & "00" & "00" & "01" & "01"; wwe <= '1'; flags <= "100"; -- IORLW
when "1110" => alu <= "10" & "00" & "00" & "00" & "01"; wwe <= '1'; flags <= "100"; -- ANDLW
when "1111" => alu <= "10" & "00" & "00" & "10" & "01"; wwe <= '1'; flags <= "100"; -- XORLW
when others => null;
end case;
end process;
p_we_comb : process(wwe,fwe,we,INST)
begin
WWE_OP <= '0';
FWE_OP <= '0';
if (wwe = '1') or ((we = '1') and (INST(5) ='0')) then
WWE_OP <= '1';
end if;
if (fwe = '1') or ((we = '1') and (INST(5) = '1')) then
FWE_OP <= '1';
end if;
end process;
ALU_ASEL <= alu(9 downto 8);
ALU_BSEL <= alu(7 downto 6);
ALU_ADDSUB <= alu(5 downto 4);
ALU_BIT <= alu(3 downto 2);
ALU_SEL <= alu(1 downto 0);
ZWE <= flags(2);
DCWE <= flags(1);
CWE <= flags(0);
end rtl;
1.1 risc5x/jumptest.asm
http://www.opencores.org/cvsweb.shtml/risc5x/jumptest.asm?rev=1.1&content-type=text/x-cvsweb-markup
Index: jumptest.asm
===================================================================
;
LIST p=16C58 ; PIC16C58 is the target processor
;
; Core Sanity Test
;
; JUMPTEST.ASM
;
; test some jumps
; NEW in rev 1.1, test indirect addressing
; test some inc & decs
; sit in loop multiplying port A with a constant
; output 16 bit result on ports C & B
;
CARRY equ H'00' ; Carry bit in STATUS register
DC equ H'01' ; DC bit in STATUS register
ZERO equ H'02' ; Zero bit in STATUS register
W equ H'00' ; W indicator for many instruction (not the address!)
INDF equ H'00' ; Magic register that uses INDIRECT register
TIMER0 equ H'01' ; Timer register
PC equ H'02' ; PC
STATUS equ H'03' ; STATUS register F3
FSR equ H'04' ; INDIRECT Pointer Register
porta equ H'05' ; I/O register F5
portb equ H'06' ; I/O register F6
portc equ H'07' ; I/O register F7
x equ H'09' ; scratch
y equ H'0A' ; scratch
rh equ H'0B' ; result h
rl equ H'0C' ; result l
mult MACRO bit
btfsc y,bit
addwf rh,1
rrf rh,1
rrf rl,1
ENDM
start: movlw H'ff'
tris porta ; PORTA is Input
clrw
tris portb ; PORTB is Output
tris portc ; PORTC is Output
movwf portb ; PORTB <= 00
movlw h'0B'
movwf PC ; move to pc (jump1)
movlw h'F0' ; fail 0
movwf portb
goto fail
jump1: movlw h'05'
addwf PC,f ; jump forward to jump2
movlw h'F1' ; fail 1
movwf portb
goto fail
jump3: goto jump4 ; continue
nop
jump2: movlw h'04'
subwf PC, f ; jump back to jump 3
movlw h'F2' ; fail 2
movwf portb
goto fail
jump4:
movlw h'10' ; set locations 10-1F to xFF
movwf FSR
movlw h'ff'
clrlp: movwf INDF
incf FSR,F
btfsc FSR,4
goto clrlp
movlw h'10'
movwf x
movlw h'20'
movwf y
movlw x
movwf FSR ; point FSR at x
movf FSR,w
xorlw h'89' ; check its x (note bit 7 set always)
btfss STATUS,ZERO
goto fail
movf INDF,w
xorlw h'10' ; check its 10
btfss STATUS,ZERO
goto fail
movlw h'15' ; write 15 to x using INDF
movwf INDF
movf x,w ; read x
xorlw h'15' ; check its 15
btfss STATUS,ZERO
goto fail
incf FSR,F
movf INDF,w
xorlw h'20' ; check its 20
btfss STATUS,ZERO
goto fail
movlw h'00'
movwf FSR
movlw h'A5' ; paranoid !
movf INDF,w ; reading INDR itself should = 0
xorlw h'00' ; check
btfss STATUS,ZERO
goto fail
; check banking
; locations 20-2F, 40-4F, 60-6F all map to 0-0F
; locations 10-1F, 30-3F, 50-5F, 70-7F are real
movlw h'00'
movwf FSR ; set bank 0
movlw h'1F'
movwf h'1F'
movlw h'20'
movwf FSR ; set bank 1
movlw h'3F'
movwf h'1F'
movlw h'40'
movwf FSR ; set bank 2
movlw h'5F'
movwf h'1F'
movlw h'60'
movwf FSR ; set bank 3
movlw h'7F'
movwf h'1F'
; check
movlw h'00'
movwf FSR ; set bank 0
movf h'1F',w
xorlw h'1F'
btfss STATUS,ZERO
goto fail
movlw h'20'
movwf FSR ; set bank 1
movf h'1F',w
xorlw h'3F'
btfss STATUS,ZERO
goto fail
movlw h'40'
movwf FSR ; set bank 2
movf h'1F',w
xorlw h'5F'
btfss STATUS,ZERO
goto fail
movlw h'60'
movwf FSR ; set bank 3
movf h'1F',w
xorlw h'7F'
btfss STATUS,ZERO
goto fail
movlw h'00'
movwf FSR ; set bank 0
movlw h'45'
movwf h'0F'
movlw h'60'
movwf FSR ; set bank 3
movlw h'54'
movwf h'0F'
movlw h'40'
movwf FSR ; set bank 2
movf h'0f',w ; w should contain 54
xorlw h'54'
btfsc STATUS,ZERO
goto test1
movlw h'F3' ; fail 3
movwf portb
goto fail
test1: movlw h'00'
movwf FSR ; set bank 0
movlw h'04' ; w <= 04
movwf x
decf x,f ; x <= 03
decf x,f ; x <= 02
decf x,f ; x <= 01
decf x,f ; x <= 00
decf x,f ; x <= FF
movf x,w
xorlw h'FF' ; does w = ff ?
btfss STATUS,ZERO ; skip if clear
goto fail
incf x,f ; x <= 00
incf x,f ; x <= 01
movf x,w
xorlw h'01' ; does w = 01
btfss STATUS,ZERO
goto fail
; test logic
clrf x ; x <= 00
movlw h'a5'
iorwf x,f ; x <= a5
swapf x,f ; x <= 5a
movlw h'f0'
andwf x,f ; x <= 50
comf x,f ; x <= af
movlw h'5a'
xorwf x,f ; x <= f5
;check
movfw x
xorlw h'f5'
btfsc STATUS,ZERO
goto test2
movlw h'F4' ; fail 4
movwf portb
goto fail
test2: movlw h'23'
movwf x ; x <= 23
movlw h'e1' ; w <= e1
addwf x,f ; x <= 04
btfss STATUS,CARRY
goto fail ; carry should be set
movlw h'02' ; w <= 02
subwf x,f ; x <= 02
btfss STATUS,CARRY
goto fail ; borrow should be clear
movlw h'34' ; w <= 34
subwf x,f ; x <= ce
btfsc STATUS,CARRY
goto fail ; borrow should be set
movf x,w
xorlw h'CE'
btfss STATUS,ZERO
goto fail ; x /= ce
test3: movlw h'34' ; test dc flag
movwf x
movlw h'0F'
addwf x,f ; x <= 43
btfsc STATUS,CARRY
goto fail ; carry should be clear
btfss STATUS,DC
goto fail ; dc should be set
movlw h'01'
subwf x,f ; x <= 42
btfss STATUS,CARRY
goto fail ; borrow should be clear
btfss STATUS,DC
goto fail ; dc borrow should be clear
movlw h'FF'
subwf x,f
btfsc STATUS,CARRY
goto fail ; borrow should be set
btfsc STATUS,DC
goto fail ; dc borrow should be set
movf x,w
xorlw h'43' ; final check
btfss STATUS,ZERO
goto fail ; x /= 43
movlw h'E0' ; ok
movwf portb
loop1: ; mult x by y
movf porta,W
movwf x
movlw h'23'
movwf y
clrf rh
clrf rl
movf x,w
bcf STATUS,CARRY
mult 0
mult 1
mult 2
mult 3
mult 4
mult 5
mult 6
mult 7
movf rl,w
movwf portb ; on port b low result
movf rh,w
movwf portc ; on port c high result
goto loop1
fail: goto fail
end
1.1 risc5x/jumptest.hex
http://www.opencores.org/cvsweb.shtml/risc5x/jumptest.hex?rev=1.1&content-type=text/x-cvsweb-markup
Index: jumptest.hex
===================================================================
:10000000FF0C050040000600070026000B0C220034
:10001000F00C2600F30A050CE201F10C2600F30AAD
:10002000170A0000040CA200F20C2600F30A100CC0
:100030002400FF0C2000A40284061A0A100C2900D8
:10004000200C2A00090C24000402890F4307F30A3C
:100050000002100F4307F30A150C20000902150FC8
:100060004307F30AA4020002200F4307F30A000C1F
:100070002400A50C0002000F4307F30A000C240023
:100080001F0C3F00200C24003F0C3F00400C2400BC
:100090005F0C3F00600C24007F0C3F00000C24002C
:1000A0001F021F0F4307F30A200C24001F023F0FFB
:1000B0004307F30A400C24001F025F0F4307F30AB3
:1000C000600C24001F027F0F4307F30A000C24007A
:1000D000450C2F00600C2400540C2F00400C240011
:1000E0000F02540F4306770AF30C2600F30A000CA4
:1000F0002400040C2900E900E900E900E900E90016
:100100000902FF0F4307F30AA902A9020902010F1E
:100110004307F30A6900A50C2901A903F00C690142
:1001200069025A0CA9010902F50F43069A0AF40C58
:100130002600F30A230C2900E10CE9010307F30A66
:10014000020CA9000307F30A340CA9000306F30A02
:100150000902CE0F4307F30A340C29000F0CE90102
:100160000306F30A2307F30A010CA9000307F30AA5
:100170002307F30AFF0CA9000306F30A2306F30A78
:100180000902430F4307F30AE00C26000502290089
:10019000230C2A006B006C00090203040A06EB0121
:1001A0002B032C032A06EB012B032C034A06EB013D
:1001B0002B032C036A06EB012B032C038A06EB01AD
:1001C0002B032C03AA06EB012B032C03CA06EB011D
:1001D0002B032C03EA06EB012B032C030C02260055
:0801E0000B022700C60AF30A16
:00000001FF
1.1 risc5x/mux2.vhd
http://www.opencores.org/cvsweb.shtml/risc5x/mux2.vhd?rev=1.1&content-type=text/x-cvsweb-markup
Index: mux2.vhd
===================================================================
--
-- Risc5x
-- www.OpenCores.Org - November 2001
--
--
-- This library is free software; you can distribute it and/or modify it
-- under the terms of the GNU Lesser General Public License as published
-- by the Free Software Foundation; either version 2.1 of the License, or
-- (at your option) any later version.
--
-- This library is distributed in the hope that it will be useful, but
-- WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-- See the GNU Lesser General Public License for more details.
--
-- A RISC CPU core.
--
-- (c) Mike Johnson 2001. All Rights Reserved.
-- mikej@o... for support or any other issues.
--
-- Revision list
--
-- version 1.0 initial opencores release
--
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity MUX2 is
generic (
WIDTH : in natural := 8;
SLICE : in natural := 1; -- 1 left, 0 right
OP_REG : in boolean := FALSE
);
port (
DIN1 : in std_logic_vector(WIDTH-1 downto 0);
DIN0 : in std_logic_vector(WIDTH-1 downto 0);
SEL : in std_logic;
ENA : in std_logic;
CLK : in std_logic;
DOUT : out std_logic_vector(WIDTH-1 downto 0)
);
end;
--
-- USE THIS ARCHITECTURE FOR XILINX
--
use work.pkg_xilinx_prims.all;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
architecture VIRTEX of MUX2 is
signal dout_int : std_logic_vector(WIDTH-1 downto 0);
begin -- architecture
ram_bit : for i in 0 to WIDTH-1 generate
attribute RLOC of mux8_muxf5_1 : label is "R" & integer'image((WIDTH -1)-i) & "C0.S" & integer'image(SLICE);
begin
mux8_muxf5_1 : MUXF5
port map (
O => dout_int(i),
I0 => DIN0(i),
I1 => DIN1(i),
S => SEL);
opreg : if OP_REG generate
attribute RLOC of reg : label is "R" & integer'image((WIDTH -1)-i) & "C0.S" & integer'image(SLICE);
begin
reg : FDE
port map (
D => dout_int(i),
C => CLK,
CE => ENA,
Q => DOUT(i));
end generate;
opwire : if not OP_REG generate
DOUT(i) <= dout_int(i);
end generate;
end generate;
end VIRTEX;
--pragma translate_off
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
architecture RTL of MUX2 is
signal mux : std_logic_vector(WIDTH-1 downto 0);
begin -- architecture
p_mux_comb : process(DIN0,DIN1,SEL)
variable ram_addr : integer := 0;
begin
mux <= DIN0;
if (SEL = '0') then
mux <= DIN0;
else
mux <= DIN1;
end if;
end process;
opreg : if OP_REG generate
p_opreg : process
begin
wait until CLK'event and (CLK = '1');
if (ENA = '1') then
DOUT <= mux;
end if;
end process;
end generate;
opwire : if not OP_REG generate
DOUT <= mux;
end generate;
end RTL;
--pragma translate_on
1.1 risc5x/mux2_add_reg.vhd
http://www.opencores.org/cvsweb.shtml/risc5x/mux2_add_reg.vhd?rev=1.1&content-type=text/x-cvsweb-markup
Index: mux2_add_reg.vhd
===================================================================
--
-- Risc5x
-- www.OpenCores.Org - November 2001
--
--
-- This library is free software; you can distribute it and/or modify it
-- under the terms of the GNU Lesser General Public License as published
-- by the Free Software Foundation; either version 2.1 of the License, or
-- (at your option) any later version.
--
-- This library is distributed in the hope that it will be useful, but
-- WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-- See the GNU Lesser General Public License for more details.
--
-- A RISC CPU core.
--
-- (c) Mike Johnson 2001. All Rights Reserved.
-- mikej@o... for support or any other issues.
--
-- Revision list
--
-- version 1.0 initial opencores release
--
-- MUX2_ADD_REG
--
-- DOUT <= REG_DOUT + ADD_VAL when ADD = '1'
-- <= LOAD_VAL when ADD = '0'
-- REG_DOUT <= DOUT when ENA = '1' and rising_edge(CLK)
-- <= (others => '1') when PRESET = '1'
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity MUX2_ADD_REG is
generic (
WIDTH : in natural := 11
);
port (
ADD_VAL : in std_logic_vector(WIDTH-1 downto 0);
LOAD_VAL : in std_logic_vector(WIDTH-1 downto 0);
ADD : in std_logic;
PRESET : in std_logic; -- async
ENA : in std_logic;
CLK : in std_logic;
DOUT : out std_logic_vector(WIDTH-1 downto 0);
REG_DOUT : out std_logic_vector(WIDTH-1 downto 0)
);
end;
--
-- USE THIS ARCHITECTURE FOR XILINX
--
use work.pkg_xilinx_prims.all;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
architecture VIRTEX of MUX2_ADD_REG is
signal lut_op : std_logic_vector(WIDTH-1 downto 0);
signal mult_and_op : std_logic_vector(WIDTH-1 downto 0);
signal carry : std_logic_vector(WIDTH downto 0);
signal op_int : std_logic_vector(WIDTH-1 downto 0);
signal reg_op_int : std_logic_vector(WIDTH-1 downto 0);
function loc(i : integer) return integer is
begin
return (((WIDTH+1)/2)-1) - i/2;
end loc;
begin
carry(0) <= '0';
INST : for i in 0 to WIDTH-1 generate
attribute RLOC of u_lut : label is "R" & integer'image(loc(i)) & "C0.S1";
attribute RLOC of u_1 : label is "R" & integer'image(loc(i)) & "C0.S1";
attribute RLOC of u_2 : label is "R" & integer'image(loc(i)) & "C0.S1";
attribute RLOC of u_3 : label is "R" & integer'image(loc(i)) & "C0.S1";
attribute RLOC of u_reg : label is "R" & integer'image(loc(i)) & "C0.S1";
attribute INIT of u_lut : label is "7D28";
begin
u_lut : LUT4
--pragma translate_off
generic map (
INIT => str2slv(u_lut'INIT)
)
--pragma translate_on
port map (
I0 => ADD,
I1 => ADD_VAL(i),
I2 => reg_op_int(i),
I3 => LOAD_VAL(i),
O => lut_op(i)
);
u_1 : MULT_AND
port map (
I0 => ADD,
I1 => ADD_VAL(i),
LO => mult_and_op(i)
);
u_2 : MUXCY
port map (
DI => mult_and_op(i),
CI => carry(i),
S => lut_op(i),
O => carry(i+1)
);
u_3 : XORCY
port map (
LI => lut_op(i),
CI => carry(i),
O => op_int(i)
);
u_reg : FDPE
port map (
Q => reg_op_int(i),
D => op_int(i),
C => CLK,
CE => ENA,
PRE=> PRESET
);
end generate;
DOUT <= op_int;
REG_DOUT <= reg_op_int;
end Virtex;
--pragma translate_off
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
architecture RTL of MUX2_ADD_REG is
signal op_int : std_logic_vector(WIDTH-1 downto 0);
signal reg_op_int : std_logic_vector(WIDTH-1 downto 0);
begin -- architecture
p_comb : process(ADD,reg_op_int,ADD_VAL,LOAD_VAL)
begin
if (ADD = '1') then
op_int <= reg_op_int + ADD_VAL;
else
op_int <= LOAD_VAL;
end if;
end process;
p_opreg : process(PRESET,CLK)
begin
if (PRESET = '1') then
reg_op_int <= (others => '1');
elsif CLK'event and (CLK = '1') then
if (ENA = '1') then
reg_op_int <= op_int;
end if;
end if;
end process;
DOUT <= op_int;
REG_DOUT <= reg_op_int;
end RTL;
--pragma translate_on
1.1 risc5x/mux4.vhd
http://www.opencores.org/cvsweb.shtml/risc5x/mux4.vhd?rev=1.1&content-type=text/x-cvsweb-markup
Index: mux4.vhd
===================================================================
--
-- Risc5x
-- www.OpenCores.Org - November 2001
--
--
-- This library is free software; you can distribute it and/or modify it
-- under the terms of the GNU Lesser General Public License as published
-- by the Free Software Foundation; either version 2.1 of the License, or
-- (at your option) any later version.
--
-- This library is distributed in the hope that it will be useful, but
-- WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-- See the GNU Lesser General Public License for more details.
--
-- A RISC CPU core.
--
-- (c) Mike Johnson 2001. All Rights Reserved.
-- mikej@o... for support or any other issues.
--
-- Revision list
--
-- version 1.0 initial opencores release
--
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity MUX4 is
generic (
WIDTH : in natural := 8;
SLICE : in natural := 1; -- 1 left, 0 right
OP_REG : in boolean := FALSE
);
port (
DIN3 : in std_logic_vector(WIDTH-1 downto 0);
DIN2 : in std_logic_vector(WIDTH-1 downto 0);
DIN1 : in std_logic_vector(WIDTH-1 downto 0);
DIN0 : in std_logic_vector(WIDTH-1 downto 0);
SEL : in std_logic_vector(1 downto 0);
ENA : in std_logic;
CLK : in std_logic;
DOUT : out std_logic_vector(WIDTH-1 downto 0)
);
end;
--
-- USE THIS ARCHITECTURE FOR XILINX
--
use work.pkg_xilinx_prims.all;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
architecture VIRTEX of MUX4 is
signal dout_int : std_logic_vector(WIDTH-1 downto 0);
signal mux8_01 : std_logic_vector(WIDTH-1 downto 0);
signal mux8_23 : std_logic_vector(WIDTH-1 downto 0);
begin -- architecture
ram_bit : for i in 0 to WIDTH-1 generate
attribute RLOC of mux8_lut1,mux8_lut2 : label is "R" & integer'image((WIDTH -1)-i) & "C0.S" & integer'image(SLICE);
attribute RLOC of mux8_muxf5_1 : label is "R" & integer'image((WIDTH -1)-i) & "C0.S" & integer'image(SLICE);
attribute INIT of mux8_lut1 : label is "00CA";
attribute INIT of mux8_lut2 : label is "00CA";
begin
mux8_lut1: LUT4
--pragma translate_off
generic map (
INIT => str2slv(mux8_lut1'INIT)
)
--pragma translate_on
port map (
I0 => DIN0(i),
I1 => DIN1(i),
I2 => SEL(0),
I3 => '0',
O => mux8_01(i));
mux8_lut2: LUT4
--pragma translate_off
generic map (
INIT => str2slv(mux8_lut2'INIT)
)
--pragma translate_on
port map (
I0 => DIN2(i),
I1 => DIN3(i),
I2 => SEL(0),
I3 => '0',
O => mux8_23(i));
mux8_muxf5_1 : MUXF5
port map (
O => dout_int(i),
I0 => mux8_01(i),
I1 => mux8_23(i),
S => SEL(1));
opreg : if OP_REG generate
attribute RLOC of reg : label is "R" & integer'image((WIDTH -1)-i) & "C0.S" & integer'image(SLICE);
begin
reg : FDE
port map (
D => dout_int(i),
C => CLK,
CE => ENA,
Q => DOUT(i));
end generate;
opwire : if not OP_REG generate
DOUT(i) <= dout_int(i);
end generate;
end generate;
end VIRTEX;
--pragma translate_off
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
architecture RTL of MUX4 is
signal mux : std_logic_vector(WIDTH-1 downto 0);
begin -- architecture
p_mux_comb : process(DIN0,DIN1,DIN2,DIN3,SEL)
variable ram_addr : integer := 0;
begin
mux <= DIN0;
case SEL is
when "00" => mux <= DIN0;
when "01" => mux <= DIN1;
when "10" => mux <= DIN2;
when "11" => mux <= DIN3;
when others => null;
end case;
end process;
opreg : if OP_REG generate
p_opreg : process
begin
wait until CLK'event and (CLK = '1');
if (ENA = '1') then
DOUT <= mux;
end if;
end process;
end generate;
opwire : if not OP_REG generate
DOUT <= mux;
end generate;
end RTL;
--pragma translate_on
1.1 risc5x/mux8.vhd
http://www.opencores.org/cvsweb.shtml/risc5x/mux8.vhd?rev=1.1&content-type=text/x-cvsweb-markup
Index: mux8.vhd
===================================================================
--
-- Risc5x
-- www.OpenCores.Org - November 2001
--
--
-- This library is free software; you can distribute it and/or modify it
-- under the terms of the GNU Lesser General Public License as published
-- by the Free Software Foundation; either version 2.1 of the License, or
-- (at your option) any later version.
--
-- This library is distributed in the hope that it will be useful, but
-- WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-- See the GNU Lesser General Public License for more details.
--
-- A RISC CPU core.
--
-- (c) Mike Johnson 2001. All Rights Reserved.
-- mikej@o... for support or any other issues.
--
-- Revision list
--
-- version 1.0 initial opencores release
--
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity MUX8 is
generic (
WIDTH : in natural := 8;
OP_REG : in boolean := FALSE
);
port (
DIN7 : in std_logic_vector(WIDTH-1 downto 0);
DIN6 : in std_logic_vector(WIDTH-1 downto 0);
DIN5 : in std_logic_vector(WIDTH-1 downto 0);
DIN4 : in std_logic_vector(WIDTH-1 downto 0);
DIN3 : in std_logic_vector(WIDTH-1 downto 0);
DIN2 : in std_logic_vector(WIDTH-1 downto 0);
DIN1 : in std_logic_vector(WIDTH-1 downto 0);
DIN0 : in std_logic_vector(WIDTH-1 downto 0);
SEL : in std_logic_vector(2 downto 0);
ENA : in std_logic;
CLK : in std_logic;
DOUT : out std_logic_vector(WIDTH-1 downto 0)
);
end;
--
-- USE THIS ARCHITECTURE FOR XILINX
--
use work.pkg_xilinx_prims.all;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
architecture VIRTEX of MUX8 is
signal dout_int : std_logic_vector(WIDTH-1 downto 0);
signal mux8_01 : std_logic_vector(WIDTH-1 downto 0);
signal mux8_23 : std_logic_vector(WIDTH-1 downto 0);
signal mux8_45 : std_logic_vector(WIDTH-1 downto 0);
signal mux8_67 : std_logic_vector(WIDTH-1 downto 0);
signal mux8_03 : std_logic_vector(WIDTH-1 downto 0);
signal mux8_47 : std_logic_vector(WIDTH-1 downto 0);
begin -- architecture
ram_bit : for i in 0 to WIDTH-1 generate
attribute RLOC of mux8_lut1,mux8_lut2 : label is "R" & integer'image((WIDTH -1)-i) & "C0.S1";
attribute RLOC of mux8_lut3,mux8_lut4 : label is "R" & integer'image((WIDTH -1)-i) & "C0.S0";
attribute RLOC of mux8_muxf5_1 : label is "R" & integer'image((WIDTH -1)-i) & "C0.S1";
attribute RLOC of mux8_muxf5_2 : label is "R" & integer'image((WIDTH -1)-i) & "C0.S0";
attribute RLOC of mux8_muxf6_1 : label is "R" & integer'image((WIDTH -1)-i) & "C0.S0";
attribute INIT of mux8_lut1 : label is "00CA";
attribute INIT of mux8_lut2 : label is "00CA";
attribute INIT of mux8_lut3 : label is "00CA";
attribute INIT of mux8_lut4 : label is "00CA";
begin
mux8_lut1: LUT4
--pragma translate_off
generic map (
INIT => str2slv(mux8_lut1'INIT)
)
--pragma translate_on
port map (
I0 => DIN0(i),
I1 => DIN1(i),
I2 => SEL(0),
I3 => '0',
O => mux8_01(i));
mux8_lut2: LUT4
--pragma translate_off
generic map (
INIT => str2slv(mux8_lut2'INIT)
)
--pragma translate_on
port map (
I0 => DIN2(i),
I1 => DIN3(i),
I2 => SEL(0),
I3 => '0',
O => mux8_23(i));
mux8_lut3: LUT4
--pragma translate_off
generic map (
INIT => str2slv(mux8_lut3'INIT)
)
--pragma translate_on
port map (
I0 => DIN4(i),
I1 => DIN5(i),
I2 => SEL(0),
I3 => '0',
O => mux8_45(i));
mux8_lut4: LUT4
--pragma translate_off
generic map (
INIT => str2slv(mux8_lut4'INIT)
)
--pragma translate_on
port map (
I0 => DIN6(i),
I1 => DIN7(i),
I2 => SEL(0),
I3 => '0',
O => mux8_67(i));
mux8_muxf5_1 : MUXF5
port map (
O => mux8_03(i),
I0 => mux8_01(i),
I1 => mux8_23(i),
S => SEL(1));
mux8_muxf5_2 : MUXF5
port map (
O => mux8_47(i),
I0 => mux8_45(i),
I1 => mux8_67(i),
S => SEL(1));
mux8_muxf6_1 : MUXF6
port map (
O => dout_int(i),
I0 => mux8_03(i),
I1 => mux8_47(i),
S => SEL(2));
opreg : if OP_REG generate
attribute RLOC of reg : label is "R" & integer'image((WIDTH -1)-i) & "C0.S1";
begin
reg : FDE
port map (
D => dout_int(i),
C => CLK,
CE => ENA,
Q => DOUT(i));
end generate;
opwire : if not OP_REG generate
DOUT(i) <= dout_int(i);
end generate;
end generate;
end VIRTEX;
--pragma translate_off
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
architecture RTL of MUX8 is
signal mux : std_logic_vector(WIDTH-1 downto 0);
begin -- architecture
p_mux_comb : process(DIN0,DIN1,DIN2,DIN3,DIN4,DIN5,DIN6,DIN7,SEL)
variable ram_addr : integer := 0;
begin
mux <= DIN0;
case SEL is
when "000" => mux <= DIN0;
when "001" => mux <= DIN1;
when "010" => mux <= DIN2;
when "011" => mux <= DIN3;
when "100" => mux <= DIN4;
when "101" => mux <= DIN5;
when "110" => mux <= DIN6;
when "111" => mux <= DIN7;
when others => null;
end case;
end process;
opreg : if OP_REG generate
p_opreg : process
begin
wait until CLK'event and (CLK = '1');
if (ENA = '1') then
DOUT <= mux;
end if;
end process;
end generate;
opwire : if not OP_REG generate
DOUT <= mux;
end generate;
end RTL;
--pragma translate_on
1.1 risc5x/pkg_prims.vhd
http://www.opencores.org/cvsweb.shtml/risc5x/pkg_prims.vhd?rev=1.1&content-type=text/x-cvsweb-markup
Index: pkg_prims.vhd
===================================================================
--
-- Risc5x
-- www.OpenCores.Org - November 2001
--
--
-- This library is free software; you can distribute it and/or modify it
-- under the terms of the GNU Lesser General Public License as published
-- by the Free Software Foundation; either version 2.1 of the License, or
-- (at your option) any later version.
--
-- This library is distributed in the hope that it will be useful, but
-- WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-- See the GNU Lesser General Public License for more details.
--
-- A RISC CPU core.
--
-- (c) Mike Johnson 2001. All Rights Reserved.
-- mikej@o... for support or any other issues.
--
-- Revision list
--
-- version 1.0 initial opencores release
--
library ieee;
use ieee.std_logic_1164.all;
package pkg_prims is
component MUX8
generic (
WIDTH : in natural;
OP_REG : in boolean
);
port (
DIN7 : in std_logic_vector(WIDTH-1 downto 0);
DIN6 : in std_logic_vector(WIDTH-1 downto 0);
DIN5 : in std_logic_vector(WIDTH-1 downto 0);
DIN4 : in std_logic_vector(WIDTH-1 downto 0);
DIN3 : in std_logic_vector(WIDTH-1 downto 0);
DIN2 : in std_logic_vector(WIDTH-1 downto 0);
DIN1 : in std_logic_vector(WIDTH-1 downto 0);
DIN0 : in std_logic_vector(WIDTH-1 downto 0);
SEL : in std_logic_vector(2 downto 0);
ENA : in std_logic;
CLK : in std_logic;
DOUT : out std_logic_vector(WIDTH-1 downto 0)
);
end component;
component MUX4
generic (
WIDTH : in natural;
SLICE : in natural;
OP_REG : in boolean
);
port (
DIN3 : in std_logic_vector(WIDTH-1 downto 0);
DIN2 : in std_logic_vector(WIDTH-1 downto 0);
DIN1 : in std_logic_vector(WIDTH-1 downto 0);
DIN0 : in std_logic_vector(WIDTH-1 downto 0);
SEL : in std_logic_vector(1 downto 0);
ENA : in std_logic;
CLK : in std_logic;
DOUT : out std_logic_vector(WIDTH-1 downto 0)
);
end component;
component MUX2
generic (
WIDTH : in natural;
SLICE : in natural;
OP_REG : in boolean
);
port (
DIN1 : in std_logic_vector(WIDTH-1 downto 0);
DIN0 : in std_logic_vector(WIDTH-1 downto 0);
SEL : in std_logic;
ENA : in std_logic;
CLK : in std_logic;
DOUT : out std_logic_vector(WIDTH-1 downto 0)
);
end component;
component MUX2_ADD_REG
generic (
WIDTH : in natural
);
port (
ADD_VAL : in std_logic_vector(WIDTH-1 downto 0);
LOAD_VAL : in std_logic_vector(WIDTH-1 downto 0);
ADD : in std_logic;
PRESET : in std_logic; -- async
ENA : in std_logic;
CLK : in std_logic;
DOUT : out std_logic_vector(WIDTH-1 downto 0);
REG_DOUT : out std_logic_vector(WIDTH-1 downto 0)
);
end component;
component ADD_SUB
generic (
WIDTH : in natural
);
port (
A : in std_logic_vector(WIDTH-1 downto 0);
B : in std_logic_vector(WIDTH-1 downto 0);
ADD_OR_SUB : in std_logic; -- high for DOUT <= A +/- B, low for DOUT <= A
DO_SUB : in std_logic; -- high for DOUT <= A - B, low for DOUT <= A + B
CARRY_OUT : out std_logic_vector(WIDTH-1 downto 0);
DOUT : out std_logic_vector(WIDTH-1 downto 0)
);
end component;
component ALUBIT
generic (
WIDTH : in natural
);
port (
A : in std_logic_vector(WIDTH-1 downto 0);
B : in std_logic_vector(WIDTH-1 downto 0);
OP : in std_logic_vector(1 downto 0);
DOUT : out std_logic_vector(WIDTH-1 downto 0)
);
end component;
end;
1.1 risc5x/pkg_risc5x.vhd
http://www.opencores.org/cvsweb.shtml/risc5x/pkg_risc5x.vhd?rev=1.1&content-type=text/x-cvsweb-markup
Index: pkg_risc5x.vhd
===================================================================
--
-- Risc5x
-- www.OpenCores.Org - November 2001
--
--
-- This library is free software; you can distribute it and/or modify it
-- under the terms of the GNU Lesser General Public License as published
-- by the Free Software Foundation; either version 2.1 of the License, or
-- (at your option) any later version.
--
-- This library is distributed in the hope that it will be useful, but
-- WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-- See the GNU Lesser General Public License for more details.
--
-- A RISC CPU core.
--
-- (c) Mike Johnson 2001. All Rights Reserved.
-- mikej@o... for support or any other issues.
--
-- Revision list
--
-- version 1.0 initial opencores release
--
library ieee;
use ieee.std_logic_1164.all;
package pkg_risc5x is
function slv_to_integer(x : std_logic_vector) return integer;
function integer_to_slv(n, bits : integer) return std_logic_vector;
end;
package body pkg_risc5x is
function slv_to_integer(x : std_logic_vector) return integer is
variable n : integer := 0;
variable failure : boolean := false;
begin
assert (x'high - x'low + 1) <= 31
report "Range of sulv_to_integer argument exceeds integer range"
severity error;
for i in x'range loop
n := n * 2;
case x(i) is
when '1' | 'H' => n := n + 1;
when '0' | 'L' => null;
when others =>
-- failure := true;
null;
end case;
end loop;
assert not failure
report "sulv_to_integer cannot convert indefinite std_logic_vector"
severity error;
if failure then
return 0;
else
return n;
end if;
end slv_to_integer;
function integer_to_slv(n, bits : integer) return std_logic_vector is
variable x : std_logic_vector(bits-1 downto 0) := (others => '0');
variable tempn : integer := n;
begin
for i in x'reverse_range loop
if (tempn mod 2) = 1 then
x(i) := '1';
end if;
tempn := tempn / 2;
end loop;
return x;
end integer_to_slv;
end;
1.1 risc5x/pkg_xilinx_prims.vhd
http://www.opencores.org/cvsweb.shtml/risc5x/pkg_xilinx_prims.vhd?rev=1.1&content-type=text/x-cvsweb-markup
Index: pkg_xilinx_prims.vhd
===================================================================
--
-- Risc5x
-- www.OpenCores.Org - November 2001
--
--
-- This library is free software; you can distribute it and/or modify it
-- under the terms of the GNU Lesser General Public License as published
-- by the Free Software Foundation; either version 2.1 of the License, or
-- (at your option) any later version.
--
-- This library is distributed in the hope that it will be useful, but
-- WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-- See the GNU Lesser General Public License for more details.
--
-- A RISC CPU core.
--
-- (c) Mike Johnson 2001. All Rights Reserved.
-- mikej@o... for support or any other issues.
--
-- Revision list
--
-- version 1.0 initial opencores release
--
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
package pkg_xilinx_prims is
attribute INIT : string;
attribute INIT_00 : string;
attribute INIT_01 : string;
attribute INIT_02 : string;
attribute INIT_03 : string;
attribute INIT_04 : string;
attribute INIT_05 : string;
attribute INIT_06 : string;
attribute INIT_07 : string;
attribute INIT_08 : string;
attribute INIT_09 : string;
attribute INIT_0A : string;
attribute INIT_0B : string;
attribute INIT_0C : string;
attribute INIT_0D : string;
attribute INIT_0E : string;
attribute INIT_0F : string;
attribute RLOC : string;
attribute HU_SET : string;
function str2slv (str : string) return std_logic_vector;
component fd port (
d : in std_logic; c : in std_logic; q : out std_logic );
end component;
component fde port (
d : in std_logic; c : in std_logic; ce : in std_logic; q : out std_logic );
end component;
component fdc port (
d : in std_logic; c : in std_logic; clr : in std_logic; q : out std_logic );
end component;
component fdce port (
d : in std_logic; c : in std_logic; clr : in std_logic; ce : in std_logic;
q : out std_logic );
end component;
component fdpe port(
d : in std_logic; c : in std_logic; pre : in std_logic; ce : in std_logic;
q : out std_logic );
end component;
component ram16x1d
port (
a0, a1, a2, a3 : in std_logic;
dpra0, dpra1, dpra2, dpra3 : in std_logic;
wclk : in std_logic;
we : in std_logic;
d : in std_logic;
spo : out std_logic;
dpo : out std_logic
);
end component;
component lut4
--pragma translate_off
generic (
INIT : std_logic_vector (15 downto 0)
);
--pragma translate_on
port (
i0 : in std_logic;
i1 : in std_logic;
i2 : in std_logic;
i3 : in std_logic;
O : out std_logic
);
end component;
component mult_and
port (
i0 : in std_logic;
i1 : in std_logic;
lo : out std_logic
);
end component;
component muxcy
port (
di : in std_logic;
ci : in std_logic;
s : in std_logic;
o : out std_logic
);
end component;
component xorcy
port (
li : |