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

Subversion Repositories risc5x

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 1 to Rev 2
    Reverse comparison

Rev 1 → Rev 2

/trunk/regs.vhd
0,0 → 1,245
--
-- 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@opencores.org 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 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;
--
-- USE THIS ARCHITECTURE FOR XILINX
--
use work.pkg_risc5x.all;
use work.pkg_xilinx_prims.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;
 
architecture VIRTEX of REGS is
 
constant WIDTH : natural := 8;
constant OP_REG : boolean := false;
 
type slv_array is array (natural range <>) of std_logic_vector(WIDTH-1 downto 0);
signal ram_out : slv_array(4 downto 0);
signal wen_int : std_logic_vector(4 downto 0);
signal sel : std_logic_vector(2 downto 0);
 
begin -- architecture
 
-- ram mapping
-- bank location
-- xx 00xxx special registers
-- xx 01xxx common 8 to all banks
-- 00 1xxxx 16 bank 0
-- 01 1xxxx 16 bank 1
-- 10 1xxxx 16 bank 2
-- 11 1xxxx 16 bank 3
p_wen_comb : process (BANK,LOCATION,WE)
variable addr : std_logic_vector(3 downto 0);
begin
addr := (BANK & LOCATION(4 downto 3));
wen_int <= (others => '0');
case addr(3 downto 1) is
when "001" => wen_int(0) <= WE; -- bank0
when "011" => wen_int(1) <= WE; -- bank1
when "101" => wen_int(2) <= WE; -- bank2
when "111" => wen_int(3) <= WE; -- bank3
 
when others => null;
end case;
if (LOCATION(4 downto 3) = "01") then
wen_int(4) <= WE; -- common
end if;
end process;
 
ram_bit : for i in 0 to WIDTH-1 generate
begin
rams : for j in 0 to 4 generate
attribute RLOC of ram: label is "R" & integer'image((WIDTH -1)-i) & "C" & integer'image((j+1)/2) & ".S" & integer'image(1 - ((j+1) mod 2));
begin
ram : RAM16X1D
port map (
a0 => LOCATION(0),
a1 => LOCATION(1),
a2 => LOCATION(2),
a3 => LOCATION(3),
dpra0 => LOCATION(0),
dpra1 => LOCATION(1),
dpra2 => LOCATION(2),
dpra3 => LOCATION(3),
wclk => CLK,
we => wen_int(j),
d => DIN(i),
dpo => ram_out(j)(i));
end generate;
end generate;
 
SEL <= BANK & LOCATION(4);
 
mux : if true generate
attribute RLOC of mux8_1: label is "R0C3";
begin
mux8_1 : MUX8
generic map (
WIDTH => WIDTH,
OP_REG => OP_REG
)
port map (
DIN7 => ram_out(3),
DIN6 => ram_out(4),
DIN5 => ram_out(2),
DIN4 => ram_out(4),
DIN3 => ram_out(1),
DIN2 => ram_out(4),
DIN1 => ram_out(0),
DIN0 => ram_out(4),
 
SEL => sel,
ENA => '1', -- not used
CLK => CLK, -- not used
 
DOUT => DOUT
);
end generate;
end VIRTEX;
 
--pragma translate_off
 
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;
 
architecture RTL of REGS is
signal final_addr : std_logic_vector(6 downto 0);
constant WIDTH : natural := 8;
constant OP_REG : boolean := false;
 
-- following required for simulation model only
constant nwords : integer := 2 ** 7;
type ram_type is array (0 to nwords-1) of std_logic_vector(WIDTH-1 downto 0);
signal ram_read_data : std_logic_vector(WIDTH-1 downto 0);
--shared variable ram :ram_type := (others => (others => 'X')); -- helps debug no end!
shared variable ram :ram_type := (others => (others => '0'));
 
begin -- architecture
p_remap : process(BANK,LOCATION)
variable addr : std_logic_vector(3 downto 0);
begin
addr := (BANK & LOCATION(4 downto 3));
final_addr <= "0000000";
case addr is
when "0001" => final_addr <= "0000" & LOCATION(2 downto 0);
when "0101" => final_addr <= "0000" & LOCATION(2 downto 0);
when "1001" => final_addr <= "0000" & LOCATION(2 downto 0);
when "1101" => final_addr <= "0000" & LOCATION(2 downto 0);
-- bank #0
when "0010" => final_addr <= "0001" & LOCATION(2 downto 0);
when "0011" => final_addr <= "0010" & LOCATION(2 downto 0);
-- bank #1
when "0110" => final_addr <= "0011" & LOCATION(2 downto 0);
when "0111" => final_addr <= "0100" & LOCATION(2 downto 0);
-- bank #2
when "1010" => final_addr <= "0101" & LOCATION(2 downto 0);
when "1011" => final_addr <= "0110" & LOCATION(2 downto 0);
-- bank #3
when "1110" => final_addr <= "0111" & LOCATION(2 downto 0);
when "1111" => final_addr <= "1000" & LOCATION(2 downto 0);
when others => null;
end case;
end process;
 
