LOGIN   :::   RECOVER PASS   :::   GET ACCOUNT    
Browse
  • Projects
  • Code (CVS)
  • Forums
  • News
  • Articles
  • Polls
  •  
    OpenCores
  • FAQ
  • CVS HowTo
  • Mission
  • Media
  • Tools
  • Sponsors
  • Mirrors
  • Logos
  • Contact us
  •  
    Tools
  • Search
      
  • Download Cores (CVSGet)
  •  
    More
  • Wishbone
  • Perlilog
  • EDA tools
  • OpenTech CD
  •  
    Navigation: All forums > Cvs-checkins > Message List > Message Post

    Message

    Reply | Reply all
    Date Prev | Date Next | Thread Prev | Thread Next Date Index | Thread Index

    From: OpenCores CVS Agent<cvs@o...>
    Date: Sun Jan 30 21:41:42 CET 2005
    Subject: [cvs-checkins] MODIFIED: risc5x ...
    Top
    Date: 00/05/01 30:21:41

    Added: risc5x add_sub.vhd alu.vhd alubit.vhd cpu.vhd cpu_tb.vhd
    idec.vhd jumptest.asm jumptest.hex mux2.vhd
    mux2_add_reg.vhd mux4.vhd mux8.vhd pkg_prims.vhd
    pkg_risc5x.vhd pkg_xilinx_prims.vhd readme.txt
    regs.vhd risc5x_xil.ucf risc5x_xil.vhd
    Log:



    Revision Changes Path
    1.1 risc5x/add_sub.vhd

    http://www.opencores.org/cvsweb.shtml/risc5x/add_sub.vhd?rev=1.1&content-type=text/x-cvsweb-markup

    Index: add_sub.vhd
    ===================================================================
    --
    -- Risc5x
    -- www.OpenCores.Org - November 2001
    --
    --
    -- This library is free software; you can distribute it and/or modify it
    -- under the terms of the GNU Lesser General Public License as published
    -- by the Free Software Foundation; either version 2.1 of the License, or
    -- (at your option) any later version.
    --
    -- This library is distributed in the hope that it will be useful, but
    -- WITHOUT ANY WARRANTY; without even the implied warranty of
    -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    -- See the GNU Lesser General Public License for more details.
    --
    -- A RISC CPU core.
    --
    -- (c) Mike Johnson 2001. All Rights Reserved.
    -- mikej@o... for support or any other issues.
    --
    -- Revision list
    --
    -- version 1.0 initial opencores release
    --
    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.std_logic_arith.all;
    use ieee.std_logic_unsigned.all;

    --
    -- op <= A +/- B or A
    --
    entity ADD_SUB is
    generic (
    WIDTH : in natural := 8
    );
    port (
    A : in std_logic_vector(WIDTH-1 downto 0);
    B : in std_logic_vector(WIDTH-1 downto 0);

    ADD_OR_SUB : in std_logic; -- high for DOUT <= A +/- B, low for DOUT <= A
    DO_SUB : in std_logic; -- high for DOUT <= A - B, low for DOUT <= A + B

    CARRY_OUT : out std_logic_vector(WIDTH-1 downto 0);
    DOUT : out std_logic_vector(WIDTH-1 downto 0)
    );
    end;

    use work.pkg_xilinx_prims.all;
    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.std_logic_arith.all;
    use ieee.std_logic_unsigned.all;

    architecture VIRTEX of ADD_SUB is

    signal lut_op : std_logic_vector(WIDTH-1 downto 0);
    signal mult_and_op : std_logic_vector(WIDTH-1 downto 0);
    signal carry : std_logic_vector(WIDTH downto 0);
    signal op_int : std_logic_vector(WIDTH-1 downto 0);

    function loc(i : integer) return integer is
    begin
    return (((WIDTH+1)/2)-1) - i/2;
    end loc;

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