-- you should replace the following simulation memory model
-- with a dpram (no clock delay on read) for synthesis if
-- you do not wish to use the Xilinx Virtex architecture.
-- i.e.
--
--U1: dpram
-- generic map (addr_bits => 7,
-- data_bits => 8)
-- port map (
-- reset => RESET,
-- wr_clk => CLK,
-- wr_en => WE,
-- wr_addr => final_addr,
-- wr_data => DIN,
-- rd_clk => '0',
-- rd_addr => final_addr,
-- rd_data => DOUT
-- );
 
-- SIMULATION MODEL OF RAM
p_ram_write : process
variable ram_addr : integer := 0;
begin
wait until CLK'event and (CLK = '1');
if (WE = '1') then
ram_addr := slv_to_integer(final_addr);
ram(ram_addr) := DIN;
end if;
end process;
 
p_ram_read_comb : process(CLK,final_addr)
variable ram_addr : integer := 0;
begin
ram_addr := slv_to_integer(final_addr);
ram_read_data <= ram(ram_addr);
end process;
 
opreg : if OP_REG generate
p_opreg : process
begin
wait until CLK'event and (CLK = '1');
if (RE = '1') then
DOUT <= ram_read_data;
end if;
end process;
end generate;
 
opwire : if not OP_REG generate
DOUT <= ram_read_data;
end generate;
 
end RTL;
 
--pragma translate_on
 
/trunk/mux2_add_reg.vhd
0,0 → 1,173
--
-- 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@opencores.org 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
 
/trunk/add_sub.vhd
0,0 → 1,157
--
-- 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@opencores.org 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
 
/trunk/mux8.vhd
0,0 → 1,224
--
-- 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@opencores.org 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
 
/trunk/idec.vhd
0,0 → 1,170
--
-- 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@opencores.org 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;
/trunk/jumptest.asm
0,0 → 1,313
;
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
/trunk/cpu_tb.vhd
0,0 → 1,330
--
-- 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@opencores.org 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;
 
/trunk/jumptest.hex
0,0 → 1,32
: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
/trunk/pkg_risc5x.vhd
0,0 → 1,80
--
-- 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@opencores.org 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;
/trunk/alubit.vhd
0,0 → 1,109
--
-- 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@opencores.org 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
 
/trunk/alu.vhd
0,0 → 1,126
--
-- 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@opencores.org 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;
 
/trunk/risc5x_xil.ucf
0,0 → 1,53
#--
#-- 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@opencores.org for support or any other issues.
#--
#-- Revision list
#--
#-- version 1.0 initial opencores release
#--
 
CONFIG PART = XCV300E-FG456-8 ;
 
 
NET CLK TNM_NET = clk_cpu;
TIMESPEC TS1 =PERIOD:clk_cpu : 25 ns;
 
TIMESPEC TS11=FROM:PADS:TO:FFS : 8ns;
TIMESPEC TS12=FROM:FFS:TO:PADS : 8ns;
 
AREA_GROUP RISC_GRP RANGE = CLB_R20C1:CLB_R32C10 ;
INST U0 AREA_GROUP = RISC_GRP ;
 
INST U0/PC_MUX2_ADD_REG RLOC_ORIGIN=R27C1;
INST U0/PC_LOAD_MUX RLOC_ORIGIN=R22C1;
INST U0/FILEADDR_MUX RLOC_ORIGIN=R26C2;
INST U0/U_REGS RLOC_ORIGIN=R25C2;
INST U0/SBUS_MUXA RLOC_ORIGIN=R25C6;
INST U0/SBUS_MUXB RLOC_ORIGIN=R25C7;
 
INST U0/ALUA_MUX RLOC_ORIGIN=R25C8;
INST U0/ALUB_MUX RLOC_ORIGIN=R25C8;
 
INST U0/U_ALU/U_ADD_SUB RLOC_ORIGIN=R25C9;
INST U0/U_ALU/U_ALUBIT RLOC_ORIGIN=R29C9;
INST U0/U_ALU/U_MUX4 RLOC_ORIGIN=R24C9;
 
 
 
/trunk/pkg_xilinx_prims.vhd
0,0 → 1,221
--
-- 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@opencores.org 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 : in std_logic;
ci : in std_logic;
o : out std_logic
);
end component;
 
component muxf6
port (
o : OUT std_logic;
i0 : IN std_logic;
i1 : IN std_logic;
s : IN std_logic
);
end component;
 
component muxf5
port (
o : OUT std_logic;
i0 : IN std_logic;
i1 : IN std_logic;
s : IN std_logic
);
end component;
 
component ramb4_s2_s2
--pragma translate_off
generic (
INIT_00 : std_logic_vector (255 downto 0) := x"0000000000000000000000000000000000000000000000000000000000000000";
INIT_01 : std_logic_vector (255 downto 0) := x"0000000000000000000000000000000000000000000000000000000000000000";
INIT_02 : std_logic_vector (255 downto 0) := x"0000000000000000000000000000000000000000000000000000000000000000";
INIT_03 : std_logic_vector (255 downto 0) := x"0000000000000000000000000000000000000000000000000000000000000000";
INIT_04 : std_logic_vector (255 downto 0) := x"0000000000000000000000000000000000000000000000000000000000000000";
INIT_05 : std_logic_vector (255 downto 0) := x"0000000000000000000000000000000000000000000000000000000000000000";
INIT_06 : std_logic_vector (255 downto 0) := x"0000000000000000000000000000000000000000000000000000000000000000";
INIT_07 : std_logic_vector (255 downto 0) := x"0000000000000000000000000000000000000000000000000000000000000000";
INIT_08 : std_logic_vector (255 downto 0) := x"0000000000000000000000000000000000000000000000000000000000000000";
INIT_09 : std_logic_vector (255 downto 0) := x"0000000000000000000000000000000000000000000000000000000000000000";
INIT_0A : std_logic_vector (255 downto 0) := x"0000000000000000000000000000000000000000000000000000000000000000";
INIT_0B : std_logic_vector (255 downto 0) := x"0000000000000000000000000000000000000000000000000000000000000000";
INIT_0C : std_logic_vector (255 downto 0) := x"0000000000000000000000000000000000000000000000000000000000000000";
INIT_0D : std_logic_vector (255 downto 0) := x"0000000000000000000000000000000000000000000000000000000000000000";
INIT_0E : std_logic_vector (255 downto 0) := x"0000000000000000000000000000000000000000000000000000000000000000";
INIT_0F : std_logic_vector (255 downto 0) := x"0000000000000000000000000000000000000000000000000000000000000000"
);
--pragma translate_on
port (
dob : out std_logic_vector (1 downto 0);
dib : in std_logic_vector (1 downto 0);
addrb : in std_logic_vector (10 downto 0);
web : in std_logic;
enb : in std_logic;
rstb : in std_logic;
clkb : in std_logic;
 
doa : out std_logic_vector (1 downto 0);
dia : in std_logic_vector (1 downto 0);
addra : in std_logic_vector (10 downto 0);
wea : in std_logic;
ena : in std_logic;
rsta : in std_logic;
clka : in std_logic
);
end component;
 
end;
 
package body pkg_xilinx_prims is
 
function str2slv (str : string) return std_logic_vector is
variable result : std_logic_vector (str'length*4-1 downto 0);
begin
for i in 0 to str'length-1 loop
case str(str'high-i) is
when '0' => result(i*4+3 downto i*4) := x"0";
when '1' => result(i*4+3 downto i*4) := x"1";
when '2' => result(i*4+3 downto i*4) := x"2";
when '3' => result(i*4+3 downto i*4) := x"3";
when '4' => result(i*4+3 downto i*4) := x"4";
when '5' => result(i*4+3 downto i*4) := x"5";
when '6' => result(i*4+3 downto i*4) := x"6";
when '7' => result(i*4+3 downto i*4) := x"7";
when '8' => result(i*4+3 downto i*4) := x"8";
when '9' => result(i*4+3 downto i*4) := x"9";
when 'a' | 'A' => result(i*4+3 downto i*4) := x"A";
when 'b' | 'B' => result(i*4+3 downto i*4) := x"B";
when 'c' | 'C' => result(i*4+3 downto i*4) := x"C";
when 'd' | 'D' => result(i*4+3 downto i*4) := x"D";
when 'e' | 'E' => result(i*4+3 downto i*4) := x"E";
when 'f' | 'F' => result(i*4+3 downto i*4) := x"F";
when others => result(i*4+3 downto i*4) := "XXXX";
end case;
end loop;
 
return result;
end str2slv;
 
end;
/trunk/cpu.vhd
0,0 → 1,731
--
-- 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@opencores.org 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;
 
/trunk/risc5x_xil.vhd
0,0 → 1,228
--
-- 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@opencores.org for support or any other issues.
--
-- Revision list
--
-- version 1.0 initial opencores release
--
 
-- Top level design for a Xilinx FPGA with a CPU core and some program block ram.
 
use work.pkg_risc5x.all;
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;
 
entity RISC5X_XIL is
port (
I_PRAM_ADDR : in std_logic_vector(10 downto 0);
I_PRAM_DIN : in std_logic_vector(11 downto 0);
O_PRAM_DOUT : out std_logic_vector(11 downto 0);
I_PRAM_WE : in std_logic;
I_PRAM_ENA : in std_logic;
PRAM_CLK : in std_logic;
--
IO_PORTA_IO : inout std_logic_vector(7 downto 0);
IO_PORTB_IO : inout std_logic_vector(7 downto 0);
IO_PORTC_IO : inout std_logic_vector(7 downto 0);
 
O_DEBUG_W : out std_logic_vector(7 downto 0);
O_DEBUG_PC : out std_logic_vector(10 downto 0);
O_DEBUG_INST : out std_logic_vector(11 downto 0);
O_DEBUG_STATUS : out std_logic_vector(7 downto 0);
 
RESET : in std_logic;
CLK : in std_logic
);
end;
 
architecture RTL of RISC5X_XIL is
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 paddr : std_logic_vector(10 downto 0);
signal pdata : std_logic_vector(11 downto 0);
signal pram_addr : std_logic_vector(10 downto 0);
signal pram_din : std_logic_vector(11 downto 0);
signal pram_dout : std_logic_vector(11 downto 0);
signal pram_we : std_logic;
signal pram_ena : std_logic;
 
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 doa_temp : std_logic_vector(11 downto 0);
signal dob_temp : std_logic_vector(11 downto 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
IO_PORTA_IO(i) <= porta_out(i);
else
IO_PORTA_IO(i) <= 'Z';
end if;
 
if (portb_oe_l(i) = '0') then
IO_PORTB_IO(i) <= portb_out(i);
else
IO_PORTB_IO(i) <= 'Z';
end if;
 
if (portc_oe_l(i) = '0') then
IO_PORTC_IO(i) <= portc_out(i);
else
IO_PORTC_IO(i) <= 'Z';
end if;
end loop;
end process;
 
p_drive_ports_in_comb : process(IO_PORTA_IO,IO_PORTB_IO,IO_PORTC_IO)
begin
porta_in <= IO_PORTA_IO;
portb_in <= IO_PORTB_IO;
portc_in <= IO_PORTC_IO;
end process;
 
prams : for i in 0 to 5 generate
attribute INIT_00 of inst : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_01 of inst : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_02 of inst : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_03 of inst : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_04 of inst : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_05 of inst : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_06 of inst : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_07 of inst : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_08 of inst : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_09 of inst : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_0A of inst : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_0B of inst : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_0C of inst : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_0D of inst : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_0E of inst : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_0F of inst : label is "0000000000000000000000000000000000000000000000000000000000000000";
begin
inst : ramb4_s2_s2
port map (
dob => pdata(i*2 +1 downto i*2),
dib => "00",
addrb => paddr,
web => '0',
enb => '1',
rstb => '0',
clkb => CLK,
 
doa => pram_dout(i*2 +1 downto i*2),
dia => pram_din(i*2 +1 downto i*2),
addra => pram_addr,
wea => pram_we,
ena => pram_ena,
rsta => '0',
clka => PRAM_CLK
);
end generate;
 
--p_debug : process
--begin
-- wait until CLK'event and (CLK = '1');
-- O_DEBUG_W <= debug_w;
-- O_DEBUG_PC <= debug_pc;
-- O_DEBUG_INST <= debug_inst;
-- O_DEBUG_STATUS <= debug_status;
--end process;
 
p_pram : process
begin
wait until PRAM_CLK'event and (PRAM_CLK = '1');
pram_addr <= I_PRAM_ADDR;
pram_din <= I_PRAM_DIN;
O_PRAM_DOUT <= pram_dout;
pram_we <= I_PRAM_WE;
pram_ena <= I_PRAM_ENA;
end process;
end RTL;
 
/trunk/hex_conv/jumptest.ucf
0,0 → 1,108
 
 
INST PRAMS_0_INST INIT_00 = 55503BF30C0D0FF0FF0FF0FF0F0F0F0F0F043C0F51F0F418480C3A83E678BB87;
INST PRAMS_0_INST INIT_01 = 000000EF83E3E3E3E3E3E3E3ED3B58FDFF7FF5FF74F9F4F6F57E2D59455F55FD;
INST PRAMS_0_INST INIT_02 = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_0_INST INIT_03 = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_0_INST INIT_04 = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_0_INST INIT_05 = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_0_INST INIT_06 = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_0_INST INIT_07 = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_0_INST INIT_08 = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_0_INST INIT_09 = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_0_INST INIT_0A = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_0_INST INIT_0B = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_0_INST INIT_0C = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_0_INST INIT_0D = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_0_INST INIT_0E = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_0_INST INIT_0F = 0000000000000000000000000000000000000000000000000000000000000000;
 
 
INST PRAMS_1_INST INIT_00 = AAA504474D4D40F40F40F40F4F4F4F4F4005001061000968894D041110442547;
INST PRAMS_1_INST INIT_01 = 000000167EAEAEAEAEAEAEAEA2E8940200B00800B90E0908088161AA8A602A0E;
INST PRAMS_1_INST INIT_02 = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_1_INST INIT_03 = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_1_INST INIT_04 = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_1_INST INIT_05 = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_1_INST INIT_06 = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_1_INST INIT_07 = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_1_INST INIT_08 = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_1_INST INIT_09 = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_1_INST INIT_0A = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_1_INST INIT_0B = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_1_INST INIT_0C = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_1_INST INIT_0D = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_1_INST INIT_0E = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_1_INST INIT_0F = 0000000000000000000000000000000000000000000000000000000000000000;
 
 
INST PRAMS_2_INST INIT_00 = AAA23BC489A88CDAC58CDAC58FAD8FAD8C0A322C49C4C08A94AE7B81EE3B8803;
INST PRAMS_2_INST INIT_01 = 000000C88AAA8AAA8AAA8AAA80AA8AC0ECBEC8EC8BC0CBC8CAAED326BAAC0ACC;
INST PRAMS_2_INST INIT_02 = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_2_INST INIT_03 = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_2_INST INIT_04 = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_2_INST INIT_05 = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_2_INST INIT_06 = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_2_INST INIT_07 = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_2_INST INIT_08 = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_2_INST INIT_09 = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_2_INST INIT_0A = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_2_INST INIT_0B = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_2_INST INIT_0C = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_2_INST INIT_0D = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_2_INST INIT_0E = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_2_INST INIT_0F = 0000000000000000000000000000000000000000000000000000000000000000;
 
 
INST PRAMS_3_INST INIT_00 = FFC0335411110D41D41D00D0011110000D08342D00D0D800028C3380CF330013;
INST PRAMS_3_INST INIT_01 = 000000F000F0F0E0E0D0D0C0C05003D4CCBCC8CCC0DCC8C8CF0CE725789D0ADC;
INST PRAMS_3_INST INIT_02 = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_3_INST INIT_03 = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_3_INST INIT_04 = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_3_INST INIT_05 = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_3_INST INIT_06 = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_3_INST INIT_07 = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_3_INST INIT_08 = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_3_INST INIT_09 = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_3_INST INIT_0A = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_3_INST INIT_0B = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_3_INST INIT_0C = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_3_INST INIT_0D = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_3_INST INIT_0E = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_3_INST INIT_0F = 0000000000000000000000000000000000000000000000000000000000000000;
 
 
INST PRAMS_4_INST INIT_00 = 000020AE00000BE0BE0BE0BE000000000BE02FABE0BEBE000A80200281200000;
INST PRAMS_4_INST INIT_01 = 000000A22F6F6F6F6F6F6F6F620020BEAA0BB0BA40BEA0B0B4082B924D0BEABE;
INST PRAMS_4_INST INIT_02 = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_4_INST INIT_03 = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_4_INST INIT_04 = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_4_INST INIT_05 = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_4_INST INIT_06 = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_4_INST INIT_07 = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_4_INST INIT_08 = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_4_INST INIT_09 = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_4_INST INIT_0A = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_4_INST INIT_0B = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_4_INST INIT_0C = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_4_INST INIT_0D = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_4_INST INIT_0E = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_4_INST INIT_0F = 0000000000000000000000000000000000000000000000000000000000000000;
 
 
INST PRAMS_5_INST INIT_00 = 000CE39C333339C39C39C39C3333333339CCE709C39C9C33390CE3328CE33003;
INST PRAMS_5_INST INIT_01 = 000000A000101010101010101403039C99399399339C93939338E70C30C9C09C;
INST PRAMS_5_INST INIT_02 = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_5_INST INIT_03 = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_5_INST INIT_04 = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_5_INST INIT_05 = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_5_INST INIT_06 = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_5_INST INIT_07 = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_5_INST INIT_08 = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_5_INST INIT_09 = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_5_INST INIT_0A = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_5_INST INIT_0B = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_5_INST INIT_0C = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_5_INST INIT_0D = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_5_INST INIT_0E = 0000000000000000000000000000000000000000000000000000000000000000;
INST PRAMS_5_INST INIT_0F = 0000000000000000000000000000000000000000000000000000000000000000;
/trunk/hex_conv/hex_conv.exe Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
trunk/hex_conv/hex_conv.exe Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: trunk/hex_conv/hex_conv.cpp =================================================================== --- trunk/hex_conv/hex_conv.cpp (nonexistent) +++ trunk/hex_conv/hex_conv.cpp (revision 2) @@ -0,0 +1,191 @@ +// +// 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@opencores.org for support or any other issues. +// +// Revision list +// +// version 1.0 initial opencores release +// + +#include +#include + +#include +#include +#include +#include +#include +using namespace std; + +#define ROM_SIZE 0x800 + +class cLine +{ + string line; +public: + + typedef std::vector List; + cLine(string l) : line(l) {} + string get() {return line;} +}; + +int hex_to_int(string hex, int start, int len) +{ + int result = 0; + + for (int i = start; i < (start + len); i++) { + result <<= 4; + if (hex[i] >= '0' && hex[i] <= '9') + result += (hex[i] - '0'); + else if (hex[i] >= 'A' && hex[i] <= 'F') + result += (hex[i] - 'A') +10; + else if (hex[i] >= 'a' && hex[i] <= 'f') + result += (hex[i] - 'a') +10; + else + { + printf("hex to int error \n"); + exit (1); + } + } + return result; +} + +int main(int argc, char* argv[]) + +{ + // read file + cLine::List l; + string buffer; + ifstream infile; + + if(argc != 2) + { + printf("no input file \n"); + return -1; + } + + infile.open(argv[1]); + if(infile.fail()) { + printf("Could not open input file \n"); + return -1; + } + do + { + std::getline(infile,buffer,infile.widen('\n')); + if(!buffer.empty()) + { + string::size_type sz1 = buffer.find(":"); + if(sz1 != string::npos) + { + sz1+=1; + string::size_type sz2 = buffer.find(";"); + string real(&buffer[sz1]); + l.push_back(cLine(real)); + } + + } + } while(!infile.fail()); + infile.close(); + + // process + int mem[ROM_SIZE]; + string line; + int len = l.size(); + int i,j,k,sum; + int wc,type,data; + int file_addr = 0; + int addr = 0; + int offset = 0; + int mask = 0; + + // clear mem + for (i = 0; i < ROM_SIZE; i++) mem[i] = 0; + + // process file + for (j = 0; j < len-1; j++) { + + line = l[j].get(); + wc = hex_to_int(line,0,2); + file_addr = hex_to_int(line,2,4); + type = hex_to_int(line,6,2); + + sum = 0; + for (i = 0; i < wc*2 + 9; i +=2) { + sum += hex_to_int(line,i,2); + } + if ((sum & 0xff) != 0) + printf("incorrect checksum line %d \n", j+1); + int value = 0; + + if (type == 0) { + for (i = 0; i < wc*2; i +=4) { + value = hex_to_int(line,i + 8,2) + hex_to_int(line,i+10,2) * 256; + mem[addr] = value; + addr ++; + } + } + } + // print attribute statements + /* + for (k = 0; k < 6; k ++){ + mask = 0x3 << (k*2); + + printf("\n\n"); + for (j = 0; j < (ROM_SIZE/128); j++) { + printf("attribute INIT_%02X of inst%d : label is \042",j,k); + for (i = 0; i < 128; i+=4) { + + data = ((mem[(j*128) + (127 - i)] & mask) >> k*2); + data <<= 2; + data += ((mem[(j*128) + (126 - i)] & mask) >> k*2); + data <<= 2; + data += ((mem[(j*128) + (125 - i)] & mask) >> k*2); + data <<= 2; + data += ((mem[(j*128) + (124 - i)] & mask) >> k*2); + printf("%02X",data); + } + printf("\042;\n"); + } + } + */ + + // print ucf statements + for (k = 0; k < 6; k ++){ + mask = 0x3 << (k*2); + + printf("\n\n"); + for (j = 0; j < (ROM_SIZE/128); j++) { + printf("INST PRAMS_%d_INST INIT_%02X = ",k,j); + for (i = 0; i < 128; i+=4) { + + data = ((mem[(j*128) + (127 - i)] & mask) >> k*2); + data <<= 2; + data += ((mem[(j*128) + (126 - i)] & mask) >> k*2); + data <<= 2; + data += ((mem[(j*128) + (125 - i)] & mask) >> k*2); + data <<= 2; + data += ((mem[(j*128) + (124 - i)] & mask) >> k*2); + printf("%02X",data); + } + printf(";\n"); + } + } + + return 0; +} Index: trunk/hex_conv/jumptest.asm =================================================================== --- trunk/hex_conv/jumptest.asm (nonexistent) +++ trunk/hex_conv/jumptest.asm (revision 2) @@ -0,0 +1,313 @@ +; + 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 Index: trunk/hex_conv/readme.txt =================================================================== --- trunk/hex_conv/readme.txt (nonexistent) +++ trunk/hex_conv/readme.txt (revision 2) @@ -0,0 +1,111 @@ +-- +-- 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@opencores.org 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 +-- (cpu.vhd file changed) +-- +-- version 1.0 initial opencores release +-- + +Risc5x is a small RISC CPU written in VHDL that is compatible with the 12 bit +opcode PIC family. Single cycle operation normally, two cycles when the program +counter is modified. Clock speeds of over 40Mhz are possible when using the +Xilinx Virtex optimisations. + + +This program ( hexconv.cpp ) may be used to read in a .HEX program file +and outputs directives to the Xilinx build tools to initialise the program +ram correctly. + +Usage : + +hexconv sourcefile.hex outputs to screen + +hexconv sourcefile.hex > temp.ucf outputs to file temp.ucf + +this will generate 16 x 6 statements like this : + +INST PRAMS_0_INST INIT_00 = 00000000000000000000000000000000000000000000000000000000E9A7B9E4; + +copy these to your RISC5X_XIL.UCF file. Job done. + + +The program source has a commented out section which will produce "attribute +init" statements which may be used in the VHDL code directly. Replace the prams +generate in RISC5X_XIL.vhd with the following. The advantage of this technique +is you can see the correct init's in the EDIF file, and if you have a block ram +simulation model that you can pass INIT generics to, then you can simulate it. + +prams : if true generate + attribute INIT_00 of inst0 : label is "00000000000000000000000000000000000000000000000000000000E9A7B9E4"; + +begin + inst0 : ramb4_s2_s2 + port map ( + dob => pdata(1 downto 0), + dib => "00", + + + doa => pram_dout(1 downto 0), + dia => pram_din(1 downto 0), + + ); + inst1 : ramb4_s2_s2 + port map ( + dob => pdata(3 downto 2), + + + doa => pram_dout(3 downto 2), + dia => pram_din(3 downto 2), + + ); + +end generate; + + +Legal Stuff + +This core 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. + +You are responsible for any legal issues arising from the use of this core. + +The source files may be used and distributed without restriction provided that +all copyright statements are not removed from the files and that any derivative +work contains the original copyright notices and the associated disclaimer. + +PIC is a trademark of Microchip Technology Inc. + + +Any questions or interest in customisation /locked / other cores (16x8x?) etc +feel free to mail. + +mikej@opencores.org + +Cheers + +Mike. + + Index: trunk/hex_conv/jumptest.hex =================================================================== --- trunk/hex_conv/jumptest.hex (nonexistent) +++ trunk/hex_conv/jumptest.hex (revision 2) @@ -0,0 +1,32 @@ +: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 Index: trunk/pkg_prims.vhd =================================================================== --- trunk/pkg_prims.vhd (nonexistent) +++ trunk/pkg_prims.vhd (revision 2) @@ -0,0 +1,140 @@ +-- +-- 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@opencores.org 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; Index: trunk/mux2.vhd =================================================================== --- trunk/mux2.vhd (nonexistent) +++ trunk/mux2.vhd (revision 2) @@ -0,0 +1,132 @@ +-- +-- 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@opencores.org 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 + Index: trunk/readme.txt =================================================================== --- trunk/readme.txt (nonexistent) +++ trunk/readme.txt (revision 2) @@ -0,0 +1,206 @@ +-- +-- 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@opencores.org 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 +-- (cpu.vhd file changed) +-- +-- version 1.0 initial opencores release +-- + +Risc5x is a small RISC CPU written in VHDL that is compatible with the 12 bit +opcode PIC family. Single cycle operation normally, two cycles when the program +counter is modified. Clock speeds of over 40Mhz are possible when using the +Xilinx Virtex optimisations. + + +Legal Stuff + +This core 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. + +You are responsible for any legal issues arising from the use of this core. + +The source files may be used and distributed without restriction provided that +all copyright statements are not removed from the files and that any derivative +work contains the original copyright notices and the associated disclaimer. + +PIC is a trademark of Microchip Technology Inc. + + +Features + +The core has a single pipeline stage and is run from a single clock, so +(ignoring program counter changes) a 40Mhz clock will give 40 MIPS processing +speed. Any instruction which modifies the program counter, for example a branch +or skip, will result in a pipeline stall and this will only cost one additional +clock cycle. + +The CPU architecture chosen is not particularly FPGA friendly, for example +multiplexers are generally quite expensive. The maximum combinatorial path delay +is also long, so to ease the place and route tool's job the core is written at a +low level. It instantiates a number of library macros, for example a 4:1 mux. +Two versions of these are given, one is generic VHDL and the second is optimised +for Xilinx Virtex series (including sparten2's etc). A constraints file locates +the data path macros within the device and ensures an easy fit and high clock +speed. + +Performance & Size + +The core builds to around 110 Virtex CLBS (depending on synthesis). + +>33 Mhz in a Virtex e - 6 +>40 Mhz in a Virtex e - 8 + +There's some good free tools out there including a compiler, simulator and +assembler (gusim & guasm for example). + + +Synthesis & File description : + +Read the files in the following order. + +** PACKAGES ** +pkg_xilinx_prims.vhd (package containing low level Virtex blocks) + only required if using Virtex optimised macros) +pkg_prims.vhd (package containing macro components) +pkg_risc5x.vhd (package containing some useful functions) + +** MACROS / RTL MODELS ** + +mux8.vhd (8 to 1 muxer) +mux4.vhd (4 to 1 muxer) +mux2.vhd (2 to 1 muxer) +mux2_add_reg.vhd (load or +1, used for program counter) +alubit.vhd (ALU bit functions) +add_sub.vhd (add or subtract) + + +IMPORTANT : Each of the macros has TWO ARCHITECTURES, the first (VIRTEX) is for +Virtex series devices ONLY, including Virtex, Virtexe, Sparten2, Sparten2e etc. +The second (RTL) is generic VHDL, and is surrounded by synthesis directives : + + --pragma translate_off + --pragma translate_on + +This makes the synthesis tool ignores the second architecture, but the simulator +does not, resulting in optimal synthesis and fast simulation. + +If you do not wish to target Virtex series devices, YOU MUST remove the --pragma +directives, and (optionally) delete the VIRTEX architecture. + + +A PROBLEM : Some of the macros have generic attributes passed to them to define +bus width etc. Unfortunately when the same macro is used twice with different +generics some synthesis tools do not build a second copy of the macro. The +easiest way round this is to generate EDIF's for each macro that is required, +and then save it with the 'expected name'. + + +For example if the Xilinx tools say they cannot find a mux4_9_0_FALSE then +you would edit the default generics in mux4.vhd to + +entity MUX4 is + generic ( + WIDTH : in natural := 9; + SLICE : in natural := 0; -- 1 left, 0 right + OP_REG : in boolean := FALSE + ); + port ( + + and build it to mux4_9_0_false.edf. + + You may need to build the files with *'s below : + + MUX2_8_1_FALSE.edf default so ok + MUX2_7_1_FALSE.edf * + + + MUX4_8_1_FALSE.edf default so ok + MUX4_8_0_FALSE.edf * + MUX4_9_0_FALSE.edf * + MUX4_11_0_FALSE.edf * + + MUX8_8_FALSE.edf default so ok + + ADD_SUB_8.edf default so ok + ALUBIT_8.edf default so ok + MUX2_ADD_REG_11.edf default so ok + +If you are using Exemplar then you can analyze the whole lot and it gets it +correct. The following works fine : + +analyze mux2_add_reg.vhd +analyze mux2.vhd +analyze mux4.vhd +analyze mux8.vhd +analyze add_sub.vhd +analyze alubit.vhd +analyze idec.vhd +analyze alu.vhd +analyze regs.vhd +analyze cpu.vhd +analyze risc5x_xil.vhd +elaborate risc5x_xil + +** CORE ** + +alu.vhd (ALU block) +idec.vhd (instruction decode) +regs.vhd (register file) +cpu.vhd (CPU top level) + +regs.vhd also has two architectures, one optimised for Virtex and a generic one +as well. The generic version has a simulation model of a dual port ram, +which should be replaced be a synthesizable block. + +** TOP LEVELS ** +risc5x_xil.vhd (xilinx chip complete with program ram) +OR +cpu_tb.vhd (simulation model which loads a .hex program file) + +** OTHER ** +risc5x_xil.ucf (xilinx constraints file) +jumptest.asm (sanity test program) +jumptest.hex (sanity test binary) + +risc5x_xil.VHD is a synthesizable top level that instantiates some Xilinx block +rams. For simulation replace risc5x_xil.vhd with cpu_tb.vhd which has extra +debug. + +Signal inst_string in cpu_tb shows the current instruction being +executed, and pc_t1 the address it came from. (t1 signifies one clock later than +the PC, due to the delay through the program memory) + + +Any questions or interest in customisation /locked / other cores (16x8x?) etc +feel free to mail. + +mikej@opencores.org + +Cheers + +Mike. + + Index: trunk/mux4.vhd =================================================================== --- trunk/mux4.vhd (nonexistent) +++ trunk/mux4.vhd (revision 2) @@ -0,0 +1,168 @@ +-- +-- 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@opencores.org 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

powered by: WebSVN 2.1.0

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