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

Subversion Repositories mod_sim_exp

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /mod_sim_exp/tags/Release_1.3/rtl/vhdl
    from Rev 77 to Rev 79
    Reverse comparison

Rev 77 → Rev 79

/interface/plb/user_logic.vhd
0,0 → 1,451
------------------------------------------------------------------------------
-- user_logic.vhd - entity/architecture pair
------------------------------------------------------------------------------
--
-- ***************************************************************************
-- ** Copyright (c) 1995-2009 Xilinx, Inc. All rights reserved. **
-- ** **
-- ** Xilinx, Inc. **
-- ** XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" **
-- ** AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND **
-- ** SOLUTIONS FOR XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE, **
-- ** OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, **
-- ** APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION **
-- ** THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT, **
-- ** AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE **
-- ** FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY **
-- ** WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE **
-- ** IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR **
-- ** REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF **
-- ** INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS **
-- ** FOR A PARTICULAR PURPOSE. **
-- ** **
-- ***************************************************************************
--
------------------------------------------------------------------------------
-- Filename: user_logic.vhd
-- Version: 2.00.a
-- Description: User logic.
-- Date: Thu May 03 09:53:36 2012 (by Create and Import Peripheral Wizard)
-- VHDL Standard: VHDL'93
------------------------------------------------------------------------------
-- Naming Conventions:
-- active low signals: "*_n"
-- clock signals: "clk", "clk_div#", "clk_#x"
-- reset signals: "rst", "rst_n"
-- generics: "C_*"
-- user defined types: "*_TYPE"
-- state machine next state: "*_ns"
-- state machine current state: "*_cs"
-- combinatorial signals: "*_com"
-- pipelined or register delay signals: "*_d#"
-- counter signals: "*cnt*"
-- clock enable signals: "*_ce"
-- internal version of output port: "*_i"
-- device pins: "*_pin"
-- ports: "- Names begin with Uppercase"
-- processes: "*_PROCESS"
-- component instantiations: "<ENTITY_>I_<#|FUNC>"
------------------------------------------------------------------------------
 
-- DO NOT EDIT BELOW THIS LINE --------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
 
library proc_common_v3_00_a;
use proc_common_v3_00_a.proc_common_pkg.all;
 
-- DO NOT EDIT ABOVE THIS LINE --------------------
 
--USER libraries added here
library mod_sim_exp;
use mod_sim_exp.mod_sim_exp_pkg.all;
 
------------------------------------------------------------------------------
-- Entity section
------------------------------------------------------------------------------
-- Definition of Generics:
-- C_SLV_AWIDTH -- Slave interface address bus width
-- C_SLV_DWIDTH -- Slave interface data bus width
-- C_NUM_REG -- Number of software accessible registers
-- C_NUM_MEM -- Number of memory spaces
-- C_NUM_INTR -- Number of interrupt event
--
-- Definition of Ports:
-- Bus2IP_Clk -- Bus to IP clock
-- Bus2IP_Reset -- Bus to IP reset
-- Bus2IP_Addr -- Bus to IP address bus
-- Bus2IP_CS -- Bus to IP chip select for user logic memory selection
-- Bus2IP_RNW -- Bus to IP read/not write
-- Bus2IP_Data -- Bus to IP data bus
-- Bus2IP_BE -- Bus to IP byte enables
-- Bus2IP_RdCE -- Bus to IP read chip enable
-- Bus2IP_WrCE -- Bus to IP write chip enable
-- IP2Bus_Data -- IP to Bus data bus
-- IP2Bus_RdAck -- IP to Bus read transfer acknowledgement
-- IP2Bus_WrAck -- IP to Bus write transfer acknowledgement
-- IP2Bus_Error -- IP to Bus error response
-- IP2Bus_IntrEvent -- IP to Bus interrupt event
------------------------------------------------------------------------------
 
entity user_logic is
generic
(
-- ADD USER GENERICS BELOW THIS LINE ---------------
--USER generics added here
-- Multiplier parameters
C_NR_BITS_TOTAL : integer := 1536;
C_NR_STAGES_TOTAL : integer := 96;
C_NR_STAGES_LOW : integer := 32;
C_SPLIT_PIPELINE : boolean := true;
C_FIFO_DEPTH : integer := 32;
C_MEM_STYLE : string := "xil_prim"; -- xil_prim, generic, asym are valid options
C_DEVICE : string := "xilinx"; -- xilinx, altera are valid options
-- ADD USER GENERICS ABOVE THIS LINE ---------------
 
-- DO NOT EDIT BELOW THIS LINE ---------------------
-- Bus protocol parameters, do not add to or delete
C_SLV_AWIDTH : integer := 32;
C_SLV_DWIDTH : integer := 32;
C_NUM_REG : integer := 1;
C_NUM_MEM : integer := 6;
C_NUM_INTR : integer := 1
-- DO NOT EDIT ABOVE THIS LINE ---------------------
);
port
(
-- ADD USER PORTS BELOW THIS LINE ------------------
--USER ports added here
calc_time : out std_logic;
-- ctrl_sigs : out std_logic_vector( downto );
-- ADD USER PORTS ABOVE THIS LINE ------------------
 
-- DO NOT EDIT BELOW THIS LINE ---------------------
-- Bus protocol ports, do not add to or delete
Bus2IP_Clk : in std_logic;
Bus2IP_Reset : in std_logic;
Bus2IP_Addr : in std_logic_vector(0 to C_SLV_AWIDTH-1);
Bus2IP_CS : in std_logic_vector(0 to C_NUM_MEM-1);
Bus2IP_RNW : in std_logic;
Bus2IP_Data : in std_logic_vector(0 to C_SLV_DWIDTH-1);
Bus2IP_BE : in std_logic_vector(0 to C_SLV_DWIDTH/8-1);
Bus2IP_RdCE : in std_logic_vector(0 to C_NUM_REG-1);
Bus2IP_WrCE : in std_logic_vector(0 to C_NUM_REG-1);
IP2Bus_Data : out std_logic_vector(0 to C_SLV_DWIDTH-1);
IP2Bus_RdAck : out std_logic;
IP2Bus_WrAck : out std_logic;
IP2Bus_Error : out std_logic;
IP2Bus_IntrEvent : out std_logic_vector(0 to C_NUM_INTR-1)
-- DO NOT EDIT ABOVE THIS LINE ---------------------
);
 
attribute SIGIS : string;
attribute SIGIS of Bus2IP_Clk : signal is "CLK";
attribute SIGIS of Bus2IP_Reset : signal is "RST";
 
end entity user_logic;
 
------------------------------------------------------------------------------
-- Architecture section
------------------------------------------------------------------------------
 
architecture IMP of user_logic is
 
--USER signal declarations added here, as needed for user logic
 
------------------------------------------------------------------
-- Signals for multiplier core slave model s/w accessible register
------------------------------------------------------------------
signal slv_reg0 : std_logic_vector(0 to C_SLV_DWIDTH-1);
signal slv_reg_write_sel : std_logic_vector(0 to 0);
signal slv_reg_read_sel : std_logic_vector(0 to 0);
signal slv_ip2bus_data : std_logic_vector(0 to C_SLV_DWIDTH-1);
signal slv_read_ack : std_logic;
signal slv_write_ack : std_logic;
 
signal load_flags : std_logic;
 
------------------------------------------------------------------
-- Signals for multiplier core interrupt
------------------------------------------------------------------
signal core_interrupt : std_logic_vector(0 to 0);
signal core_fifo_full : std_logic;
signal core_fifo_nopush : std_logic;
signal core_ready : std_logic;
signal core_mem_collision : std_logic;
 
------------------------------------------------------------------
-- Signals for multiplier core control
------------------------------------------------------------------
signal core_start : std_logic;
signal core_exp_m : std_logic;
signal core_p_sel : std_logic_vector(1 downto 0);
signal core_dest_op_single : std_logic_vector(1 downto 0);
signal core_x_sel_single : std_logic_vector(1 downto 0);
signal core_y_sel_single : std_logic_vector(1 downto 0);
signal core_flags : std_logic_vector(15 downto 0);
signal core_modulus_sel : std_logic;
 
------------------------------------------------------------------
-- Signals for multiplier core memory space
------------------------------------------------------------------
signal mem_address : std_logic_vector(0 to 5);
signal mem_select : std_logic_vector(0 to 5);
signal mem_read_enable : std_logic;
signal mem_read_enable_dly1 : std_logic;
signal mem_read_req : std_logic;
signal mem_ip2bus_data : std_logic_vector(0 to C_SLV_DWIDTH-1);
signal mem_read_ack_dly1 : std_logic;
signal mem_read_ack : std_logic;
signal mem_write_ack : std_logic;
 
signal core_rw_address : std_logic_vector (8 downto 0);
signal core_data_in : std_logic_vector(31 downto 0);
signal core_fifo_din : std_logic_vector(31 downto 0);
signal sel_mno : std_logic;
signal sel_op : std_logic_vector(1 downto 0);
signal core_data_out : std_logic_vector(31 downto 0);
signal core_write_enable : std_logic;
signal core_fifo_push : std_logic;
begin
 
--USER logic implementation added here
--ctrl_sigs <=
 
------------------------------------------
-- Example code to read/write user logic slave model s/w accessible registers
--
-- Note:
-- The example code presented here is to show you one way of reading/writing
-- software accessible registers implemented in the user logic slave model.
-- Each bit of the Bus2IP_WrCE/Bus2IP_RdCE signals is configured to correspond
-- to one software accessible register by the top level template. For example,
-- if you have four 32 bit software accessible registers in the user logic,
-- you are basically operating on the following memory mapped registers:
--
-- Bus2IP_WrCE/Bus2IP_RdCE Memory Mapped Register
-- "1000" C_BASEADDR + 0x0
-- "0100" C_BASEADDR + 0x4
-- "0010" C_BASEADDR + 0x8
-- "0001" C_BASEADDR + 0xC
--
------------------------------------------
slv_reg_write_sel <= Bus2IP_WrCE(0 to 0);
slv_reg_read_sel <= Bus2IP_RdCE(0 to 0);
slv_write_ack <= Bus2IP_WrCE(0);
slv_read_ack <= Bus2IP_RdCE(0);
 
-- implement slave model software accessible register(s)
SLAVE_REG_WRITE_PROC : process( Bus2IP_Clk ) is
begin
if Bus2IP_Clk'event and Bus2IP_Clk = '1' then
if Bus2IP_Reset = '1' then
slv_reg0 <= (others => '0');
elsif load_flags = '1' then
slv_reg0 <= slv_reg0(0 to 15) & core_flags;
else
case slv_reg_write_sel is
when "1" =>
for byte_index in 0 to (C_SLV_DWIDTH/8)-1 loop
if ( Bus2IP_BE(byte_index) = '1' ) then
slv_reg0(byte_index*8 to byte_index*8+7) <= Bus2IP_Data(byte_index*8 to byte_index*8+7);
end if;
end loop;
when others => null;
end case;
end if;
end if;
 
end process SLAVE_REG_WRITE_PROC;
 
-- implement slave model software accessible register(s) read mux
SLAVE_REG_READ_PROC : process( slv_reg_read_sel, slv_reg0 ) is
begin
 
case slv_reg_read_sel is
when "1" => slv_ip2bus_data <= slv_reg0;
when others => slv_ip2bus_data <= (others => '0');
end case;
 
end process SLAVE_REG_READ_PROC;
 
------------------------------------------
-- Multiplier core interrupts form IP core interrupt
------------------------------------------
 
core_interrupt(0) <= core_ready or core_mem_collision or core_fifo_full or core_fifo_nopush;
IP2Bus_IntrEvent <= core_interrupt;
 
FLAGS_CNTRL_PROC: process(Bus2IP_Clk, Bus2IP_Reset) is
begin
if Bus2IP_Reset = '1' then
core_flags <= (others => '0');
load_flags <= '0';
elsif rising_edge(Bus2IP_Clk) then
if core_start = '1' then
core_flags <= (others => '0');
else
if core_ready = '1' then
core_flags(15) <= '1';
else
core_flags(15) <= core_flags(15);
end if;
if core_mem_collision = '1' then
core_flags(14) <= '1';
else
core_flags(14) <= core_flags(14);
end if;
if core_fifo_full = '1' then
core_flags(13) <= '1';
else
core_flags(13) <= core_flags(13);
end if;
if core_fifo_nopush = '1' then
core_flags(12) <= '1';
else
core_flags(12) <= core_flags(12);
end if;
end if;
--
load_flags <= core_interrupt(0);
end if;
end process FLAGS_CNTRL_PROC;
 
------------------------------------------
-- Example code to access user logic memory region
--
-- Note:
-- The example code presented here is to show you one way of using
-- the user logic memory space features. The Bus2IP_Addr, Bus2IP_CS,
-- and Bus2IP_RNW IPIC signals are dedicated to these user logic
-- memory spaces. Each user logic memory space has its own address
-- range and is allocated one bit on the Bus2IP_CS signal to indicated
-- selection of that memory space. Typically these user logic memory
-- spaces are used to implement memory controller type cores, but it
-- can also be used in cores that need to access additional address space
-- (non C_BASEADDR based), s.t. bridges. This code snippet infers
-- 6 256x32-bit (byte accessible) single-port Block RAM by XST.
------------------------------------------
mem_select <= Bus2IP_CS;
mem_read_enable <= ( Bus2IP_CS(0) or Bus2IP_CS(1) or Bus2IP_CS(2) or Bus2IP_CS(3) or Bus2IP_CS(4) or Bus2IP_CS(5) ) and Bus2IP_RNW;
mem_read_ack <= mem_read_ack_dly1;
mem_write_ack <= ( Bus2IP_CS(0) or Bus2IP_CS(1) or Bus2IP_CS(2) or Bus2IP_CS(3) or Bus2IP_CS(4) or Bus2IP_CS(5) ) and not(Bus2IP_RNW);
mem_address <= Bus2IP_Addr(C_SLV_AWIDTH-8 to C_SLV_AWIDTH-3);
 
-- implement single clock wide read request
mem_read_req <= mem_read_enable and not(mem_read_enable_dly1);
BRAM_RD_REQ_PROC : process( Bus2IP_Clk ) is
begin
 
if ( Bus2IP_Clk'event and Bus2IP_Clk = '1' ) then
if ( Bus2IP_Reset = '1' ) then
mem_read_enable_dly1 <= '0';
else
mem_read_enable_dly1 <= mem_read_enable;
end if;
end if;
 
end process BRAM_RD_REQ_PROC;
 
-- this process generates the read acknowledge 1 clock after read enable
-- is presented to the BRAM block. The BRAM block has a 1 clock delay
-- from read enable to data out.
BRAM_RD_ACK_PROC : process( Bus2IP_Clk ) is
begin
 
if ( Bus2IP_Clk'event and Bus2IP_Clk = '1' ) then
if ( Bus2IP_Reset = '1' ) then
mem_read_ack_dly1 <= '0';
else
mem_read_ack_dly1 <= mem_read_req;
end if;
end if;
 
end process BRAM_RD_ACK_PROC;
 
-- address logic
Sel_MNO <= mem_select(0);
with mem_select(1 to 4) select
Sel_Op <= "00" when "1000",
"01" when "0100",
"10" when "0010",
"11" when others;
core_rw_address <= Sel_MNO & Sel_Op & mem_address;
-- data-in
core_data_in <= Bus2IP_Data;
core_fifo_din <= Bus2IP_Data;
core_write_enable <= (Bus2IP_CS(0) or Bus2IP_CS(1) or Bus2IP_CS(2) or Bus2IP_CS(3) or Bus2IP_CS(4)) and (not Bus2IP_RNW);
core_fifo_push <= Bus2IP_CS(5) and (not Bus2IP_RNW);
-- no read mux required, we can only read from core_data_out
mem_ip2bus_data <= core_data_out;
 
------------------------------------------
-- Map slv_reg0 bits to core control signals
------------------------------------------
core_p_sel <= slv_reg0(0 to 1);
core_dest_op_single <= slv_reg0(2 to 3);
core_x_sel_single <= slv_reg0(4 to 5);
core_y_sel_single <= slv_reg0(6 to 7);
core_start <= slv_reg0(8);
core_exp_m <= slv_reg0(9);
core_modulus_sel <= slv_reg0(10);
 
------------------------------------------
-- Multiplier core instance
------------------------------------------
the_multiplier: mod_sim_exp_core
generic map(
C_NR_BITS_TOTAL => C_NR_BITS_TOTAL,
C_NR_STAGES_TOTAL => C_NR_STAGES_TOTAL,
C_NR_STAGES_LOW => C_NR_STAGES_LOW,
C_SPLIT_PIPELINE => C_SPLIT_PIPELINE,
C_FIFO_DEPTH => C_FIFO_DEPTH,
C_MEM_STYLE => C_MEM_STYLE,
C_DEVICE => C_DEVICE
)
port map(
clk => Bus2IP_Clk,
reset => Bus2IP_Reset,
-- operand memory interface (plb shared memory)
write_enable => core_write_enable,
data_in => core_data_in,
rw_address => core_rw_address,
data_out => core_data_out,
collision => core_mem_collision,
-- op_sel fifo interface
fifo_din => core_fifo_din,
fifo_push => core_fifo_push,
fifo_full => core_fifo_full,
fifo_nopush => core_fifo_nopush,
-- ctrl signals
start => core_start,
exp_m => core_exp_m,
ready => core_ready,
x_sel_single => core_x_sel_single,
y_sel_single => core_y_sel_single,
dest_op_single => core_dest_op_single,
p_sel => core_p_sel,
calc_time => calc_time,
modulus_sel => core_modulus_sel
);
 
 
------------------------------------------
-- Drive IP to Bus signals
------------------------------------------
IP2Bus_Data <= slv_ip2bus_data when slv_read_ack = '1' else
mem_ip2bus_data when mem_read_ack = '1' else
(others => '0');
 
IP2Bus_WrAck <= slv_write_ack or mem_write_ack;
IP2Bus_RdAck <= slv_read_ack or mem_read_ack;
IP2Bus_Error <= '0';
 
end IMP;
/interface/plb/mod_sim_exp_IPcore.vhd
0,0 → 1,645
------------------------------------------------------------------------------
-- mod_sim_exp_IPcore.vhd - entity/architecture pair
------------------------------------------------------------------------------
-- IMPORTANT:
-- DO NOT MODIFY THIS FILE EXCEPT IN THE DESIGNATED SECTIONS.
--
-- SEARCH FOR --USER TO DETERMINE WHERE CHANGES ARE ALLOWED.
--
-- TYPICALLY, THE ONLY ACCEPTABLE CHANGES INVOLVE ADDING NEW
-- PORTS AND GENERICS THAT GET PASSED THROUGH TO THE INSTANTIATION
-- OF THE USER_LOGIC ENTITY.
------------------------------------------------------------------------------
--
-- ***************************************************************************
-- ** Copyright (c) 1995-2009 Xilinx, Inc. All rights reserved. **
-- ** **
-- ** Xilinx, Inc. **
-- ** XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" **
-- ** AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND **
-- ** SOLUTIONS FOR XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE, **
-- ** OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, **
-- ** APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION **
-- ** THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT, **
-- ** AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE **
-- ** FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY **
-- ** WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE **
-- ** IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR **
-- ** REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF **
-- ** INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS **
-- ** FOR A PARTICULAR PURPOSE. **
-- ** **
-- ***************************************************************************
--
------------------------------------------------------------------------------
-- Filename: mod_sim_exp_IPcore.vhd
-- Version: 0.20
-- Description: Top level design, instantiates library components and user logic.
-- Date: Thu May 03 09:53:36 2012 (by Create and Import Peripheral Wizard)
-- VHDL Standard: VHDL'93
------------------------------------------------------------------------------
-- Naming Conventions:
-- active low signals: "*_n"
-- clock signals: "clk", "clk_div#", "clk_#x"
-- reset signals: "rst", "rst_n"
-- generics: "C_*"
-- user defined types: "*_TYPE"
-- state machine next state: "*_ns"
-- state machine current state: "*_cs"
-- combinatorial signals: "*_com"
-- pipelined or register delay signals: "*_d#"
-- counter signals: "*cnt*"
-- clock enable signals: "*_ce"
-- internal version of output port: "*_i"
-- device pins: "*_pin"
-- ports: "- Names begin with Uppercase"
-- processes: "*_PROCESS"
-- component instantiations: "<ENTITY_>I_<#|FUNC>"
------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
 
library proc_common_v3_00_a;
use proc_common_v3_00_a.proc_common_pkg.all;
use proc_common_v3_00_a.ipif_pkg.all;
use proc_common_v3_00_a.soft_reset;
 
library interrupt_control_v2_01_a;
use interrupt_control_v2_01_a.interrupt_control;
 
library plbv46_slave_single_v1_01_a;
use plbv46_slave_single_v1_01_a.plbv46_slave_single;
 
library mod_sim_exp;
use mod_sim_exp.user_logic;
 
------------------------------------------------------------------------------
-- Entity section
------------------------------------------------------------------------------
-- Definition of Generics:
-- C_BASEADDR -- PLBv46 slave: base address
-- C_HIGHADDR -- PLBv46 slave: high address
-- C_SPLB_AWIDTH -- PLBv46 slave: address bus width
-- C_SPLB_DWIDTH -- PLBv46 slave: data bus width
-- C_SPLB_NUM_MASTERS -- PLBv46 slave: Number of masters
-- C_SPLB_MID_WIDTH -- PLBv46 slave: master ID bus width
-- C_SPLB_NATIVE_DWIDTH -- PLBv46 slave: internal native data bus width
-- C_SPLB_P2P -- PLBv46 slave: point to point interconnect scheme
-- C_SPLB_SUPPORT_BURSTS -- PLBv46 slave: support bursts
-- C_SPLB_SMALLEST_MASTER -- PLBv46 slave: width of the smallest master
-- C_SPLB_CLK_PERIOD_PS -- PLBv46 slave: bus clock in picoseconds
-- C_INCLUDE_DPHASE_TIMER -- PLBv46 slave: Data Phase Timer configuration; 0 = exclude timer, 1 = include timer
-- C_FAMILY -- Xilinx FPGA family
-- C_MEM0_BASEADDR -- User memory space 0 base address
-- C_MEM0_HIGHADDR -- User memory space 0 high address
-- C_MEM1_BASEADDR -- User memory space 1 base address
-- C_MEM1_HIGHADDR -- User memory space 1 high address
-- C_MEM2_BASEADDR -- User memory space 2 base address
-- C_MEM2_HIGHADDR -- User memory space 2 high address
-- C_MEM3_BASEADDR -- User memory space 3 base address
-- C_MEM3_HIGHADDR -- User memory space 3 high address
-- C_MEM4_BASEADDR -- User memory space 4 base address
-- C_MEM4_HIGHADDR -- User memory space 4 high address
-- C_MEM5_BASEADDR -- User memory space 5 base address
-- C_MEM5_HIGHADDR -- User memory space 5 high address
--
-- Definition of Ports:
-- SPLB_Clk -- PLB main bus clock
-- SPLB_Rst -- PLB main bus reset
-- PLB_ABus -- PLB address bus
-- PLB_UABus -- PLB upper address bus
-- PLB_PAValid -- PLB primary address valid indicator
-- PLB_SAValid -- PLB secondary address valid indicator
-- PLB_rdPrim -- PLB secondary to primary read request indicator
-- PLB_wrPrim -- PLB secondary to primary write request indicator
-- PLB_masterID -- PLB current master identifier
-- PLB_abort -- PLB abort request indicator
-- PLB_busLock -- PLB bus lock
-- PLB_RNW -- PLB read/not write
-- PLB_BE -- PLB byte enables
-- PLB_MSize -- PLB master data bus size
-- PLB_size -- PLB transfer size
-- PLB_type -- PLB transfer type
-- PLB_lockErr -- PLB lock error indicator
-- PLB_wrDBus -- PLB write data bus
-- PLB_wrBurst -- PLB burst write transfer indicator
-- PLB_rdBurst -- PLB burst read transfer indicator
-- PLB_wrPendReq -- PLB write pending bus request indicator
-- PLB_rdPendReq -- PLB read pending bus request indicator
-- PLB_wrPendPri -- PLB write pending request priority
-- PLB_rdPendPri -- PLB read pending request priority
-- PLB_reqPri -- PLB current request priority
-- PLB_TAttribute -- PLB transfer attribute
-- Sl_addrAck -- Slave address acknowledge
-- Sl_SSize -- Slave data bus size
-- Sl_wait -- Slave wait indicator
-- Sl_rearbitrate -- Slave re-arbitrate bus indicator
-- Sl_wrDAck -- Slave write data acknowledge
-- Sl_wrComp -- Slave write transfer complete indicator
-- Sl_wrBTerm -- Slave terminate write burst transfer
-- Sl_rdDBus -- Slave read data bus
-- Sl_rdWdAddr -- Slave read word address
-- Sl_rdDAck -- Slave read data acknowledge
-- Sl_rdComp -- Slave read transfer complete indicator
-- Sl_rdBTerm -- Slave terminate read burst transfer
-- Sl_MBusy -- Slave busy indicator
-- Sl_MWrErr -- Slave write error indicator
-- Sl_MRdErr -- Slave read error indicator
-- Sl_MIRQ -- Slave interrupt indicator
-- IP2INTC_Irpt -- Interrupt output to processor
------------------------------------------------------------------------------
 
entity mod_sim_exp_IPcore is
generic
(
-- ADD USER GENERICS BELOW THIS LINE ---------------
--USER generics added here
-- Multiplier parameters
C_NR_BITS_TOTAL : integer := 1536;
C_NR_STAGES_TOTAL : integer := 96;
C_NR_STAGES_LOW : integer := 32;
C_SPLIT_PIPELINE : boolean := true;
C_FIFO_DEPTH : integer := 32;
C_MEM_STYLE : string := "xil_prim"; -- xil_prim, generic, asym are valid options
C_DEVICE : string := "xilinx"; -- xilinx, altera are valid options
-- ADD USER GENERICS ABOVE THIS LINE ---------------
 
-- DO NOT EDIT BELOW THIS LINE ---------------------
-- Bus protocol parameters, do not add to or delete
C_BASEADDR : std_logic_vector := X"FFFFFFFF";
C_HIGHADDR : std_logic_vector := X"00000000";
C_SPLB_AWIDTH : integer := 32;
C_SPLB_DWIDTH : integer := 128;
C_SPLB_NUM_MASTERS : integer := 8;
C_SPLB_MID_WIDTH : integer := 3;
C_SPLB_NATIVE_DWIDTH : integer := 32;
C_SPLB_P2P : integer := 0;
C_SPLB_SUPPORT_BURSTS : integer := 0;
C_SPLB_SMALLEST_MASTER : integer := 32;
C_SPLB_CLK_PERIOD_PS : integer := 10000;
C_INCLUDE_DPHASE_TIMER : integer := 0;
C_FAMILY : string := "virtex5";
C_M_BASEADDR : std_logic_vector := X"FFFFFFFF";
C_M_HIGHADDR : std_logic_vector := X"00000000";
C_OP0_BASEADDR : std_logic_vector := X"FFFFFFFF";
C_OP0_HIGHADDR : std_logic_vector := X"00000000";
C_OP1_BASEADDR : std_logic_vector := X"FFFFFFFF";
C_OP1_HIGHADDR : std_logic_vector := X"00000000";
C_OP2_BASEADDR : std_logic_vector := X"FFFFFFFF";
C_OP2_HIGHADDR : std_logic_vector := X"00000000";
C_OP3_BASEADDR : std_logic_vector := X"FFFFFFFF";
C_OP3_HIGHADDR : std_logic_vector := X"00000000";
C_FIFO_BASEADDR : std_logic_vector := X"FFFFFFFF";
C_FIFO_HIGHADDR : std_logic_vector := X"00000000"
-- DO NOT EDIT ABOVE THIS LINE ---------------------
);
port
(
-- ADD USER PORTS BELOW THIS LINE ------------------
--USER ports added here
calc_time : out std_logic;
-- ADD USER PORTS ABOVE THIS LINE ------------------
 
-- DO NOT EDIT BELOW THIS LINE ---------------------
-- Bus protocol ports, do not add to or delete
SPLB_Clk : in std_logic;
SPLB_Rst : in std_logic;
PLB_ABus : in std_logic_vector(0 to 31);
PLB_UABus : in std_logic_vector(0 to 31);
PLB_PAValid : in std_logic;
PLB_SAValid : in std_logic;
PLB_rdPrim : in std_logic;
PLB_wrPrim : in std_logic;
PLB_masterID : in std_logic_vector(0 to C_SPLB_MID_WIDTH-1);
PLB_abort : in std_logic;
PLB_busLock : in std_logic;
PLB_RNW : in std_logic;
PLB_BE : in std_logic_vector(0 to C_SPLB_DWIDTH/8-1);
PLB_MSize : in std_logic_vector(0 to 1);
PLB_size : in std_logic_vector(0 to 3);
PLB_type : in std_logic_vector(0 to 2);
PLB_lockErr : in std_logic;
PLB_wrDBus : in std_logic_vector(0 to C_SPLB_DWIDTH-1);
PLB_wrBurst : in std_logic;
PLB_rdBurst : in std_logic;
PLB_wrPendReq : in std_logic;
PLB_rdPendReq : in std_logic;
PLB_wrPendPri : in std_logic_vector(0 to 1);
PLB_rdPendPri : in std_logic_vector(0 to 1);
PLB_reqPri : in std_logic_vector(0 to 1);
PLB_TAttribute : in std_logic_vector(0 to 15);
Sl_addrAck : out std_logic;
Sl_SSize : out std_logic_vector(0 to 1);
Sl_wait : out std_logic;
Sl_rearbitrate : out std_logic;
Sl_wrDAck : out std_logic;
Sl_wrComp : out std_logic;
Sl_wrBTerm : out std_logic;
Sl_rdDBus : out std_logic_vector(0 to C_SPLB_DWIDTH-1);
Sl_rdWdAddr : out std_logic_vector(0 to 3);
Sl_rdDAck : out std_logic;
Sl_rdComp : out std_logic;
Sl_rdBTerm : out std_logic;
Sl_MBusy : out std_logic_vector(0 to C_SPLB_NUM_MASTERS-1);
Sl_MWrErr : out std_logic_vector(0 to C_SPLB_NUM_MASTERS-1);
Sl_MRdErr : out std_logic_vector(0 to C_SPLB_NUM_MASTERS-1);
Sl_MIRQ : out std_logic_vector(0 to C_SPLB_NUM_MASTERS-1);
IP2INTC_Irpt : out std_logic
-- DO NOT EDIT ABOVE THIS LINE ---------------------
);
 
attribute SIGIS : string;
attribute SIGIS of SPLB_Clk : signal is "CLK";
attribute SIGIS of SPLB_Rst : signal is "RST";
attribute SIGIS of IP2INTC_Irpt : signal is "INTR_LEVEL_HIGH";
 
end entity mod_sim_exp_IPcore;
 
------------------------------------------------------------------------------
-- Architecture section
------------------------------------------------------------------------------
 
architecture IMP of mod_sim_exp_IPcore is
 
------------------------------------------
-- Array of base/high address pairs for each address range
------------------------------------------
constant ZERO_ADDR_PAD : std_logic_vector(0 to 31) := (others => '0');
constant USER_SLV_BASEADDR : std_logic_vector := C_BASEADDR or X"00000000";
constant USER_SLV_HIGHADDR : std_logic_vector := C_BASEADDR or X"000000FF";
constant RST_BASEADDR : std_logic_vector := C_BASEADDR or X"00000100";
constant RST_HIGHADDR : std_logic_vector := C_BASEADDR or X"000001FF";
constant INTR_BASEADDR : std_logic_vector := C_BASEADDR or X"00000200";
constant INTR_HIGHADDR : std_logic_vector := C_BASEADDR or X"000002FF";
 
constant IPIF_ARD_ADDR_RANGE_ARRAY : SLV64_ARRAY_TYPE :=
(
ZERO_ADDR_PAD & USER_SLV_BASEADDR, -- user logic slave space base address
ZERO_ADDR_PAD & USER_SLV_HIGHADDR, -- user logic slave space high address
ZERO_ADDR_PAD & RST_BASEADDR, -- soft reset space base address
ZERO_ADDR_PAD & RST_HIGHADDR, -- soft reset space high address
ZERO_ADDR_PAD & INTR_BASEADDR, -- interrupt control space base address
ZERO_ADDR_PAD & INTR_HIGHADDR, -- interrupt control space high address
ZERO_ADDR_PAD & C_M_BASEADDR, -- user logic memory space 0 base address
ZERO_ADDR_PAD & C_M_HIGHADDR, -- user logic memory space 0 high address
ZERO_ADDR_PAD & C_OP0_BASEADDR, -- user logic memory space 1 base address
ZERO_ADDR_PAD & C_OP0_HIGHADDR, -- user logic memory space 1 high address
ZERO_ADDR_PAD & C_OP1_BASEADDR, -- user logic memory space 2 base address
ZERO_ADDR_PAD & C_OP1_HIGHADDR, -- user logic memory space 2 high address
ZERO_ADDR_PAD & C_OP2_BASEADDR, -- user logic memory space 3 base address
ZERO_ADDR_PAD & C_OP2_HIGHADDR, -- user logic memory space 3 high address
ZERO_ADDR_PAD & C_OP3_BASEADDR, -- user logic memory space 4 base address
ZERO_ADDR_PAD & C_OP3_HIGHADDR, -- user logic memory space 4 high address
ZERO_ADDR_PAD & C_FIFO_BASEADDR, -- user logic memory space 5 base address
ZERO_ADDR_PAD & C_FIFO_HIGHADDR -- user logic memory space 5 high address
);
 
------------------------------------------
-- Array of desired number of chip enables for each address range
------------------------------------------
constant USER_SLV_NUM_REG : integer := 1;
constant USER_NUM_REG : integer := USER_SLV_NUM_REG;
constant RST_NUM_CE : integer := 1;
constant INTR_NUM_CE : integer := 16;
constant USER_NUM_MEM : integer := 6;
 
constant IPIF_ARD_NUM_CE_ARRAY : INTEGER_ARRAY_TYPE :=
(
0 => pad_power2(USER_SLV_NUM_REG), -- number of ce for user logic slave space
1 => RST_NUM_CE, -- number of ce for soft reset space
2 => INTR_NUM_CE, -- number of ce for interrupt control space
3 => 1, -- number of ce for user logic memory space 0 (always 1 chip enable)
4 => 1, -- number of ce for user logic memory space 1 (always 1 chip enable)
5 => 1, -- number of ce for user logic memory space 2 (always 1 chip enable)
6 => 1, -- number of ce for user logic memory space 3 (always 1 chip enable)
7 => 1, -- number of ce for user logic memory space 4 (always 1 chip enable)
8 => 1 -- number of ce for user logic memory space 5 (always 1 chip enable)
);
 
------------------------------------------
-- Ratio of bus clock to core clock (for use in dual clock systems)
-- 1 = ratio is 1:1
-- 2 = ratio is 2:1
------------------------------------------
constant IPIF_BUS2CORE_CLK_RATIO : integer := 1;
 
------------------------------------------
-- Width of the slave data bus (32 only)
------------------------------------------
constant USER_SLV_DWIDTH : integer := C_SPLB_NATIVE_DWIDTH;
 
constant IPIF_SLV_DWIDTH : integer := C_SPLB_NATIVE_DWIDTH;
 
------------------------------------------
-- Width of triggered reset in bus clocks
------------------------------------------
constant RESET_WIDTH : integer := 4;
 
------------------------------------------
-- Number of device level interrupts
------------------------------------------
constant INTR_NUM_IPIF_IRPT_SRC : integer := 4;
 
------------------------------------------
-- Capture mode for each IP interrupt (generated by user logic)
-- 1 = pass through (non-inverting)
-- 2 = pass through (inverting)
-- 3 = registered level (non-inverting)
-- 4 = registered level (inverting)
-- 5 = positive edge detect
-- 6 = negative edge detect
------------------------------------------
constant USER_NUM_INTR : integer := 1;
constant USER_INTR_CAPTURE_MODE : integer := 1;
 
constant INTR_IP_INTR_MODE_ARRAY : INTEGER_ARRAY_TYPE :=
(
0 => USER_INTR_CAPTURE_MODE
);
 
------------------------------------------
-- Device priority encoder feature inclusion/omission
-- true = include priority encoder
-- false = omit priority encoder
------------------------------------------
constant INTR_INCLUDE_DEV_PENCODER : boolean := false;
 
------------------------------------------
-- Device ISC feature inclusion/omission
-- true = include device ISC
-- false = omit device ISC
------------------------------------------
constant INTR_INCLUDE_DEV_ISC : boolean := false;
 
------------------------------------------
-- Width of the slave address bus (32 only)
------------------------------------------
constant USER_SLV_AWIDTH : integer := C_SPLB_AWIDTH;
 
------------------------------------------
-- Index for CS/CE
------------------------------------------
constant USER_SLV_CS_INDEX : integer := 0;
constant USER_SLV_CE_INDEX : integer := calc_start_ce_index(IPIF_ARD_NUM_CE_ARRAY, USER_SLV_CS_INDEX);
constant RST_CS_INDEX : integer := 1;
constant RST_CE_INDEX : integer := calc_start_ce_index(IPIF_ARD_NUM_CE_ARRAY, RST_CS_INDEX);
constant INTR_CS_INDEX : integer := 2;
constant INTR_CE_INDEX : integer := calc_start_ce_index(IPIF_ARD_NUM_CE_ARRAY, INTR_CS_INDEX);
constant USER_MEM0_CS_INDEX : integer := 3;
constant USER_CS_INDEX : integer := USER_MEM0_CS_INDEX;
 
constant USER_CE_INDEX : integer := USER_SLV_CE_INDEX;
 
------------------------------------------
-- IP Interconnect (IPIC) signal declarations
------------------------------------------
signal ipif_Bus2IP_Clk : std_logic;
signal ipif_Bus2IP_Reset : std_logic;
signal ipif_IP2Bus_Data : std_logic_vector(0 to IPIF_SLV_DWIDTH-1);
signal ipif_IP2Bus_WrAck : std_logic;
signal ipif_IP2Bus_RdAck : std_logic;
signal ipif_IP2Bus_Error : std_logic;
signal ipif_Bus2IP_Addr : std_logic_vector(0 to C_SPLB_AWIDTH-1);
signal ipif_Bus2IP_Data : std_logic_vector(0 to IPIF_SLV_DWIDTH-1);
signal ipif_Bus2IP_RNW : std_logic;
signal ipif_Bus2IP_BE : std_logic_vector(0 to IPIF_SLV_DWIDTH/8-1);
signal ipif_Bus2IP_CS : std_logic_vector(0 to ((IPIF_ARD_ADDR_RANGE_ARRAY'length)/2)-1);
signal ipif_Bus2IP_RdCE : std_logic_vector(0 to calc_num_ce(IPIF_ARD_NUM_CE_ARRAY)-1);
signal ipif_Bus2IP_WrCE : std_logic_vector(0 to calc_num_ce(IPIF_ARD_NUM_CE_ARRAY)-1);
signal rst_Bus2IP_Reset : std_logic;
signal rst_IP2Bus_WrAck : std_logic;
signal rst_IP2Bus_Error : std_logic;
signal intr_IPIF_Reg_Interrupts : std_logic_vector(0 to 1);
signal intr_IPIF_Lvl_Interrupts : std_logic_vector(0 to INTR_NUM_IPIF_IRPT_SRC-1);
signal intr_IP2Bus_Data : std_logic_vector(0 to IPIF_SLV_DWIDTH-1);
signal intr_IP2Bus_WrAck : std_logic;
signal intr_IP2Bus_RdAck : std_logic;
signal intr_IP2Bus_Error : std_logic;
signal user_Bus2IP_RdCE : std_logic_vector(0 to USER_NUM_REG-1);
signal user_Bus2IP_WrCE : std_logic_vector(0 to USER_NUM_REG-1);
signal user_IP2Bus_Data : std_logic_vector(0 to USER_SLV_DWIDTH-1);
signal user_IP2Bus_RdAck : std_logic;
signal user_IP2Bus_WrAck : std_logic;
signal user_IP2Bus_Error : std_logic;
signal user_IP2Bus_IntrEvent : std_logic_vector(0 to USER_NUM_INTR-1);
 
begin
 
------------------------------------------
-- instantiate plbv46_slave_single
------------------------------------------
PLBV46_SLAVE_SINGLE_I : entity plbv46_slave_single_v1_01_a.plbv46_slave_single
generic map
(
C_ARD_ADDR_RANGE_ARRAY => IPIF_ARD_ADDR_RANGE_ARRAY,
C_ARD_NUM_CE_ARRAY => IPIF_ARD_NUM_CE_ARRAY,
C_SPLB_P2P => C_SPLB_P2P,
C_BUS2CORE_CLK_RATIO => IPIF_BUS2CORE_CLK_RATIO,
C_SPLB_MID_WIDTH => C_SPLB_MID_WIDTH,
C_SPLB_NUM_MASTERS => C_SPLB_NUM_MASTERS,
C_SPLB_AWIDTH => C_SPLB_AWIDTH,
C_SPLB_DWIDTH => C_SPLB_DWIDTH,
C_SIPIF_DWIDTH => IPIF_SLV_DWIDTH,
C_INCLUDE_DPHASE_TIMER => C_INCLUDE_DPHASE_TIMER,
C_FAMILY => C_FAMILY
)
port map
(
SPLB_Clk => SPLB_Clk,
SPLB_Rst => SPLB_Rst,
PLB_ABus => PLB_ABus,
PLB_UABus => PLB_UABus,
PLB_PAValid => PLB_PAValid,
PLB_SAValid => PLB_SAValid,
PLB_rdPrim => PLB_rdPrim,
PLB_wrPrim => PLB_wrPrim,
PLB_masterID => PLB_masterID,
PLB_abort => PLB_abort,
PLB_busLock => PLB_busLock,
PLB_RNW => PLB_RNW,
PLB_BE => PLB_BE,
PLB_MSize => PLB_MSize,
PLB_size => PLB_size,
PLB_type => PLB_type,
PLB_lockErr => PLB_lockErr,
PLB_wrDBus => PLB_wrDBus,
PLB_wrBurst => PLB_wrBurst,
PLB_rdBurst => PLB_rdBurst,
PLB_wrPendReq => PLB_wrPendReq,
PLB_rdPendReq => PLB_rdPendReq,
PLB_wrPendPri => PLB_wrPendPri,
PLB_rdPendPri => PLB_rdPendPri,
PLB_reqPri => PLB_reqPri,
PLB_TAttribute => PLB_TAttribute,
Sl_addrAck => Sl_addrAck,
Sl_SSize => Sl_SSize,
Sl_wait => Sl_wait,
Sl_rearbitrate => Sl_rearbitrate,
Sl_wrDAck => Sl_wrDAck,
Sl_wrComp => Sl_wrComp,
Sl_wrBTerm => Sl_wrBTerm,
Sl_rdDBus => Sl_rdDBus,
Sl_rdWdAddr => Sl_rdWdAddr,
Sl_rdDAck => Sl_rdDAck,
Sl_rdComp => Sl_rdComp,
Sl_rdBTerm => Sl_rdBTerm,
Sl_MBusy => Sl_MBusy,
Sl_MWrErr => Sl_MWrErr,
Sl_MRdErr => Sl_MRdErr,
Sl_MIRQ => Sl_MIRQ,
Bus2IP_Clk => ipif_Bus2IP_Clk,
Bus2IP_Reset => ipif_Bus2IP_Reset,
IP2Bus_Data => ipif_IP2Bus_Data,
IP2Bus_WrAck => ipif_IP2Bus_WrAck,
IP2Bus_RdAck => ipif_IP2Bus_RdAck,
IP2Bus_Error => ipif_IP2Bus_Error,
Bus2IP_Addr => ipif_Bus2IP_Addr,
Bus2IP_Data => ipif_Bus2IP_Data,
Bus2IP_RNW => ipif_Bus2IP_RNW,
Bus2IP_BE => ipif_Bus2IP_BE,
Bus2IP_CS => ipif_Bus2IP_CS,
Bus2IP_RdCE => ipif_Bus2IP_RdCE,
Bus2IP_WrCE => ipif_Bus2IP_WrCE
);
 
------------------------------------------
-- instantiate soft_reset
------------------------------------------
SOFT_RESET_I : entity proc_common_v3_00_a.soft_reset
generic map
(
C_SIPIF_DWIDTH => IPIF_SLV_DWIDTH,
C_RESET_WIDTH => RESET_WIDTH
)
port map
(
Bus2IP_Reset => ipif_Bus2IP_Reset,
Bus2IP_Clk => ipif_Bus2IP_Clk,
Bus2IP_WrCE => ipif_Bus2IP_WrCE(RST_CE_INDEX),
Bus2IP_Data => ipif_Bus2IP_Data,
Bus2IP_BE => ipif_Bus2IP_BE,
Reset2IP_Reset => rst_Bus2IP_Reset,
Reset2Bus_WrAck => rst_IP2Bus_WrAck,
Reset2Bus_Error => rst_IP2Bus_Error,
Reset2Bus_ToutSup => open
);
 
------------------------------------------
-- instantiate interrupt_control
------------------------------------------
INTERRUPT_CONTROL_I : entity interrupt_control_v2_01_a.interrupt_control
generic map
(
C_NUM_CE => INTR_NUM_CE,
C_NUM_IPIF_IRPT_SRC => INTR_NUM_IPIF_IRPT_SRC,
C_IP_INTR_MODE_ARRAY => INTR_IP_INTR_MODE_ARRAY,
C_INCLUDE_DEV_PENCODER => INTR_INCLUDE_DEV_PENCODER,
C_INCLUDE_DEV_ISC => INTR_INCLUDE_DEV_ISC,
C_IPIF_DWIDTH => IPIF_SLV_DWIDTH
)
port map
(
Bus2IP_Clk => ipif_Bus2IP_Clk,
Bus2IP_Reset => rst_Bus2IP_Reset,
Bus2IP_Data => ipif_Bus2IP_Data,
Bus2IP_BE => ipif_Bus2IP_BE,
Interrupt_RdCE => ipif_Bus2IP_RdCE(INTR_CE_INDEX to INTR_CE_INDEX+INTR_NUM_CE-1),
Interrupt_WrCE => ipif_Bus2IP_WrCE(INTR_CE_INDEX to INTR_CE_INDEX+INTR_NUM_CE-1),
IPIF_Reg_Interrupts => intr_IPIF_Reg_Interrupts,
IPIF_Lvl_Interrupts => intr_IPIF_Lvl_Interrupts,
IP2Bus_IntrEvent => user_IP2Bus_IntrEvent,
Intr2Bus_DevIntr => IP2INTC_Irpt,
Intr2Bus_DBus => intr_IP2Bus_Data,
Intr2Bus_WrAck => intr_IP2Bus_WrAck,
Intr2Bus_RdAck => intr_IP2Bus_RdAck,
Intr2Bus_Error => intr_IP2Bus_Error,
Intr2Bus_Retry => open,
Intr2Bus_ToutSup => open
);
 
-- feed registered and level-pass-through interrupts into Device ISC if exists, otherwise ignored
intr_IPIF_Reg_Interrupts(0) <= '0';
intr_IPIF_Reg_Interrupts(1) <= '0';
intr_IPIF_Lvl_Interrupts(0) <= '0';
intr_IPIF_Lvl_Interrupts(1) <= '0';
intr_IPIF_Lvl_Interrupts(2) <= '0';
intr_IPIF_Lvl_Interrupts(3) <= '0';
 
------------------------------------------
-- instantiate User Logic
------------------------------------------
USER_LOGIC_I : entity mod_sim_exp.user_logic
generic map
(
-- MAP USER GENERICS BELOW THIS LINE ---------------
-- Multiplier parameters
C_NR_BITS_TOTAL => C_NR_BITS_TOTAL,
C_NR_STAGES_TOTAL => C_NR_STAGES_TOTAL,
C_NR_STAGES_LOW => C_NR_STAGES_LOW,
C_SPLIT_PIPELINE => C_SPLIT_PIPELINE,
C_FIFO_DEPTH => C_FIFO_DEPTH,
C_MEM_STYLE => C_MEM_STYLE,
C_DEVICE => C_DEVICE,
-- MAP USER GENERICS ABOVE THIS LINE ---------------
 
C_SLV_AWIDTH => USER_SLV_AWIDTH,
C_SLV_DWIDTH => USER_SLV_DWIDTH,
C_NUM_REG => USER_NUM_REG,
C_NUM_MEM => USER_NUM_MEM,
C_NUM_INTR => USER_NUM_INTR
)
port map
(
-- MAP USER PORTS BELOW THIS LINE ------------------
--USER ports mapped here
calc_time => calc_time,
-- MAP USER PORTS ABOVE THIS LINE ------------------
 
Bus2IP_Clk => ipif_Bus2IP_Clk,
Bus2IP_Reset => rst_Bus2IP_Reset,
Bus2IP_Addr => ipif_Bus2IP_Addr,
Bus2IP_CS => ipif_Bus2IP_CS(USER_CS_INDEX to USER_CS_INDEX+USER_NUM_MEM-1),
Bus2IP_RNW => ipif_Bus2IP_RNW,
Bus2IP_Data => ipif_Bus2IP_Data,
Bus2IP_BE => ipif_Bus2IP_BE,
Bus2IP_RdCE => user_Bus2IP_RdCE,
Bus2IP_WrCE => user_Bus2IP_WrCE,
IP2Bus_Data => user_IP2Bus_Data,
IP2Bus_RdAck => user_IP2Bus_RdAck,
IP2Bus_WrAck => user_IP2Bus_WrAck,
IP2Bus_Error => user_IP2Bus_Error,
IP2Bus_IntrEvent => user_IP2Bus_IntrEvent
);
 
------------------------------------------
-- connect internal signals
------------------------------------------
IP2BUS_DATA_MUX_PROC : process( ipif_Bus2IP_CS, user_IP2Bus_Data, intr_IP2Bus_Data ) is
begin
 
case ipif_Bus2IP_CS is
when "100000000" => ipif_IP2Bus_Data <= user_IP2Bus_Data;
when "010000000" => ipif_IP2Bus_Data <= (others => '0');
when "001000000" => ipif_IP2Bus_Data <= intr_IP2Bus_Data;
when "000100000" => ipif_IP2Bus_Data <= user_IP2Bus_Data;
when "000010000" => ipif_IP2Bus_Data <= user_IP2Bus_Data;
when "000001000" => ipif_IP2Bus_Data <= user_IP2Bus_Data;
when "000000100" => ipif_IP2Bus_Data <= user_IP2Bus_Data;
when "000000010" => ipif_IP2Bus_Data <= user_IP2Bus_Data;
when "000000001" => ipif_IP2Bus_Data <= user_IP2Bus_Data;
when others => ipif_IP2Bus_Data <= (others => '0');
end case;
 
end process IP2BUS_DATA_MUX_PROC;
 
ipif_IP2Bus_WrAck <= user_IP2Bus_WrAck or rst_IP2Bus_WrAck or intr_IP2Bus_WrAck;
ipif_IP2Bus_RdAck <= user_IP2Bus_RdAck or intr_IP2Bus_RdAck;
ipif_IP2Bus_Error <= user_IP2Bus_Error or rst_IP2Bus_Error or intr_IP2Bus_Error;
 
user_Bus2IP_RdCE <= ipif_Bus2IP_RdCE(USER_CE_INDEX to USER_CE_INDEX+USER_NUM_REG-1);
user_Bus2IP_WrCE <= ipif_Bus2IP_WrCE(USER_CE_INDEX to USER_CE_INDEX+USER_NUM_REG-1);
 
end IMP;
/core/mod_sim_exp_pkg.vhd
0,0 → 1,965
----------------------------------------------------------------------
---- mod_sim_exp_pkg ----
---- ----
---- This file is part of the ----
---- Modular Simultaneous Exponentiation Core project ----
---- http://www.opencores.org/cores/mod_sim_exp/ ----
---- ----
---- Description ----
---- Package for the Modular Simultaneous Exponentiation Core ----
---- Project. Contains the component declarations and used ----
---- constants. ----
---- ----
---- Dependencies: none ----
---- ----
---- Authors: ----
---- - Geoffrey Ottoy, DraMCo research group ----
---- - Jonas De Craene, JonasDC@opencores.org ----
---- ----
----------------------------------------------------------------------
---- ----
---- Copyright (C) 2011 DraMCo research group and OPENCORES.ORG ----
---- ----
---- This source file may be used and distributed without ----
---- restriction provided that this copyright statement is not ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer. ----
---- ----
---- This source file is free software; you can redistribute 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 source 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. ----
---- ----
---- You should have received a copy of the GNU Lesser General ----
---- Public License along with this source; if not, download it ----
---- from http://www.opencores.org/lgpl.shtml ----
---- ----
----------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
library mod_sim_exp;
use mod_sim_exp.std_functions.all;
 
package mod_sim_exp_pkg is
--------------------------------------------------------------------
---------------------- COMPONENT DECLARATIONS ----------------------
--------------------------------------------------------------------
--------------------------- MULTIPLIER -----------------------------
--------------------------------------------------------------------
-- d_flip_flop
--------------------------------------------------------------------
-- 1-bit D flip-flop with asynchronous active high reset
--
component d_flip_flop is
port(
core_clk : in std_logic; -- clock signal
reset : in std_logic; -- active high reset
din : in std_logic; -- data in
dout : out std_logic -- data out
);
end component d_flip_flop;
--------------------------------------------------------------------
-- register_1b
--------------------------------------------------------------------
-- 1-bit register with asynchronous reset and clock enable
--
component register_1b is
port(
core_clk : in std_logic; -- clock input
ce : in std_logic; -- clock enable (active high)
reset : in std_logic; -- reset (active high)
din : in std_logic; -- data in
dout : out std_logic -- data out
);
end component register_1b;
--------------------------------------------------------------------
-- register_n
--------------------------------------------------------------------
-- n-bit register with asynchronous reset and clock enable
--
component register_n is
generic(
width : integer := 4
);
port(
core_clk : in std_logic; -- clock input
ce : in std_logic; -- clock enable (active high)
reset : in std_logic; -- reset (active high)
din : in std_logic_vector((width-1) downto 0); -- data in (width)-bit
dout : out std_logic_vector((width-1) downto 0) -- data out (width)-bit
);
end component register_n;
--------------------------------------------------------------------
-- cell_1b_adder
--------------------------------------------------------------------
-- 1-bit full adder cell using combinatorial logic
--
component cell_1b_adder is
port (
-- input operands a, b
a : in std_logic;
b : in std_logic;
-- carry in, out
cin : in std_logic;
cout : out std_logic;
-- result out
r : out std_logic
);
end component cell_1b_adder;
--------------------------------------------------------------------
-- cell_1b_mux
--------------------------------------------------------------------
-- 1-bit mux for a standard cell in the montgommery multiplier
-- systolic array
--
component cell_1b_mux is
port (
-- input bits
my : in std_logic;
y : in std_logic;
m : in std_logic;
-- selection bits
x : in std_logic;
q : in std_logic;
-- mux out
result : out std_logic
);
end component cell_1b_mux;
--------------------------------------------------------------------
-- cell_1b
--------------------------------------------------------------------
-- 1-bit cell for the systolic array
--
component cell_1b is
port (
-- operand input bits (m+y, y and m)
my : in std_logic;
y : in std_logic;
m : in std_logic;
-- operand x input bit and q
x : in std_logic;
q : in std_logic;
-- previous result input bit
a : in std_logic;
-- carry's
cin : in std_logic;
cout : out std_logic;
-- cell result out
r : out std_logic
);
end component cell_1b;
--------------------------------------------------------------------
-- adder_block
--------------------------------------------------------------------
-- (width)-bit full adder block using cell_1b_adders with buffered
-- carry out
--
component adder_block is
generic (
width : integer := 32 --adder operand widths
);
port (
-- clock input
core_clk : in std_logic;
-- adder input operands a, b (width)-bit
a : in std_logic_vector((width-1) downto 0);
b : in std_logic_vector((width-1) downto 0);
-- carry in, out
cin : in std_logic;
cout : out std_logic;
-- adder result out (width)-bit
r : out std_logic_vector((width-1) downto 0)
);
end component adder_block;
--------------------------------------------------------------------
-- standard_cell_block
--------------------------------------------------------------------
-- a standard cell block of (width)-bit for the montgommery multiplier
-- systolic array
--
component standard_cell_block is
generic (
width : integer := 16
);
port (
-- modulus and y operand input (width)-bit
my : in std_logic_vector((width-1) downto 0);
y : in std_logic_vector((width-1) downto 0);
m : in std_logic_vector((width-1) downto 0);
-- q and x operand input (serial input)
x : in std_logic;
q : in std_logic;
-- previous result in (width)-bit
a : in std_logic_vector((width-1) downto 0);
-- carry in and out
cin : in std_logic;
cout : out std_logic;
-- result out (width)-bit
r : out std_logic_vector((width-1) downto 0)
);
end component standard_cell_block;
--------------------------------------------------------------------
-- counter_sync
--------------------------------------------------------------------
-- counter with synchronous count enable. It generates an
-- overflow when max_value is reached
--
component counter_sync is
generic(
max_value : integer := 1024 -- maximum value (constraints the nr bits for counter)
);
port(
reset_value : in integer; -- value the counter counts to
core_clk : in std_logic; -- clock input
ce : in std_logic; -- count enable
reset : in std_logic; -- reset input
overflow : out std_logic -- gets high when counter reaches reset_value
);
end component counter_sync;
--------------------------------------------------------------------
-- stepping_logic
--------------------------------------------------------------------
-- stepping logic for the pipeline, generates the start pulses for the
-- first stage and keeps track of when the last stages are done
--
component stepping_logic is
generic(
n : integer := 1536; -- max nr of steps required to complete a multiplication
t : integer := 192 -- total nr of steps in the pipeline
);
port(
core_clk : in std_logic; -- clock input
start : in std_logic; -- start signal for pipeline (one multiplication)
reset : in std_logic; -- reset signal
t_sel : in integer range 0 to t; -- nr of stages in the pipeline piece
n_sel : in integer range 0 to n; -- nr of steps(bits in operands) required for a complete multiplication
start_first_stage : out std_logic; -- start pulse output for first stage
stepping_done : out std_logic -- done signal
);
end component stepping_logic;
 
--------------------------------------------------------------------
-- x_shift_reg
--------------------------------------------------------------------
-- shift register for the x operand of the multiplier
-- outputs the lsb of the register or bit at offset according to the
-- selected pipeline part
--
component x_shift_reg is
generic(
n : integer := 1536; -- width of the operands (# bits)
t : integer := 48; -- total number of stages
tl : integer := 16 -- lower number of stages
);
port(
-- clock input
clk : in std_logic;
-- x operand in (n-bit)
x_in : in std_logic_vector((n-1) downto 0);
-- control signals
reset : in std_logic; -- reset, clears register
load_x : in std_logic; -- load operand into shift register
next_x : in std_logic; -- next bit of x
p_sel : in std_logic_vector(1 downto 0); -- pipeline selection
-- x operand bit out (serial)
xi : out std_logic
);
end component x_shift_reg;
component autorun_cntrl is
port (
clk : in std_logic;
reset : in std_logic;
start : in std_logic;
done : out std_logic;
op_sel : out std_logic_vector (1 downto 0);
start_multiplier : out std_logic;
multiplier_done : in std_logic;
read_buffer : out std_logic;
buffer_din : in std_logic_vector (31 downto 0);
buffer_empty : in std_logic
);
end component autorun_cntrl;
--------------------------------------------------------------------
-- mont_ctrl
--------------------------------------------------------------------
-- This module controls the montgommery mutliplier and controls traffic between
-- RAM and multiplier. Also contains the autorun logic for exponentiations.
--
component mont_ctrl is
port (
clk : in std_logic;
reset : in std_logic;
-- bus side
start : in std_logic;
x_sel_single : in std_logic_vector(1 downto 0);
y_sel_single : in std_logic_vector(1 downto 0);
run_auto : in std_logic;
op_buffer_empty : in std_logic;
op_sel_buffer : in std_logic_vector(31 downto 0);
read_buffer : out std_logic;
done : out std_logic;
calc_time : out std_logic;
-- multiplier side
op_sel : out std_logic_vector(1 downto 0);
load_x : out std_logic;
load_result : out std_logic;
start_multiplier : out std_logic;
multiplier_ready : in std_logic
);
end component mont_ctrl;
component sys_stage is
generic(
width : integer := 32 -- width of the stage
);
port(
-- clock input
core_clk : in std_logic;
-- modulus and y operand input (width)-bit
y : in std_logic_vector((width-1) downto 0);
m : in std_logic_vector((width) downto 0);
my_cin : in std_logic;
my_cout : out std_logic;
-- q and x operand input (serial input)
xin : in std_logic;
qin : in std_logic;
-- q and x operand output (serial output)
xout : out std_logic;
qout : out std_logic;
-- msb input (lsb from next stage, for shift right operation)
a_msb : in std_logic;
a_0 : out std_logic;
-- carry out(clocked) and in
cin : in std_logic;
cout : out std_logic;
-- reduction adder carry's
red_cin : in std_logic;
red_cout : out std_logic;
-- control singals
start : in std_logic;
reset : in std_logic;
done : out std_logic;
-- result out
r_sel : in std_logic; -- result selection: 0 -> pipeline result, 1 -> reducted result
r : out std_logic_vector((width-1) downto 0)
);
end component sys_stage;
 
--------------------------------------------------------------------
-- sys_last_cell_logic
--------------------------------------------------------------------
-- logic needed as the last piece in the systolic array pipeline
-- calculates the last 2 bits of the cell_result and finishes the reduction
-- also generates the result selection signal
--
component sys_last_cell_logic is
port (
core_clk : in std_logic; -- clock input
reset : in std_logic;
a_0 : out std_logic; -- a_msb for last stage
cin : in std_logic; -- cout from last stage
red_cin : in std_logic; -- red_cout from last stage
r_sel : out std_logic; -- result selection bit
start : in std_logic -- done signal from last stage
);
end component sys_last_cell_logic;
--------------------------------------------------------------------
-- sys_first_cell_logic
--------------------------------------------------------------------
-- logic needed as the first piece in the systolic array pipeline
-- calculates the first my_cout and generates q signal
--
component sys_first_cell_logic is
port (
m0 : in std_logic; -- lsb from m operand
y0 : in std_logic; -- lsb from y operand
my_cout : out std_logic; -- my_cin for first stage
xi : in std_logic; -- xi operand input
xout : out std_logic; -- xin for first stage
qout : out std_logic; -- qin for first stage
cout : out std_logic; -- cin for first stage
a_0 : in std_logic; -- a_0 from first stage
red_cout : out std_logic -- red_cin for first stage
);
end component sys_first_cell_logic;
 
--------------------------------------------------------------------
-- sys_pipeline
--------------------------------------------------------------------
-- the pipelined systolic array for a montgommery multiplier
-- contains a structural description of the pipeline using the systolic stages
--
component sys_pipeline is
generic(
n : integer := 1536; -- width of the operands (# bits)
t : integer := 192; -- total number of stages (minimum 2)
tl : integer := 64; -- lower number of stages (minimum 1)
split : boolean := true -- if true the pipeline wil be split in 2 parts,
-- if false there are no lower stages, only t counts
);
port(
-- clock input
core_clk : in std_logic;
-- modulus and y opperand input (n)-bit
y : in std_logic_vector((n-1) downto 0);
m : in std_logic_vector((n-1) downto 0);
-- x operand input (serial)
xi : in std_logic;
next_x : out std_logic; -- next x operand bit
-- control signals
start : in std_logic; -- start multiplier
reset : in std_logic;
p_sel : in std_logic_vector(1 downto 0); -- select which piece of the pipeline will be used
-- result out
r : out std_logic_vector((n-1) downto 0)
);
end component sys_pipeline;
component mont_multiplier is
generic (
n : integer := 1536; -- width of the operands
t : integer := 96; -- total number of stages (minimum 2)
tl : integer := 32; -- lower number of stages (minimum 1)
split : boolean := true -- if true the pipeline wil be split in 2 parts,
-- if false there are no lower stages, only t counts
);
port (
-- clock input
core_clk : in std_logic;
-- operand inputs
xy : in std_logic_vector((n-1) downto 0); -- bus for x or y operand
m : in std_logic_vector((n-1) downto 0); -- modulus
-- result output
r : out std_logic_vector((n-1) downto 0); -- result
-- control signals
start : in std_logic;
reset : in std_logic;
p_sel : in std_logic_vector(1 downto 0);
load_x : in std_logic;
ready : out std_logic
);
end component mont_multiplier;
 
 
------------------------------ MEMORY ------------------------------
-------------------------- xil_prim specific -----------------------
--------------------------------------------------------------------
-- operand_dp
--------------------------------------------------------------------
-- true dual port RAM 512x4, uses xilinx primitives
--
component operand_dp is
port (
clka : in std_logic;
wea : in std_logic_vector(0 downto 0);
addra : in std_logic_vector(5 downto 0);
dina : in std_logic_vector(31 downto 0);
douta : out std_logic_vector(511 downto 0);
clkb : in std_logic;
web : in std_logic_vector(0 downto 0);
addrb : in std_logic_vector(5 downto 0);
dinb : in std_logic_vector(511 downto 0);
doutb : out std_logic_vector(31 downto 0)
);
end component operand_dp;
--------------------------------------------------------------------
-- operand_sp
--------------------------------------------------------------------
-- dual port RAM 512x2, uses xilinx primitives
--
component operands_sp is
port (
clka : in std_logic;
wea : in std_logic_vector(0 downto 0);
addra : in std_logic_vector(4 downto 0);
dina : in std_logic_vector(31 downto 0);
douta : out std_logic_vector(511 downto 0)
);
end component operands_sp;
--------------------------------------------------------------------
-- fifo_primitive
--------------------------------------------------------------------
-- a xilinx fifo primitive wrapper
--
component fifo_primitive is
port (
clk : in std_logic;
din : in std_logic_vector (31 downto 0);
dout : out std_logic_vector (31 downto 0);
empty : out std_logic;
full : out std_logic;
push : in std_logic;
pop : in std_logic;
reset : in std_logic;
nopop : out std_logic;
nopush : out std_logic
);
end component fifo_primitive;
--------------------------------------------------------------------
-- operand_ram
--------------------------------------------------------------------
-- RAM for the operands, fixed width of 1536-bit and depth of 4
-- uses xilinx primitives
--
component operand_ram is
port(
-- global ports
clk : in std_logic;
collision : out std_logic;
-- bus side connections (32-bit serial)
operand_addr : in std_logic_vector(5 downto 0);
operand_in : in std_logic_vector(31 downto 0);
operand_in_sel : in std_logic_vector(1 downto 0);
result_out : out std_logic_vector(31 downto 0);
write_operand : in std_logic;
-- multiplier side connections (1536 bit parallel)
result_dest_op : in std_logic_vector(1 downto 0);
operand_out : out std_logic_vector(1535 downto 0);
operand_out_sel : in std_logic_vector(1 downto 0); -- controlled by bus side
write_result : in std_logic;
result_in : in std_logic_vector(1535 downto 0)
);
end component operand_ram;
--------------------------------------------------------------------
-- modulus_ram
--------------------------------------------------------------------
-- RAM for the modulus, fixed width of 1536-bit, uses xilinx primitives
--
component modulus_ram is
port(
clk : in std_logic;
modulus_addr : in std_logic_vector(5 downto 0);
write_modulus : in std_logic;
modulus_in : in std_logic_vector(31 downto 0);
modulus_out : out std_logic_vector(1535 downto 0)
);
end component modulus_ram;
------------------------- generic modules --------------------------
--------------------------------------------------------------------
-- dpram_generic
--------------------------------------------------------------------
-- behavorial description of a dual port ram with one 32-bit
-- write port and one 32-bit read port
--
component dpram_generic is
generic (
depth : integer := 2
);
port (
clk : in std_logic;
-- write port
waddr : in std_logic_vector(log2(depth)-1 downto 0);
we : in std_logic;
din : in std_logic_vector(31 downto 0);
-- read port
raddr : in std_logic_vector(log2(depth)-1 downto 0);
dout : out std_logic_vector(31 downto 0)
);
end component dpram_generic;
--------------------------------------------------------------------
-- tdpram_generic
--------------------------------------------------------------------
-- behavorial description of a true dual port ram with 2
-- 32-bit write/read ports
--
component tdpram_generic is
generic (
depth : integer := 9
);
port (
-- port A
clkA : in std_logic;
addrA : in std_logic_vector(log2(depth)-1 downto 0);
weA : in std_logic;
dinA : in std_logic_vector(31 downto 0);
doutA : out std_logic_vector(31 downto 0);
-- port B
clkB : in std_logic;
addrB : in std_logic_vector(log2(depth)-1 downto 0);
weB : in std_logic;
dinB : in std_logic_vector(31 downto 0);
doutB : out std_logic_vector(31 downto 0)
);
end component tdpram_generic;
--------------------------------------------------------------------
-- fifo_generic
--------------------------------------------------------------------
-- a behavorial implementation of a fifo that is designed to
-- infer blockram
--
component fifo_generic is
generic (
depth : integer := 32
);
port (
clk : in std_logic; -- clock input
din : in std_logic_vector (31 downto 0); -- 32 bit input data for push
dout : out std_logic_vector (31 downto 0); -- 32 bit output data for pop
empty : out std_logic; -- empty flag, 1 when FIFO is empty
full : out std_logic; -- full flag, 1 when FIFO is full
push : in std_logic;
pop : in std_logic;
reset : in std_logic;
nopop : out std_logic;
nopush : out std_logic
);
end component fifo_generic;
--------------------------------------------------------------------
-- modulus_ram_gen
--------------------------------------------------------------------
-- structural description of a RAM to hold the modulus, with
-- adjustable width and depth(nr of moduluses)
--
component modulus_ram_gen is
generic(
width : integer := 1536; -- must be a multiple of 32
depth : integer := 2 -- nr of moduluses
);
port(
clk : in std_logic;
-- bus side
write_modulus : in std_logic; -- write enable
modulus_in_sel : in std_logic_vector(log2(depth)-1 downto 0); -- modulus operand to write to
modulus_addr : in std_logic_vector(log2((width)/32)-1 downto 0); -- modulus word(32-bit) address
modulus_in : in std_logic_vector(31 downto 0); -- modulus word data in
modulus_sel : in std_logic_vector(log2(depth)-1 downto 0); -- selects the modulus to use for multiplications
-- multiplier side
modulus_out : out std_logic_vector(width-1 downto 0)
);
end component modulus_ram_gen;
--------------------------------------------------------------------
-- operand_ram_gen
--------------------------------------------------------------------
-- behavorial description of a RAM to hold the operands, with
-- adjustable width and depth(nr of operands)
--
component operand_ram_gen is
generic(
width : integer := 1536; -- width of the operands
depth : integer := 4 -- nr of operands
);
port(
-- global ports
clk : in std_logic;
collision : out std_logic; -- 1 if simultaneous write on RAM
-- bus side connections (32-bit serial)
write_operand : in std_logic; -- write_enable
operand_in_sel : in std_logic_vector(log2(depth)-1 downto 0); -- operand to write to
operand_addr : in std_logic_vector(log2(width/32)-1 downto 0); -- address of operand word to write
operand_in : in std_logic_vector(31 downto 0); -- operand word(32-bit) to write
result_out : out std_logic_vector(31 downto 0); -- operand out, reading is always result operand
operand_out_sel : in std_logic_vector(log2(depth)-1 downto 0); -- operand to give to multiplier
-- multiplier side connections (width-bit parallel)
result_dest_op : in std_logic_vector(log2(depth)-1 downto 0); -- operand select for result
operand_out : out std_logic_vector(width-1 downto 0); -- operand out to multiplier
write_result : in std_logic; -- write enable for multiplier side
result_in : in std_logic_vector(width-1 downto 0) -- result to write from multiplier
);
end component operand_ram_gen;
------------------------ asymmetric modules ------------------------
--------------------------------------------------------------------
-- dpram_asym
--------------------------------------------------------------------
-- behavorial description of an asymmetric dual port ram
-- with one (wrwidth)-bit write port and one 32-bit read
-- port. Made using the templates of xilinx and altera for
-- asymmetric ram.
--
component dpram_asym is
generic(
rddepth : integer := 4; -- nr of 32-bit words
wrwidth : integer := 2; -- write width, must be smaller than or equal to 32
device : string := "xilinx" -- device template to use
);
port(
clk : in std_logic;
-- write port
waddr : in std_logic_vector(log2((rddepth*32)/wrwidth)-1 downto 0);
we : in std_logic;
din : in std_logic_vector(wrwidth-1 downto 0);
-- read port
raddr : in std_logic_vector(log2(rddepth)-1 downto 0);
dout : out std_logic_vector(31 downto 0)
);
end component dpram_asym;
--------------------------------------------------------------------
-- dpramblock_asym
--------------------------------------------------------------------
-- structural description of an asymmetric dual port ram
-- with one 32-bit write port and one (width)-bit read
-- port.
--
component dpramblock_asym is
generic(
width : integer := 256; -- read width
depth : integer := 2; -- nr of (width)-bit words
device : string := "xilinx"
);
port(
clk : in std_logic;
-- write port
waddr : in std_logic_vector(log2((width*depth)/32)-1 downto 0);
we : in std_logic;
din : in std_logic_vector(31 downto 0);
-- read port
raddr : in std_logic_vector(log2(depth)-1 downto 0);
dout : out std_logic_vector(width-1 downto 0)
);
end component dpramblock_asym;
--------------------------------------------------------------------
-- tdpram_asym
--------------------------------------------------------------------
-- behavorial description of an asymmetric true dual port
-- ram with one (widthA)-bit read/write port and one 32-bit
-- read/write port. Made using the templates of xilinx and
-- altera for asymmetric ram.
--
component tdpram_asym is
generic(
depthB : integer := 4; -- nr of 32-bit words
widthA : integer := 2; -- port A width, must be smaller than or equal to 32
device : string := "xilinx"
);
port(
clk : in std_logic;
-- port A (widthA)-bit
addrA : in std_logic_vector(log2((depthB*32)/widthA)-1 downto 0);
weA : in std_logic;
dinA : in std_logic_vector(widthA-1 downto 0);
doutA : out std_logic_vector(widthA-1 downto 0);
-- port B 32-bit
addrB : in std_logic_vector(log2(depthB)-1 downto 0);
weB : in std_logic;
dinB : in std_logic_vector(31 downto 0);
doutB : out std_logic_vector(31 downto 0)
);
end component tdpram_asym;
--------------------------------------------------------------------
-- tdpramblock_asym
--------------------------------------------------------------------
-- structural description of an asymmetric true dual port
-- ram with one 32-bit read/write port and one (width)-bit
-- read/write port.
--
component tdpramblock_asym is
generic (
depth : integer := 4; -- nr of (width)-bit words
width : integer := 512; -- width of portB
device : string := "xilinx"
);
port (
clk : in std_logic;
-- port A 32-bit
addrA : in std_logic_vector(log2((width*depth)/32)-1 downto 0);
weA : in std_logic;
dinA : in std_logic_vector(31 downto 0);
doutA : out std_logic_vector(31 downto 0);
-- port B (width)-bit
addrB : in std_logic_vector(log2(depth)-1 downto 0);
weB : in std_logic;
dinB : in std_logic_vector(width-1 downto 0);
doutB : out std_logic_vector(width-1 downto 0)
);
end component tdpramblock_asym;
--------------------------------------------------------------------
-- modulus_ram_asym
--------------------------------------------------------------------
-- BRAM memory and logic to store the modulus, due to the
-- achitecture, a minimum depth of 2 is needed for this
-- module to be inferred into blockram, this version is
-- slightly more performant than modulus_ram_gen and uses
-- less resources. but does not work on every fpga, only
-- the ones that support asymmetric rams.
--
component modulus_ram_asym is
generic(
width : integer := 1536; -- must be a multiple of 32
depth : integer := 2; -- nr of moduluses
device : string := "xilinx"
);
port(
clk : in std_logic;
-- bus side
write_modulus : in std_logic; -- write enable
modulus_in_sel : in std_logic_vector(log2(depth)-1 downto 0); -- modulus operand to write to
modulus_addr : in std_logic_vector(log2((width)/32)-1 downto 0); -- modulus word(32-bit) address
modulus_in : in std_logic_vector(31 downto 0); -- modulus word data in
modulus_sel : in std_logic_vector(log2(depth)-1 downto 0); -- selects the modulus to use for multiplications
-- multiplier side
modulus_out : out std_logic_vector(width-1 downto 0)
);
end component modulus_ram_asym;
--------------------------------------------------------------------
-- operand_ram_asym
--------------------------------------------------------------------
-- BRAM memory and logic to store the operands, due to the
-- achitecture, a minimum depth of 2 is needed for this
-- module to be inferred into blockram, this version is
-- slightly more performant than operand_ram_gen and uses
-- less resources. but does not work on every fpga, only
-- the ones that support asymmetric rams.
--
component operand_ram_asym is
generic(
width : integer := 1536; -- width of the operands
depth : integer := 4; -- nr of operands
device : string := "xilinx"
);
port(
-- global ports
clk : in std_logic;
collision : out std_logic; -- 1 if simultaneous write on RAM
-- bus side connections (32-bit serial)
write_operand : in std_logic; -- write_enable
operand_in_sel : in std_logic_vector(log2(depth)-1 downto 0); -- operand to write to
operand_addr : in std_logic_vector(log2(width/32)-1 downto 0); -- address of operand word to write
operand_in : in std_logic_vector(31 downto 0); -- operand word(32-bit) to write
result_out : out std_logic_vector(31 downto 0); -- operand out, reading is always result operand
operand_out_sel : in std_logic_vector(log2(depth)-1 downto 0); -- operand to give to multiplier
-- multiplier side connections (width-bit parallel)
result_dest_op : in std_logic_vector(log2(depth)-1 downto 0); -- operand select for result
operand_out : out std_logic_vector(width-1 downto 0); -- operand out to multiplier
write_result : in std_logic; -- write enable for multiplier side
result_in : in std_logic_vector(width-1 downto 0) -- result to write from multiplier
);
end component operand_ram_asym;
--------------------------------------------------------------------
-- operand_mem
--------------------------------------------------------------------
-- RAM memory and logic to the store operands and the
-- modulus for the montgomery multiplier, the user has a
-- choise between 3 memory styles, more detail in the
-- documentation.
--
-- address structure:
-- bit: highest -> '1': modulus
-- '0': operands
-- bits: (highest-1)-log2(width/32) -> operand_in_sel in case of highest bit = '0'
-- modulus_in_sel in case of highest bit = '1'
-- bits: (log2(width/32)-1)-0 -> modulus_addr / operand_addr resp.
--
component operand_mem is
generic(
width : integer := 1536; -- width of the operands
nr_op : integer := 4; -- nr of operand storages, has to be greater than nr_m
nr_m : integer := 2; -- nr of modulus storages
mem_style : string := "asym"; -- xil_prim, generic, asym are valid options
device : string := "altera" -- xilinx, altera are valid options
);
port(
-- system clock
clk : in std_logic;
-- data interface (plb side)
data_in : in std_logic_vector(31 downto 0);
data_out : out std_logic_vector(31 downto 0);
rw_address : in std_logic_vector(8 downto 0);
write_enable : in std_logic;
-- operand interface (multiplier side)
op_sel : in std_logic_vector(log2(nr_op)-1 downto 0);
xy_out : out std_logic_vector((width-1) downto 0);
m : out std_logic_vector((width-1) downto 0);
result_in : in std_logic_vector((width-1) downto 0);
-- control signals
load_result : in std_logic;
result_dest_op : in std_logic_vector(log2(nr_op)-1 downto 0);
collision : out std_logic;
modulus_sel : in std_logic_vector(log2(nr_m)-1 downto 0)
);
end component operand_mem;
---------------------------- TOP LEVEL -----------------------------
--------------------------------------------------------------------
-- mod_sim_exp_core
--------------------------------------------------------------------
-- toplevel of the modular simultaneous exponentiation core
-- contains an operand and modulus ram, multiplier, an exponent fifo
-- and control logic
--
component mod_sim_exp_core is
generic(
C_NR_BITS_TOTAL : integer := 1536;
C_NR_STAGES_TOTAL : integer := 96;
C_NR_STAGES_LOW : integer := 32;
C_SPLIT_PIPELINE : boolean := true;
C_FIFO_DEPTH : integer := 32;
C_MEM_STYLE : string := "generic"; -- xil_prim, generic, asym are valid options
C_DEVICE : string := "xilinx" -- xilinx, altera are valid options
);
port(
clk : in std_logic;
reset : in std_logic;
-- operand memory interface (plb shared memory)
write_enable : in std_logic; -- write data to operand ram
data_in : in std_logic_vector (31 downto 0); -- operand ram data in
rw_address : in std_logic_vector (8 downto 0); -- operand ram address bus
data_out : out std_logic_vector (31 downto 0); -- operand ram data out
collision : out std_logic; -- write collision
-- op_sel fifo interface
fifo_din : in std_logic_vector (31 downto 0); -- exponent fifo data in
fifo_push : in std_logic; -- push data in exponent fifo
fifo_full : out std_logic; -- high if fifo is full
fifo_nopush : out std_logic; -- high if error during push
-- control signals
start : in std_logic; -- start multiplication/exponentiation
exp_m : in std_logic; -- single multiplication if low, exponentiation if high
ready : out std_logic; -- calculations done
x_sel_single : in std_logic_vector (1 downto 0); -- single multiplication x operand selection
y_sel_single : in std_logic_vector (1 downto 0); -- single multiplication y operand selection
dest_op_single : in std_logic_vector (1 downto 0); -- result destination operand selection
p_sel : in std_logic_vector (1 downto 0); -- pipeline part selection
calc_time : out std_logic;
modulus_sel : in std_logic -- selects which modulus to use for multiplications
);
end component mod_sim_exp_core;
 
end package mod_sim_exp_pkg;
/core/mod_sim_exp_core.vhd
0,0 → 1,230
----------------------------------------------------------------------
---- mod_sim_exp_core ----
---- ----
---- This file is part of the ----
---- Modular Simultaneous Exponentiation Core project ----
---- http://www.opencores.org/cores/mod_sim_exp/ ----
---- ----
---- Description ----
---- toplevel of a modular simultaneous exponentiation core ----
---- using a pipelined montgommery multiplier with split ----
---- pipeline and auto-run support ----
---- ----
---- Dependencies: ----
---- - mont_mult_sys_pipeline ----
---- - operand_mem ----
---- - fifo_primitive ----
---- - mont_ctrl ----
---- ----
---- Authors: ----
---- - Geoffrey Ottoy, DraMCo research group ----
---- - Jonas De Craene, JonasDC@opencores.org ----
---- ----
----------------------------------------------------------------------
---- ----
---- Copyright (C) 2011 DraMCo research group and OPENCORES.ORG ----
---- ----
---- This source file may be used and distributed without ----
---- restriction provided that this copyright statement is not ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer. ----
---- ----
---- This source file is free software; you can redistribute 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 source 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. ----
---- ----
---- You should have received a copy of the GNU Lesser General ----
---- Public License along with this source; if not, download it ----
---- from http://www.opencores.org/lgpl.shtml ----
---- ----
----------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
 
library mod_sim_exp;
use mod_sim_exp.mod_sim_exp_pkg.all;
use mod_sim_exp.std_functions.all;
 
-- toplevel of the modular simultaneous exponentiation core
-- contains an operand and modulus ram, multiplier, an exponent fifo
-- and control logic
entity mod_sim_exp_core is
generic(
C_NR_BITS_TOTAL : integer := 1536;
C_NR_STAGES_TOTAL : integer := 96;
C_NR_STAGES_LOW : integer := 32;
C_SPLIT_PIPELINE : boolean := true;
C_FIFO_DEPTH : integer := 32;
C_MEM_STYLE : string := "asym"; -- xil_prim, generic, asym are valid options
C_DEVICE : string := "xilinx" -- xilinx, altera are valid options
);
port(
clk : in std_logic;
reset : in std_logic;
-- operand memory interface (plb shared memory)
write_enable : in std_logic; -- write data to operand ram
data_in : in std_logic_vector (31 downto 0); -- operand ram data in
rw_address : in std_logic_vector (8 downto 0); -- operand ram address bus
data_out : out std_logic_vector (31 downto 0); -- operand ram data out
collision : out std_logic; -- write collision
-- op_sel fifo interface
fifo_din : in std_logic_vector (31 downto 0); -- exponent fifo data in
fifo_push : in std_logic; -- push data in exponent fifo
fifo_full : out std_logic; -- high if fifo is full
fifo_nopush : out std_logic; -- high if error during push
-- control signals
start : in std_logic; -- start multiplication/exponentiation
exp_m : in std_logic; -- single multiplication if low, exponentiation if high
ready : out std_logic; -- calculations done
x_sel_single : in std_logic_vector (1 downto 0); -- single multiplication x operand selection
y_sel_single : in std_logic_vector (1 downto 0); -- single multiplication y operand selection
dest_op_single : in std_logic_vector (1 downto 0); -- result destination operand selection
p_sel : in std_logic_vector (1 downto 0); -- pipeline part selection
calc_time : out std_logic;
modulus_sel : in std_logic -- selects which modulus to use for multiplications
);
end mod_sim_exp_core;
 
 
architecture Structural of mod_sim_exp_core is
-- constants
constant nr_op : integer := 4;
constant nr_m : integer := 2;
 
-- data busses
signal xy : std_logic_vector(C_NR_BITS_TOTAL-1 downto 0); -- x and y operand data bus RAM -> multiplier
signal m : std_logic_vector(C_NR_BITS_TOTAL-1 downto 0); -- modulus data bus RAM -> multiplier
signal r : std_logic_vector(C_NR_BITS_TOTAL-1 downto 0); -- result data bus RAM <- multiplier
 
-- control signals
signal op_sel : std_logic_vector(1 downto 0); -- operand selection
signal result_dest_op : std_logic_vector(1 downto 0); -- result destination operand
signal mult_ready : std_logic;
signal start_mult : std_logic;
signal load_x : std_logic;
signal load_result : std_logic;
signal modulus_sel_i : std_logic_vector(0 downto 0);
 
-- fifo signals
signal fifo_empty : std_logic;
signal fifo_pop : std_logic;
signal fifo_nopop : std_logic;
signal fifo_dout : std_logic_vector(31 downto 0);
begin
 
-- The actual multiplier
the_multiplier : mont_multiplier
generic map(
n => C_NR_BITS_TOTAL,
t => C_NR_STAGES_TOTAL,
tl => C_NR_STAGES_LOW,
split => C_SPLIT_PIPELINE
)
port map(
core_clk => clk,
xy => xy,
m => m,
r => r,
start => start_mult,
reset => reset,
p_sel => p_sel,
load_x => load_x,
ready => mult_ready
);
 
-- Block ram memory for storing the operands and the modulus
the_memory : operand_mem
generic map(
width => C_NR_BITS_TOTAL,
nr_op => nr_op,
nr_m => nr_m,
mem_style => C_MEM_STYLE,
device => C_DEVICE
)
port map(
data_in => data_in,
data_out => data_out,
rw_address => rw_address,
write_enable => write_enable,
op_sel => op_sel,
xy_out => xy,
m => m,
result_in => r,
load_result => load_result,
result_dest_op => result_dest_op,
collision => collision,
clk => clk,
modulus_sel => modulus_sel_i
);
modulus_sel_i(0) <= modulus_sel;
result_dest_op <= dest_op_single when exp_m = '0' else "11"; -- in autorun mode we always store the result in operand3
-- A fifo for exponentiation mode
xil_prim_fifo : if C_MEM_STYLE="xil_prim" generate
the_exponent_fifo : fifo_primitive
port map(
clk => clk,
din => fifo_din,
dout => fifo_dout,
empty => fifo_empty,
full => fifo_full,
push => fifo_push,
pop => fifo_pop,
reset => reset,
nopop => fifo_nopop,
nopush => fifo_nopush
);
end generate;
gen_fifo : if (C_MEM_STYLE="generic") or (C_MEM_STYLE="asym") generate
the_exponent_fifo : fifo_generic
generic map(
depth => C_FIFO_DEPTH
)
port map(
clk => clk,
din => fifo_din,
dout => fifo_dout,
empty => fifo_empty,
full => fifo_full,
push => fifo_push,
pop => fifo_pop,
reset => reset,
nopop => fifo_nopop,
nopush => fifo_nopush
);
end generate;
-- The control logic for the core
the_control_unit : mont_ctrl
port map(
clk => clk,
reset => reset,
start => start,
x_sel_single => x_sel_single,
y_sel_single => y_sel_single,
run_auto => exp_m,
op_buffer_empty => fifo_empty,
op_sel_buffer => fifo_dout,
read_buffer => fifo_pop,
done => ready,
calc_time => calc_time,
op_sel => op_sel,
load_x => load_x,
load_result => load_result,
start_multiplier => start_mult,
multiplier_ready => mult_ready
);
 
end Structural;
/core/operand_mem.vhd
0,0 → 1,240
----------------------------------------------------------------------
---- operand_mem ----
---- ----
---- This file is part of the ----
---- Modular Simultaneous Exponentiation Core project ----
---- http://www.opencores.org/cores/mod_sim_exp/ ----
---- ----
---- Description ----
---- RAM memory and logic to the store operands and the ----
---- modulus for the montgomery multiplier, the user has a ----
---- choise between 3 memory styles, more detail in the ----
---- documentation ----
---- ----
---- Dependencies: ----
---- - operand_ram ----
---- - modulus_ram ----
---- - operand_ram_gen ----
---- - modulus_ram_gen ----
---- - operand_ram_asym ----
---- - modulus_ram_asym ----
---- ----
---- Authors: ----
---- - Geoffrey Ottoy, DraMCo research group ----
---- - Jonas De Craene, JonasDC@opencores.org ----
---- ----
----------------------------------------------------------------------
---- ----
---- Copyright (C) 2011 DraMCo research group and OPENCORES.ORG ----
---- ----
---- This source file may be used and distributed without ----
---- restriction provided that this copyright statement is not ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer. ----
---- ----
---- This source file is free software; you can redistribute 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 source 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. ----
---- ----
---- You should have received a copy of the GNU Lesser General ----
---- Public License along with this source; if not, download it ----
---- from http://www.opencores.org/lgpl.shtml ----
---- ----
----------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
 
library mod_sim_exp;
use mod_sim_exp.mod_sim_exp_pkg.all;
use mod_sim_exp.std_functions.all;
 
-- address structure:
-- bit: 8 -> '1': modulus
-- '0': operands
-- bits: 7-6 -> operand_in_sel in case of highest bit = '0'
-- modulus_in_sel in case of highest bit = '1'
-- bits: (log2(width/32)-1)-0 -> modulus_addr / operand_addr resp.
--
entity operand_mem is
generic(
width : integer := 1536; -- width of the operands
nr_op : integer := 4; -- nr of operand storages, has to be greater than nr_m
nr_m : integer := 2; -- nr of modulus storages
mem_style : string := "asym"; -- xil_prim, generic, asym are valid options
device : string := "altera" -- xilinx, altera are valid options
);
port(
-- system clock
clk : in std_logic;
-- data interface (plb side)
data_in : in std_logic_vector(31 downto 0);
data_out : out std_logic_vector(31 downto 0);
rw_address : in std_logic_vector(8 downto 0);
write_enable : in std_logic;
-- operand interface (multiplier side)
op_sel : in std_logic_vector(log2(nr_op)-1 downto 0);
xy_out : out std_logic_vector((width-1) downto 0);
m : out std_logic_vector((width-1) downto 0);
result_in : in std_logic_vector((width-1) downto 0);
-- control signals
load_result : in std_logic;
result_dest_op : in std_logic_vector(log2(nr_op)-1 downto 0);
collision : out std_logic;
modulus_sel : in std_logic_vector(log2(nr_m)-1 downto 0)
);
end operand_mem;
 
architecture structural of operand_mem is
-- constants
constant wordaddr_aw : integer := log2(width/32);
constant opaddr_aw : integer := log2(nr_op);
constant maddr_aw : integer := log2(nr_m);
constant total_aw : integer := 1+opaddr_aw+wordaddr_aw;
 
-- internal signals
signal xy_data_i : std_logic_vector(31 downto 0);
signal xy_addr_i : std_logic_vector(wordaddr_aw-1 downto 0);
signal operand_in_sel_i : std_logic_vector(opaddr_aw-1 downto 0);
signal modulus_in_sel_i : std_logic_vector(maddr_aw-1 downto 0);
 
signal load_op : std_logic;
 
signal m_addr_i : std_logic_vector(wordaddr_aw-1 downto 0);
signal load_m : std_logic;
signal m_data_i : std_logic_vector(31 downto 0);
 
begin
 
-- map inputs
xy_addr_i <= rw_address(wordaddr_aw-1 downto 0);
m_addr_i <= rw_address(wordaddr_aw-1 downto 0);
operand_in_sel_i <= rw_address(7 downto 6);
modulus_in_sel_i <= rw_address(6 downto 6);
xy_data_i <= data_in;
m_data_i <= data_in;
-- select right memory with highest address bit
load_op <= write_enable when (rw_address(8) = '0') else '0';
load_m <= write_enable when (rw_address(8) = '1') else '0';
 
xil_prim_RAM : if mem_style="xil_prim" generate
-- xy operand storage
xy_ram_xil : operand_ram
port map(
clk => clk,
collision => collision,
operand_addr => xy_addr_i,
operand_in => xy_data_i,
operand_in_sel => operand_in_sel_i,
result_out => data_out,
write_operand => load_op,
operand_out => xy_out,
operand_out_sel => op_sel,
result_dest_op => result_dest_op,
write_result => load_result,
result_in => result_in
);
-- modulus storage
m_ram_xil : modulus_ram
port map(
clk => clk,
modulus_addr => m_addr_i,
write_modulus => load_m,
modulus_in => m_data_i,
modulus_out => m
);
end generate;
 
gen_RAM : if mem_style="generic" generate
-- xy operand storage
xy_ram_gen : operand_ram_gen
generic map(
width => width,
depth => nr_op
)
port map(
clk => clk,
collision => collision,
operand_addr => xy_addr_i,
operand_in => xy_data_i,
operand_in_sel => operand_in_sel_i,
result_out => data_out,
write_operand => load_op,
operand_out => xy_out,
operand_out_sel => op_sel,
result_dest_op => result_dest_op,
write_result => load_result,
result_in => result_in
);
-- modulus storage
m_ram_gen : modulus_ram_gen
generic map(
width => width,
depth => nr_m
)
port map(
clk => clk,
modulus_in_sel => modulus_in_sel_i,
modulus_addr => m_addr_i,
write_modulus => load_m,
modulus_in => m_data_i,
modulus_out => m,
modulus_sel => modulus_sel
);
end generate;
 
asym_RAM : if mem_style="asym" generate
-- xy operand storage
xy_ram_asym : operand_ram_asym
generic map(
width => width,
depth => nr_op,
device => device
)
port map(
clk => clk,
collision => collision,
operand_addr => xy_addr_i,
operand_in => xy_data_i,
operand_in_sel => operand_in_sel_i,
result_out => data_out,
write_operand => load_op,
operand_out => xy_out,
operand_out_sel => op_sel,
result_dest_op => result_dest_op,
write_result => load_result,
result_in => result_in
);
-- modulus storage
m_ram_asym : modulus_ram_asym
generic map(
width => width,
depth => nr_m,
device => device
)
port map(
clk => clk,
modulus_in_sel => modulus_in_sel_i,
modulus_addr => m_addr_i,
write_modulus => load_m,
modulus_in => m_data_i,
modulus_out => m,
modulus_sel => modulus_sel
);
end generate;
end structural;
/core/fifo_generic.vhd
0,0 → 1,151
----------------------------------------------------------------------
---- fifo_generic ----
---- ----
---- This file is part of the ----
---- Modular Simultaneous Exponentiation Core project ----
---- http://www.opencores.org/cores/mod_sim_exp/ ----
---- ----
---- Description ----
---- behavorial description of a FIFO, correctly inferred by ----
---- altera and xilinx. ----
---- ----
---- Resources needed (xilinx): ----
---- - RAM: (depth+1 * 32) bits ----
---- - 2 adders/substractors ----
---- - 2 comparators ----
---- - 2 registers: aw bits (for the address pointers) ----
---- - 3 registers: 1 bit (for the flags) ----
---- ----
---- Authors: ----
---- - Geoffrey Ottoy, DraMCo research group ----
---- - Jonas De Craene, JonasDC@opencores.org ----
---- ----
----------------------------------------------------------------------
---- ----
---- Copyright (C) 2011 DraMCo research group and OPENCORES.ORG ----
---- ----
---- This source file may be used and distributed without ----
---- restriction provided that this copyright statement is not ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer. ----
---- ----
---- This source file is free software; you can redistribute 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 source 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. ----
---- ----
---- You should have received a copy of the GNU Lesser General ----
---- Public License along with this source; if not, download it ----
---- from http://www.opencores.org/lgpl.shtml ----
---- ----
----------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
 
library mod_sim_exp;
use mod_sim_exp.mod_sim_exp_pkg.all;
use mod_sim_exp.std_functions.all;
 
entity fifo_generic is
generic (
depth : integer := 32
);
port (
clk : in std_logic; -- clock input
din : in std_logic_vector (31 downto 0); -- 32 bit input data for push
dout : out std_logic_vector (31 downto 0); -- 32 bit output data for pop
empty : out std_logic; -- empty flag, 1 when FIFO is empty
full : out std_logic; -- full flag, 1 when FIFO is full
push : in std_logic;
pop : in std_logic;
reset : in std_logic;
nopop : out std_logic;
nopush : out std_logic
);
end fifo_generic;
 
architecture arch of fifo_generic is
-- calculate the width for the address-pointers
constant aw : integer := log2(depth+1);
 
-- read and write pointer
signal rd_addr : std_logic_vector(aw-1 downto 0);
signal wr_addr : std_logic_vector(aw-1 downto 0);
-- control signals
signal empty_i : std_logic;
signal full_i : std_logic;
signal push_i : std_logic;
signal push_i_d : std_logic;
signal pop_i : std_logic;
begin
empty <= empty_i;
full <= full_i;
-- full flag is 1 when read address is one below write address
full_i <= '1' when (wr_addr+'1'=rd_addr) or
(wr_addr=conv_std_logic_vector(depth, aw) and (rd_addr=conv_std_logic_vector(0, aw)))
else '0';
-- empty flag is 1 when read and write address are the same
empty_i <= '1' when (wr_addr=rd_addr) else '0';
fifo_addr_proc : process (clk)
begin
if rising_edge(clk) then
if reset='1' then -- if reset, both read and write address point to the maximum address (depth)
wr_addr <= conv_std_logic_vector(depth, aw);
rd_addr <= conv_std_logic_vector(depth, aw);
else
if push_i='1' then -- push
if (wr_addr=conv_std_logic_vector(depth, aw)) then
wr_addr <= (others=>'0'); -- if overflow, set to zero
else
wr_addr <= wr_addr+'1'; -- else, increase address
end if;
end if;
if pop_i='1' then -- pop
if (rd_addr=conv_std_logic_vector(depth, aw)) then
rd_addr <= (others=>'0'); -- if overflow, set to zero
else
rd_addr <= rd_addr+'1'; -- else, increase address
end if;
end if;
end if;
push_i_d <= push_i; -- delayed version of push signal
nopop <= (pop and empty_i) or (pop and reset);
nopush <= (push and full_i) or (push and reset);
end if;
end process;
push_i <= push and not full_i;
pop_i <= pop and not empty_i;
-- Block RAM
ramblock: dpram_generic
generic map(
depth => depth+1
)
port map(
clk => clk,
-- write port
waddr => wr_addr,
we => push_i_d,
din => din,
-- read port
raddr => rd_addr,
dout => dout
);
 
end arch;
/core/operand_ram_asym.vhd
0,0 → 1,235
----------------------------------------------------------------------
---- operand_ram_asym ----
---- ----
---- This file is part of the ----
---- Modular Simultaneous Exponentiation Core project ----
---- http://www.opencores.org/cores/mod_sim_exp/ ----
---- ----
---- Description ----
---- BRAM memory and logic to store the operands, due to the ----
---- achitecture, a minimum depth of 2 is needed for this ----
---- module to be inferred into blockram, this version is ----
---- slightly more performant than operand_ram_gen and uses ----
---- less resources. but does not work on every fpga, only ----
---- the ones that support asymmetric rams. ----
---- ----
---- Dependencies: ----
---- - tdpramblock_asym ----
---- ----
---- Authors: ----
---- - Geoffrey Ottoy, DraMCo research group ----
---- - Jonas De Craene, JonasDC@opencores.org ----
---- ----
----------------------------------------------------------------------
---- ----
---- Copyright (C) 2011 DraMCo research group and OPENCORES.ORG ----
---- ----
---- This source file may be used and distributed without ----
---- restriction provided that this copyright statement is not ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer. ----
---- ----
---- This source file is free software; you can redistribute 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 source 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. ----
---- ----
---- You should have received a copy of the GNU Lesser General ----
---- Public License along with this source; if not, download it ----
---- from http://www.opencores.org/lgpl.shtml ----
---- ----
----------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
 
library mod_sim_exp;
use mod_sim_exp.std_functions.all;
 
-- structural description of a RAM to hold the operands, with
-- adjustable width (64, 128, 256, 512, 576, 640,..) and depth(nr of operands)
-- formula for available widths: (i*512+(0 or 64 or 128 or 256)) (i=integer number)
--
entity operand_ram_asym is
generic(
width : integer := 1536; -- width of the operands
depth : integer := 4; -- nr of operands
device : string := "xilinx"
);
port(
-- global ports
clk : in std_logic;
collision : out std_logic; -- 1 if simultaneous write on RAM
-- bus side connections (32-bit serial)
write_operand : in std_logic; -- write_enable
operand_in_sel : in std_logic_vector(log2(depth)-1 downto 0); -- operand to write to
operand_addr : in std_logic_vector(log2(width/32)-1 downto 0); -- address of operand word to write
operand_in : in std_logic_vector(31 downto 0); -- operand word(32-bit) to write
result_out : out std_logic_vector(31 downto 0); -- operand out, reading is always result operand
operand_out_sel : in std_logic_vector(log2(depth)-1 downto 0); -- operand to give to multiplier
-- multiplier side connections (width-bit parallel)
result_dest_op : in std_logic_vector(log2(depth)-1 downto 0); -- operand select for result
operand_out : out std_logic_vector(width-1 downto 0); -- operand out to multiplier
write_result : in std_logic; -- write enable for multiplier side
result_in : in std_logic_vector(width-1 downto 0) -- result to write from multiplier
);
end operand_ram_asym;
 
architecture Behavioral of operand_ram_asym is
-- contstants
constant RAMblock_maxwidth : integer := 512;
constant nrRAMblocks_full : integer := width/RAMblock_maxwidth;
constant RAMblock_part : integer := width rem RAMblock_maxwidth;
constant RAMblock_part_width : integer := width-(nrRAMblocks_full*RAMblock_maxwidth);
constant RAMselect_aw : integer := log2(width/32)-log2(nrRAMblocks_full/32);
-- internal signals
signal mult_op_sel : std_logic_vector(log2(depth)-1 downto 0);
signal write_operand_i : std_logic;
begin
-- WARNING: Very Important!
-- wea & web signals must never be high at the same time !!
-- web has priority
write_operand_i <= write_operand and not write_result; -- portB has write priority
collision <= write_operand and write_result;
 
-- when multiplier is writing back result, select the result address
with write_result select
mult_op_sel <= result_dest_op when '1',
operand_out_sel when others;
-- generate (width/512) ramblocks with a given depth
-- these rams are tyed together to form the following structure
-- True dual port ram:
-- - PORT A : 32-bit write | 32-bit read
-- - PORT B : (width)-bit write | (width)-bit read
--
single_block : if (width <= RAMblock_maxwidth) generate
-- signals for single block
signal addrA_single : std_logic_vector(log2(width*depth/32)-1 downto 0);
begin
addrA_single <= operand_in_sel & operand_addr;
ramblock : entity mod_sim_exp.tdpramblock_asym
generic map(
depth => depth,
width => width,
device => device
)
port map(
clk => clk,
-- port A 32-bit
addrA => addrA_single,
weA => write_operand_i,
dinA => operand_in,
doutA => result_out,
-- port B (width)-bit
addrB => mult_op_sel,
weB => write_result,
dinB => result_in,
doutB => operand_out
);
end generate;
multiple_full_blocks : if (width > RAMblock_maxwidth) generate
-- signals for multiple blocks
type wordsplit is array (nrRAMblocks_full downto 0) of std_logic_vector(31 downto 0);
signal doutA_RAM : wordsplit;
signal addrA : std_logic_vector(log2(RAMblock_maxwidth*depth/32)-1 downto 0);
signal weA_RAM : std_logic_vector(nrRAMblocks_full-1 downto 0);
begin
ramblocks_full : for i in 0 to nrRAMblocks_full generate
-- port A signals
addrA <= operand_in_sel & operand_addr(log2(RAMblock_maxwidth/32)-1 downto 0);
full_ones : if (i < nrRAMblocks_full) generate
ramblock_full : entity mod_sim_exp.tdpramblock_asym
generic map(
depth => depth,
width => RAMblock_maxwidth,
device => device
)
port map(
clk => clk,
-- port A 32-bit
addrA => addrA,
weA => weA_RAM(i),
dinA => operand_in,
doutA => doutA_RAM(i),
-- port B (width)-bit
addrB => mult_op_sel,
weB => write_result,
dinB => result_in((i+1)*RAMblock_maxwidth-1 downto i*RAMblock_maxwidth),
doutB => operand_out((i+1)*RAMblock_maxwidth-1 downto i*RAMblock_maxwidth)
);
-- weA, weB
process (write_operand_i, operand_addr)
begin
if operand_addr(log2(width/32)-1 downto log2(RAMblock_maxwidth/32)) = conv_std_logic_vector(i,RAMselect_aw) then
weA_RAM(i) <= write_operand_i;
else
weA_RAM(i) <= '0';
end if;
end process;
only_once : if (i = 0) generate
-- port A read mux
only_full_blocks : if (RAMblock_part = 0) generate
result_out <= doutA_RAM(conv_integer(operand_addr(log2(width/32)-1 downto log2(RAMblock_maxwidth/32))))
when (conv_integer(operand_addr(log2(width/32)-1 downto log2(RAMblock_maxwidth/32)))<nrRAMblocks_full)
else (others=>'0');
end generate;
with_extra_part : if (RAMblock_part /= 0) generate
result_out <= doutA_RAM(conv_integer(operand_addr(log2(width/32)-1 downto log2(RAMblock_maxwidth/32))))
when (conv_integer(operand_addr(log2(width/32)-1 downto log2(RAMblock_maxwidth/32)))<nrRAMblocks_full+1)
else (others=>'0');
end generate;
end generate;
end generate;
optional_part : if (i = nrRAMblocks_full) and (RAMblock_part /= 0) generate
-- signals for part
signal addrA_part : std_logic_vector(log2(RAMblock_part_width*depth/32)-1 downto 0);
signal weA_part : std_logic;
begin
addrA_part <= operand_in_sel & operand_addr(log2(RAMblock_part_width/32)-1 downto 0);
ramblock_part : entity mod_sim_exp.tdpramblock_asym
generic map(
depth => depth,
width => RAMblock_part_width,
device => device
)
port map(
clk => clk,
-- port A 32-bit
addrA => addrA_part,
weA => weA_part,
dinA => operand_in,
doutA => doutA_RAM(i),
-- port B (width)-bit
addrB => mult_op_sel,
weB => write_result,
dinB => result_in(width-1 downto i*RAMblock_maxwidth),
doutB => operand_out(width-1 downto i*RAMblock_maxwidth)
);
-- weA, weB part
process (write_operand_i, operand_addr)
begin
if operand_addr(log2(width/32)-1 downto log2(RAMblock_maxwidth/32)) = conv_std_logic_vector(i,RAMselect_aw) then
weA_part <= write_operand_i;
else
weA_part <= '0';
end if;
end process;
end generate;
end generate;
end generate;
 
end Behavioral;
/core/modulus_ram_asym.vhd
0,0 → 1,194
----------------------------------------------------------------------
---- modulus_ram_asym ----
---- ----
---- This file is part of the ----
---- Modular Simultaneous Exponentiation Core project ----
---- http://www.opencores.org/cores/mod_sim_exp/ ----
---- ----
---- Description ----
---- BRAM memory and logic to store the modulus, due to the ----
---- achitecture, a minimum depth of 2 is needed for this ----
---- module to be inferred into blockram, this version is ----
---- slightly more performant than modulus_ram_gen and uses ----
---- less resources. but does not work on every fpga, only ----
---- the ones that support asymmetric rams. ----
---- ----
---- Dependencies: ----
---- - dpramblock_asym ----
---- ----
---- Authors: ----
---- - Geoffrey Ottoy, DraMCo research group ----
---- - Jonas De Craene, JonasDC@opencores.org ----
---- ----
----------------------------------------------------------------------
---- ----
---- Copyright (C) 2011 DraMCo research group and OPENCORES.ORG ----
---- ----
---- This source file may be used and distributed without ----
---- restriction provided that this copyright statement is not ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer. ----
---- ----
---- This source file is free software; you can redistribute 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 source 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. ----
---- ----
---- You should have received a copy of the GNU Lesser General ----
---- Public License along with this source; if not, download it ----
---- from http://www.opencores.org/lgpl.shtml ----
---- ----
----------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
 
library mod_sim_exp;
use mod_sim_exp.std_functions.all;
 
-- structural description of a RAM to hold the modulus, with
-- adjustable width (64, 128, 256, 512, 576, 640,..) and depth(nr of moduluses)
-- formula for available widths: (i*512+(0 or 64 or 128 or 256)) (i=integer number)
--
entity modulus_ram_asym is
generic(
width : integer := 1536; -- must be a multiple of 32
depth : integer := 2; -- nr of moduluses
device : string := "xilinx"
);
port(
clk : in std_logic;
-- bus side
write_modulus : in std_logic; -- write enable
modulus_in_sel : in std_logic_vector(log2(depth)-1 downto 0); -- modulus operand to write to
modulus_addr : in std_logic_vector(log2((width)/32)-1 downto 0); -- modulus word(32-bit) address
modulus_in : in std_logic_vector(31 downto 0); -- modulus word data in
modulus_sel : in std_logic_vector(log2(depth)-1 downto 0); -- selects the modulus to use for multiplications
-- multiplier side
modulus_out : out std_logic_vector(width-1 downto 0)
);
end modulus_ram_asym;
 
architecture structural of modulus_ram_asym is
-- constants
constant RAMblock_maxwidth : integer := 512;
constant nrRAMblocks_full : integer := width/RAMblock_maxwidth;
constant RAMblock_part : integer := width rem RAMblock_maxwidth;
constant RAMblock_part_width : integer := width-(nrRAMblocks_full*RAMblock_maxwidth);
constant RAMselect_aw : integer := log2(width/32)-log2(nrRAMblocks_full/32);
 
begin
-- generate (width/512) ramblocks with a given depth
-- these rams are tyed together to form the following structure
-- dual port ram:
-- - PORT A : 32-bit write
-- - PORT B : (width)-bit read
--
single_block : if (width <= RAMblock_maxwidth) generate
signal waddr : std_logic_vector(log2((width*depth)/32)-1 downto 0);
begin
waddr <= modulus_in_sel & modulus_addr;
ramblock: entity mod_sim_exp.dpramblock_asym
generic map(
width => width,
depth => depth,
device => device
)
port map(
clk => clk,
-- write port
waddr => waddr,
we => write_modulus,
din => modulus_in,
-- read port
raddr => modulus_sel,
dout => modulus_out
);
end generate;
multiple_full_blocks : if (width > RAMblock_maxwidth) generate
-- signals for multiple blocks
signal waddr : std_logic_vector(log2(RAMblock_maxwidth*depth/32)-1 downto 0);
signal we_RAM : std_logic_vector(nrRAMblocks_full-1 downto 0);
begin
ramblocks_full : for i in 0 to nrRAMblocks_full generate
-- write port signal
waddr <= modulus_in_sel & modulus_addr(log2(RAMblock_maxwidth/32)-1 downto 0);
full_ones : if (i < nrRAMblocks_full) generate
ramblock_full : entity mod_sim_exp.dpramblock_asym
generic map(
width => RAMblock_maxwidth,
depth => depth,
device => device
)
port map(
clk => clk,
-- write port
waddr => waddr,
we => we_RAM(i),
din => modulus_in,
-- read port
raddr => modulus_sel,
dout => modulus_out((i+1)*RAMblock_maxwidth-1 downto i*RAMblock_maxwidth)
);
-- we
process (write_modulus, modulus_addr)
begin
if modulus_addr(log2(width/32)-1 downto log2(RAMblock_maxwidth/32)) = conv_std_logic_vector(i,RAMselect_aw) then
we_RAM(i) <= write_modulus;
else
we_RAM(i) <= '0';
end if;
end process;
end generate; -- end of if generate for full blocks
optional_part : if (i = nrRAMblocks_full) and (RAMblock_part /= 0) generate
-- signals for optional part
signal waddr_part : std_logic_vector(log2(RAMblock_part_width*depth/32)-1 downto 0);
signal we_part : std_logic;
begin
-- write port signal
waddr_part <= modulus_in_sel & modulus_addr(log2(RAMblock_part_width/32)-1 downto 0);
ramblock_part : entity mod_sim_exp.dpramblock_asym
generic map(
width => RAMblock_part_width,
depth => depth,
device => device
)
port map(
clk => clk,
-- write port
waddr => waddr_part,
we => we_part,
din => modulus_in,
-- read port
raddr => modulus_sel,
dout => modulus_out(width-1 downto i*RAMblock_maxwidth)
);
-- we_part
process (write_modulus, modulus_addr)
begin
if modulus_addr(log2(width/32)-1 downto log2(RAMblock_maxwidth/32)) = conv_std_logic_vector(i,RAMselect_aw) then
we_part <= write_modulus;
else
we_part <= '0';
end if;
end process;
end generate;-- end of if generate for part block
end generate;-- end of for generate
end generate;-- end of if generate for multiple blocks
 
end structural;
/core/modulus_ram_gen.vhd
0,0 → 1,120
----------------------------------------------------------------------
---- modulus_ram_gen ----
---- ----
---- This file is part of the ----
---- Modular Simultaneous Exponentiation Core project ----
---- http://www.opencores.org/cores/mod_sim_exp/ ----
---- ----
---- Description ----
---- BRAM memory and logic to store the modulus, due to the ----
---- achitecture, a minimum depth of 2 is needed for this ----
---- module to be inferred into blockram ----
---- ----
---- Dependencies: ----
---- - dpram_generic ----
---- ----
---- Authors: ----
---- - Geoffrey Ottoy, DraMCo research group ----
---- - Jonas De Craene, JonasDC@opencores.org ----
---- ----
----------------------------------------------------------------------
---- ----
---- Copyright (C) 2011 DraMCo research group and OPENCORES.ORG ----
---- ----
---- This source file may be used and distributed without ----
---- restriction provided that this copyright statement is not ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer. ----
---- ----
---- This source file is free software; you can redistribute 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 source 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. ----
---- ----
---- You should have received a copy of the GNU Lesser General ----
---- Public License along with this source; if not, download it ----
---- from http://www.opencores.org/lgpl.shtml ----
---- ----
----------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
 
library mod_sim_exp;
use mod_sim_exp.mod_sim_exp_pkg.all;
use mod_sim_exp.std_functions.all;
 
-- behavorial description of a RAM to hold the modulus, with
-- adjustable width and depth(nr of moduluses)
entity modulus_ram_gen is
generic(
width : integer := 1536; -- must be a multiple of 32
depth : integer := 2 -- nr of moduluses
);
port(
clk : in std_logic;
-- bus side
write_modulus : in std_logic; -- write enable
modulus_in_sel : in std_logic_vector(log2(depth)-1 downto 0); -- modulus operand to write to
modulus_addr : in std_logic_vector(log2((width)/32)-1 downto 0); -- modulus word(32-bit) address
modulus_in : in std_logic_vector(31 downto 0); -- modulus word data in
modulus_sel : in std_logic_vector(log2(depth)-1 downto 0); -- selects the modulus to use for multiplications
-- multiplier side
modulus_out : out std_logic_vector(width-1 downto 0)
);
end modulus_ram_gen;
 
architecture Behavioral of modulus_ram_gen is
--- constants
constant nrRAMs : integer := width/32;
constant RAMselect_aw : integer := log2(nrRAMs);
constant RAMdepth_aw : integer := log2(depth);
constant total_aw : integer := RAMdepth_aw+RAMselect_aw;
 
-- interconnection signals
signal modulus_rdaddr : std_logic_vector(RAMdepth_aw-1 downto 0);
signal modulus_wraddr : std_logic_vector(total_aw-1 downto 0);
signal we : std_logic_vector(nrRAMs-1 downto 0);
begin
modulus_wraddr(RAMselect_aw-1 downto 0) <= modulus_addr;
modulus_wraddr(total_aw-1 downto RAMselect_aw) <= modulus_in_sel;
-- generate (width/32) blocks of 32-bit ram with a given depth
-- these rams outputs are concatenated to a width-bit signal
ramblocks : for i in 0 to nrRAMs-1 generate
ramblock: dpram_generic
generic map(
depth => depth
)
port map(
clk => clk,
-- write port
waddr => modulus_wraddr(total_aw-1 downto RAMselect_aw),
we => we(i),
din => modulus_in,
-- read port
raddr => modulus_rdaddr,
dout => modulus_out(((i+1)*32)-1 downto i*32)
);
-- connect the w
process (write_modulus, modulus_wraddr)
begin
if modulus_wraddr(RAMselect_aw-1 downto 0) = conv_std_logic_vector(i,RAMselect_aw) then
we(i) <= write_modulus;
else
we(i) <= '0';
end if;
end process;
end generate;
modulus_rdaddr <= modulus_sel;
end Behavioral;
/core/operand_ram_gen.vhd
0,0 → 1,177
----------------------------------------------------------------------
---- operand_ram_gen ----
---- ----
---- This file is part of the ----
---- Modular Simultaneous Exponentiation Core project ----
---- http://www.opencores.org/cores/mod_sim_exp/ ----
---- ----
---- Description ----
---- BRAM memory and logic to the store the operands ----
---- for the montgomery multiplier ----
---- ----
---- Dependencies: ----
---- - tdpram_generic ----
---- ----
---- Authors: ----
---- - Geoffrey Ottoy, DraMCo research group ----
---- - Jonas De Craene, JonasDC@opencores.org ----
---- ----
----------------------------------------------------------------------
---- ----
---- Copyright (C) 2011 DraMCo research group and OPENCORES.ORG ----
---- ----
---- This source file may be used and distributed without ----
---- restriction provided that this copyright statement is not ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer. ----
---- ----
---- This source file is free software; you can redistribute 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 source 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. ----
---- ----
---- You should have received a copy of the GNU Lesser General ----
---- Public License along with this source; if not, download it ----
---- from http://www.opencores.org/lgpl.shtml ----
---- ----
----------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
 
library mod_sim_exp;
use mod_sim_exp.mod_sim_exp_pkg.all;
use mod_sim_exp.std_functions.all;
 
-- behavorial description of a RAM to hold the operands, with
-- adjustable width and depth(nr of operands)
entity operand_ram_gen is
generic(
width : integer := 1536; -- width of the operands
depth : integer := 4 -- nr of operands
);
port(
-- global ports
clk : in std_logic;
collision : out std_logic; -- 1 if simultaneous write on RAM
-- bus side connections (32-bit serial)
write_operand : in std_logic; -- write_enable
operand_in_sel : in std_logic_vector(log2(depth)-1 downto 0); -- operand to write to
operand_addr : in std_logic_vector(log2(width/32)-1 downto 0); -- address of operand word to write
operand_in : in std_logic_vector(31 downto 0); -- operand word(32-bit) to write
result_out : out std_logic_vector(31 downto 0); -- operand out, reading is always result operand
operand_out_sel : in std_logic_vector(log2(depth)-1 downto 0); -- operand to give to multiplier
-- multiplier side connections (width-bit parallel)
result_dest_op : in std_logic_vector(log2(depth)-1 downto 0); -- operand select for result
operand_out : out std_logic_vector(width-1 downto 0); -- operand out to multiplier
write_result : in std_logic; -- write enable for multiplier side
result_in : in std_logic_vector(width-1 downto 0) -- result to write from multiplier
);
end operand_ram_gen;
 
 
architecture Behavioral of operand_ram_gen is
constant nrRAMs : integer := width/32;
constant RAMselect_aw : integer := log2(nrRAMs);
constant RAMdepth_aw : integer := log2(depth);
constant total_aw : integer := RAMdepth_aw+RAMselect_aw;
-- total RAM structure signals
signal weA_RAM : std_logic_vector(nrRAMs-1 downto 0);
type wordsplit is array (nrRAMs-1 downto 0) of std_logic_vector(31 downto 0);
signal doutB_RAM : wordsplit;
--- PORT A : 32-bit write | (width)-bit read
signal dinA : std_logic_vector(31 downto 0);
signal doutA : std_logic_vector(width-1 downto 0);
signal weA : std_logic;
signal addrA : std_logic_vector(RAMselect_aw-1 downto 0);
signal op_selA : std_logic_vector(RAMdepth_aw-1 downto 0);
--- PORT B : 32-bit read | (width)-bit write
signal dinB : std_logic_vector(width-1 downto 0);
signal doutB : std_logic_vector(31 downto 0);
signal weB : std_logic;
signal addrB : std_logic_vector(RAMselect_aw-1 downto 0);
signal op_selB : std_logic_vector(RAMdepth_aw-1 downto 0);
signal write_operand_i : std_logic;
signal op_selA_i : std_logic_vector(RAMdepth_aw-1 downto 0);
begin
 
-- WARNING: Very Important!
-- wea & web signals must never be high at the same time !!
-- web has priority
write_operand_i <= write_operand and not write_result; -- portB has write priority
collision <= write_operand and write_result;
-- the dual port ram has a depth of 4 (each layer contains an operand)
-- result is always stored in position 3
-- doutb is always result
with write_operand_i select
op_selA_i <= operand_in_sel when '1',
operand_out_sel when others;
-- map signals to RAM
-- PORTA
weA <= write_operand_i;
op_selA <= op_selA_i;
addrA <= operand_addr;
dinA <= operand_in;
operand_out <= doutA;
-- PORT B
weB <= write_result;
op_selB <= result_dest_op; -- portB locked to result operand
addrB <= operand_addr;
dinB <= result_in;
result_out <= doutB;
-- generate (width/32) blocks of 32-bit ram with a given depth
-- these rams are tyed together to form the following structure
-- True dual port ram:
-- - PORT A : 32-bit write | (width)-bit read
-- - PORT B : 32-bit read | (width)-bit write
-- ^ ^
-- addres addr op_sel
--
ramblocks : for i in 0 to nrRAMs-1 generate
ramblock: tdpram_generic
generic map(
depth => depth
)
port map(
-- port A : 32-bit
clkA => clk,
addrA => op_selA,
weA => weA_RAM(i),
dinA => dinA,
doutA => doutA(((i+1)*32)-1 downto i*32),
-- port B : 32-bit
clkB => clk,
addrB => op_selB,
weB => weB,
dinB => dinB(((i+1)*32)-1 downto i*32),
doutB => doutB_RAM(i)
);
-- demultiplexer for write enable A signal
process (addrA, weA)
begin
if addrA(RAMselect_aw-1 downto 0) = conv_std_logic_vector(i,RAMselect_aw) then
weA_RAM(i) <= weA;
else
weA_RAM(i) <= '0';
end if;
end process;
end generate;
-- PORTB 32-bit read
doutB <= doutB_RAM(conv_integer(addrB)) when (conv_integer(addrB)<nrRAMs)
else (others=>'0');
end Behavioral;
/core/std_functions.vhd
0,0 → 1,81
----------------------------------------------------------------------
---- std_functions ----
---- ----
---- This file is part of the ----
---- Modular Simultaneous Exponentiation Core project ----
---- http://www.opencores.org/cores/mod_sim_exp/ ----
---- ----
---- Description ----
---- package with standard functions used in this project ----
---- ----
---- Authors: ----
---- - Geoffrey Ottoy, DraMCo research group ----
---- - Jonas De Craene, JonasDC@opencores.org ----
---- ----
----------------------------------------------------------------------
---- ----
---- Copyright (C) 2011 DraMCo research group and OPENCORES.ORG ----
---- ----
---- This source file may be used and distributed without ----
---- restriction provided that this copyright statement is not ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer. ----
---- ----
---- This source file is free software; you can redistribute 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 source 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. ----
---- ----
---- You should have received a copy of the GNU Lesser General ----
---- Public License along with this source; if not, download it ----
---- from http://www.opencores.org/lgpl.shtml ----
---- ----
----------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
package std_functions is
function maxV(L, R: INTEGER) return INTEGER;
function minV(L, R: INTEGER) return INTEGER;
function log2 (val: INTEGER) return natural;
end std_functions;
 
package body std_functions is
function maxV(L, R: INTEGER) return INTEGER is
begin
if L > R then
return L;
else
return R;
end if;
end;
 
function minV(L, R: INTEGER) return INTEGER is
begin
if L < R then
return L;
else
return R;
end if;
end;
 
function log2 (val: INTEGER) return natural is
variable res : natural;
begin
for i in 0 to 31 loop
if (val <= (2**i)) then
res := i;
exit;
end if;
end loop;
return res;
end function Log2;
end std_functions;
/core/autorun_cntrl.vhd
0,0 → 1,185
----------------------------------------------------------------------
---- autorun_ctrl ----
---- ----
---- This file is part of the ----
---- Modular Simultaneous Exponentiation Core project ----
---- http://www.opencores.org/cores/mod_sim_exp/ ----
---- ----
---- Description ----
---- autorun control unit for a pipelined montgomery ----
---- multiplier ----
---- ----
---- Dependencies: none ----
---- ----
---- Authors: ----
---- - Geoffrey Ottoy, DraMCo research group ----
---- - Jonas De Craene, JonasDC@opencores.org ----
---- ----
----------------------------------------------------------------------
---- ----
---- Copyright (C) 2011 DraMCo research group and OPENCORES.ORG ----
---- ----
---- This source file may be used and distributed without ----
---- restriction provided that this copyright statement is not ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer. ----
---- ----
---- This source file is free software; you can redistribute 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 source 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. ----
---- ----
---- You should have received a copy of the GNU Lesser General ----
---- Public License along with this source; if not, download it ----
---- from http://www.opencores.org/lgpl.shtml ----
---- ----
----------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
 
 
entity autorun_cntrl is
port (
clk : in std_logic;
reset : in std_logic;
start : in std_logic;
done : out std_logic;
op_sel : out std_logic_vector (1 downto 0);
start_multiplier : out std_logic;
multiplier_done : in std_logic;
read_buffer : out std_logic;
buffer_din : in std_logic_vector (31 downto 0);
buffer_empty : in std_logic
);
end autorun_cntrl;
 
 
architecture Behavioral of autorun_cntrl is
 
signal bit_counter_i : integer range 0 to 15 := 0;
signal bit_counter_0_i : std_logic;
signal bit_counter_15_i : std_logic;
signal next_bit_i : std_logic := '0';
signal start_cycle_i : std_logic := '0';
signal start_cycle_del_i : std_logic;
signal done_i : std_logic;
signal running_i : std_logic;
signal start_multiplier_i : std_logic;
signal start_multiplier_del_i : std_logic;
signal mult_done_del_i : std_logic;
signal e0_i : std_logic_vector(15 downto 0);
signal e1_i : std_logic_vector(15 downto 0);
signal e0_bit_i : std_logic;
signal e1_bit_i : std_logic;
signal e_bits_i : std_logic_vector(1 downto 0);
signal e_bits_0_i : std_logic;
signal cycle_counter_i : std_logic;
signal op_sel_sel_i : std_logic;
signal op_sel_i : std_logic_vector(1 downto 0);
begin
 
done <= done_i;
-- the two exponents
e0_i <= buffer_din(15 downto 0);
e1_i <= buffer_din(31 downto 16);
 
-- generate the index to select a single bit from the two exponents
SYNC_BIT_COUNTER: process (clk, reset)
begin
if reset = '1' then
bit_counter_i <= 15;
elsif rising_edge(clk) then
if start = '1' then -- make sure we start @ bit 0
bit_counter_i <= 15;
elsif next_bit_i = '1' then -- count
if bit_counter_i = 0 then
bit_counter_i <= 15;
else
bit_counter_i <= bit_counter_i - 1;
end if;
end if;
end if;
end process SYNC_BIT_COUNTER;
-- signal when bit_counter_i = 0
bit_counter_0_i <= '1' when bit_counter_i=0 else '0';
bit_counter_15_i <= '1' when bit_counter_i=15 else '0';
-- the bits...
e0_bit_i <= e0_i(bit_counter_i);
e1_bit_i <= e1_i(bit_counter_i);
e_bits_i <= e0_bit_i & e1_bit_i;
e_bits_0_i <= '1' when (e_bits_i = "00") else '0';
-- operand pre-select
with e_bits_i select
op_sel_i <= "00" when "10", -- gt0
"01" when "01", -- gt1
"10" when "11", -- gt01
"11" when others;
-- select operands
op_sel_sel_i <= '0' when e_bits_0_i = '1' else (cycle_counter_i);
op_sel <= op_sel_i when op_sel_sel_i = '1' else "11";
-- process that drives running_i signal ('1' when in autorun, '0' when not)
RUNNING_PROC: process(clk, reset)
begin
if reset = '1' then
running_i <= '0';
elsif rising_edge(clk) then
running_i <= start or (running_i and (not done_i));
end if;
end process RUNNING_PROC;
-- ctrl logic
start_multiplier_i <= start_cycle_del_i or (mult_done_del_i and (cycle_counter_i) and (not e_bits_0_i));
read_buffer <= start_cycle_del_i and bit_counter_15_i and running_i; -- pop new word from fifo when bit_counter is back at '15'
start_multiplier <= start_multiplier_del_i and running_i;
-- start/stop logic
start_cycle_i <= (start and (not buffer_empty)) or next_bit_i; -- start pulse (external or internal)
done_i <= (start and buffer_empty) or (next_bit_i and bit_counter_0_i and buffer_empty); -- stop when buffer is empty
next_bit_i <= (mult_done_del_i and e_bits_0_i) or (mult_done_del_i and (not e_bits_0_i) and (not cycle_counter_i));
 
-- process for delaying signals with 1 clock cycle
DEL_PROC: process(clk)
begin
if rising_edge(clk) then
start_multiplier_del_i <= start_multiplier_i;
start_cycle_del_i <= start_cycle_i;
mult_done_del_i <= multiplier_done;
end if;
end process DEL_PROC;
-- process for delaying signals with 1 clock cycle
CYCLE_CNTR_PROC: process(clk, start, reset)
begin
if start = '1' or reset = '1' then
cycle_counter_i <= '0';
elsif rising_edge(clk) then
if (e_bits_0_i = '0') and (multiplier_done = '1') then
cycle_counter_i <= not cycle_counter_i;
elsif (e_bits_0_i = '1') and (multiplier_done = '1') then
cycle_counter_i <= '0';
else
cycle_counter_i <= cycle_counter_i;
end if;
end if;
end process CYCLE_CNTR_PROC;
end Behavioral;
 
/core/mont_ctrl.vhd
0,0 → 1,197
----------------------------------------------------------------------
---- mont_ctrl ----
---- ----
---- This file is part of the ----
---- Modular Simultaneous Exponentiation Core project ----
---- http://www.opencores.org/cores/mod_sim_exp/ ----
---- ----
---- Description ----
---- control unit for a pipelined montgomery multiplier, with ----
---- split pipeline operation and "auto-run" support ----
---- ----
---- Dependencies: ----
---- - autorun_cntrl ----
---- ----
---- Authors: ----
---- - Geoffrey Ottoy, DraMCo research group ----
---- - Jonas De Craene, JonasDC@opencores.org ----
---- ----
----------------------------------------------------------------------
---- ----
---- Copyright (C) 2011 DraMCo research group and OPENCORES.ORG ----
---- ----
---- This source file may be used and distributed without ----
---- restriction provided that this copyright statement is not ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer. ----
---- ----
---- This source file is free software; you can redistribute 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 source 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. ----
---- ----
---- You should have received a copy of the GNU Lesser General ----
---- Public License along with this source; if not, download it ----
---- from http://www.opencores.org/lgpl.shtml ----
---- ----
----------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
 
library mod_sim_exp;
use mod_sim_exp.mod_sim_exp_pkg.all;
 
 
-- This module controls the montgommery mutliplier and controls traffic between
-- RAM and multiplier. Also contains the autorun logic for exponentiations.
entity mont_ctrl is
port (
clk : in std_logic;
reset : in std_logic;
-- bus side
start : in std_logic;
x_sel_single : in std_logic_vector(1 downto 0);
y_sel_single : in std_logic_vector(1 downto 0);
run_auto : in std_logic;
op_buffer_empty : in std_logic;
op_sel_buffer : in std_logic_vector(31 downto 0);
read_buffer : out std_logic;
done : out std_logic;
calc_time : out std_logic;
-- multiplier side
op_sel : out std_logic_vector(1 downto 0);
load_x : out std_logic;
load_result : out std_logic;
start_multiplier : out std_logic;
multiplier_ready : in std_logic
);
end mont_ctrl;
 
 
architecture Behavioral of mont_ctrl is
signal start_d : std_logic; -- delayed version of start input
signal start_pulse : std_logic;
signal auto_start_pulse : std_logic;
signal start_multiplier_i : std_logic;
signal start_up_counter : std_logic_vector(2 downto 0) := "100"; -- used in op_sel at multiplier start
 
signal calc_time_i : std_logic; -- high ('1') during multiplication
 
signal x_sel : std_logic_vector(1 downto 0); -- the operand used as x input
signal y_sel : std_logic_vector(1 downto 0); -- the operand used as y input
signal x_sel_buffer : std_logic_vector(1 downto 0); -- x operand as specified by fifo buffer (autorun)
 
signal auto_done : std_logic;
signal start_auto : std_logic;
signal auto_multiplier_done_i : std_logic;
begin
 
-----------------------------------------------------------------------------------
-- Processes related to starting and stopping the multiplier
-----------------------------------------------------------------------------------
-- generate a start pulse (duration 1 clock cycle) based on ext. start sig
START_PULSE_PROC: process(clk)
begin
if rising_edge(clk) then
start_d <= start;
end if;
end process START_PULSE_PROC;
start_pulse <= start and (not start_d);
start_auto <= start_pulse and run_auto;
 
-- to start the multiplier we first need to select the x_operand and
-- clock it in the x shift register
-- the we select the y_operand and start the multiplier
-- start_up_counter
-- default state : "100"
-- at start pulse counter resets to 0 and counts up to "100"
START_MULT_PROC: process(clk, reset)
begin
if reset = '1' then
start_up_counter <= "100";
elsif rising_edge(clk) then
if start_pulse = '1' or auto_start_pulse = '1' then
start_up_counter <= "000";
elsif start_up_counter(2) /= '1' then
start_up_counter <= start_up_counter + '1';
else
start_up_counter <= "100";
end if;
end if;
end process;
-- select operands (autorun/single run)
x_sel <= x_sel_buffer when (run_auto = '1') else x_sel_single;
y_sel <= "11" when (run_auto = '1') else y_sel_single; -- y is operand3 in auto mode
-- clock operands to operand_mem output (first x, then y)
with start_up_counter(2 downto 1) select
op_sel <= x_sel when "00", -- start_up_counter="00x" (first 2 cycles)
y_sel when others; --
load_x <= start_up_counter(0) and (not start_up_counter(1)); -- latch x operand if start_up_counter="x01"
-- start multiplier when start_up_counter="x11"
start_multiplier_i <= start_up_counter(1) and start_up_counter(0);
start_multiplier <= start_multiplier_i;
 
-- signal calc time is high during multiplication
CALC_TIME_PROC: process(clk, reset)
begin
if reset = '1' then
calc_time_i <= '0';
elsif rising_edge(clk) then
if start_multiplier_i = '1' then
calc_time_i <= '1';
elsif multiplier_ready = '1' then
calc_time_i <= '0';
else
calc_time_i <= calc_time_i;
end if;
end if;
end process CALC_TIME_PROC;
calc_time <= calc_time_i;
-- what happens when a multiplication has finished
load_result <= multiplier_ready;
-- ignore multiplier_ready when in automode, the logic will assert auto_done when finished
done <= ((not run_auto) and multiplier_ready) or auto_done;
-----------------------------------------------------------------------------------
-- Processes related to op_buffer cntrl and auto_run mode
-- start_auto -> start autorun mode operation
-- auto_start_pulse <- autorun logic starts the multiplier
-- auto_done <- autorun logic signals when autorun operation has finished
-- x_sel_buffer <- autorun logic determines which operand is used as x
-- check buffer empty signal
-----------------------------------------------------------------------------------
 
-- multiplier_ready is only passed to autorun control when in autorun mode
auto_multiplier_done_i <= (multiplier_ready and run_auto);
autorun_control_logic : autorun_cntrl port map(
clk => clk,
reset => reset,
start => start_auto,
done => auto_done,
op_sel => x_sel_buffer,
start_multiplier => auto_start_pulse,
multiplier_done => auto_multiplier_done_i,
read_buffer => read_buffer,
buffer_din => op_sel_buffer,
buffer_empty => op_buffer_empty
);
 
end Behavioral;
/core/counter_sync.vhd
0,0 → 1,94
----------------------------------------------------------------------
---- counter_sync ----
---- ----
---- This file is part of the ----
---- Modular Simultaneous Exponentiation Core project ----
---- http://www.opencores.org/cores/mod_sim_exp/ ----
---- ----
---- Description ----
---- counter with synchronous count enable. It generates an ----
---- overflow when max_value is reached ----
---- ----
---- Dependencies: none ----
---- ----
---- Authors: ----
---- - Geoffrey Ottoy, DraMCo research group ----
---- - Jonas De Craene, JonasDC@opencores.org ----
---- ----
----------------------------------------------------------------------
---- ----
---- Copyright (C) 2011 DraMCo research group and OPENCORES.ORG ----
---- ----
---- This source file may be used and distributed without ----
---- restriction provided that this copyright statement is not ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer. ----
---- ----
---- This source file is free software; you can redistribute 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 source 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. ----
---- ----
---- You should have received a copy of the GNU Lesser General ----
---- Public License along with this source; if not, download it ----
---- from http://www.opencores.org/lgpl.shtml ----
---- ----
----------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
 
-- counter with synchronous count enable. It generates an
-- overflow when max_value is reached
entity counter_sync is
generic(
max_value : integer := 1024 -- maximum value (constraints the nr bits for counter)
);
port(
reset_value : in integer; -- value the counter counts to
core_clk : in std_logic; -- clock input
ce : in std_logic; -- count enable
reset : in std_logic; -- reset input
overflow : out std_logic -- gets high when counter reaches reset_value
);
end counter_sync;
 
 
architecture Behavioral of counter_sync is
begin
-- counter process with asynchronous active high reset
count_proc: process(core_clk, reset)
variable steps_counter : integer range 0 to max_value-1;
begin
if reset = '1' then -- reset counter
steps_counter := 0;
overflow <= '0';
elsif rising_edge(core_clk) then
-- counter is enabled, count till reset_value
if ce = '1' then
if steps_counter = (reset_value-1) then -- generate overflow and reset counter
steps_counter := 0;
overflow <= '1';
else -- just count
steps_counter := steps_counter + 1;
overflow <= '0';
end if;
else
--counter disabled, halt counter
overflow <= '0';
steps_counter := steps_counter;
end if;
end if;
end process;
end Behavioral;
/core/sys_last_cell_logic.vhd
0,0 → 1,94
----------------------------------------------------------------------
---- sys_last_cell_logic ----
---- ----
---- This file is part of the ----
---- Modular Simultaneous Exponentiation Core project ----
---- http://www.opencores.org/cores/mod_sim_exp/ ----
---- ----
---- Description ----
---- last cell logic for use int the montogommery mulitplier ----
---- pipelined systolic array ----
---- ----
---- Dependencies: ----
---- - register_n ----
---- - cell_1b_adder ----
---- ----
---- Authors: ----
---- - Geoffrey Ottoy, DraMCo research group ----
---- - Jonas De Craene, JonasDC@opencores.org ----
---- ----
----------------------------------------------------------------------
---- ----
---- Copyright (C) 2011 DraMCo research group and OPENCORES.ORG ----
---- ----
---- This source file may be used and distributed without ----
---- restriction provided that this copyright statement is not ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer. ----
---- ----
---- This source file is free software; you can redistribute 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 source 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. ----
---- ----
---- You should have received a copy of the GNU Lesser General ----
---- Public License along with this source; if not, download it ----
---- from http://www.opencores.org/lgpl.shtml ----
---- ----
----------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
library mod_sim_exp;
use mod_sim_exp.mod_sim_exp_pkg.all;
 
-- logic needed as the last piece in the systolic array pipeline
-- calculates the last 2 bits of the cell_result and finishes the reduction
-- also generates the result selection signal
entity sys_last_cell_logic is
port (
core_clk : in std_logic; -- clock input
reset : in std_logic;
a_0 : out std_logic; -- a_msb for last stage
cin : in std_logic; -- cout from last stage
red_cin : in std_logic; -- red_cout from last stage
r_sel : out std_logic; -- result selection bit
start : in std_logic -- done signal from last stage
);
end sys_last_cell_logic;
 
 
architecture Behavorial of sys_last_cell_logic is
signal cin_reg : std_logic;
begin
a_0 <= cin_reg;
last_reg : register_1b
port map(
core_clk => core_clk,
ce => start,
reset => reset,
din => cin,
dout => cin_reg
);
-- reduction, finishing last bit
reduction_adder : cell_1b_adder
port map(
a => '1', -- for 2s complement of m
b => cin_reg,
cin => red_cin,
cout => r_sel
);
 
end Behavorial;
/core/operand_ram.vhd
0,0 → 1,168
----------------------------------------------------------------------
---- operand_ram ----
---- ----
---- This file is part of the ----
---- Modular Simultaneous Exponentiation Core project ----
---- http://www.opencores.org/cores/mod_sim_exp/ ----
---- ----
---- Description ----
---- BRAM memory and logic to the store 4 (1536-bit) operands ----
---- for the montgomery multiplier ----
---- ----
---- Dependencies: ----
---- - operand_dp (coregen) ----
---- ----
---- Authors: ----
---- - Geoffrey Ottoy, DraMCo research group ----
---- - Jonas De Craene, JonasDC@opencores.org ----
---- ----
----------------------------------------------------------------------
---- ----
---- Copyright (C) 2011 DraMCo research group and OPENCORES.ORG ----
---- ----
---- This source file may be used and distributed without ----
---- restriction provided that this copyright statement is not ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer. ----
---- ----
---- This source file is free software; you can redistribute 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 source 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. ----
---- ----
---- You should have received a copy of the GNU Lesser General ----
---- Public License along with this source; if not, download it ----
---- from http://www.opencores.org/lgpl.shtml ----
---- ----
----------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
 
library mod_sim_exp;
use mod_sim_exp.mod_sim_exp_pkg.all;
 
 
entity operand_ram is
port( -- write_operand_ack voorzien?
-- global ports
clk : in std_logic;
collision : out std_logic;
-- bus side connections (32-bit serial)
operand_addr : in std_logic_vector(5 downto 0);
operand_in : in std_logic_vector(31 downto 0);
operand_in_sel : in std_logic_vector(1 downto 0);
result_out : out std_logic_vector(31 downto 0);
write_operand : in std_logic;
-- multiplier side connections (1536 bit parallel)
result_dest_op : in std_logic_vector(1 downto 0);
operand_out : out std_logic_vector(1535 downto 0);
operand_out_sel : in std_logic_vector(1 downto 0); -- controlled by bus side
write_result : in std_logic;
result_in : in std_logic_vector(1535 downto 0)
);
end operand_ram;
 
 
architecture Behavioral of operand_ram is
-- port a signals
signal addra : std_logic_vector(5 downto 0);
signal part_enable : std_logic_vector(3 downto 0);
signal wea : std_logic_vector(3 downto 0);
signal write_operand_i : std_logic;
 
-- port b signals
signal addrb : std_logic_vector(5 downto 0);
signal web : std_logic_vector(0 downto 0);
signal doutb0 : std_logic_vector(31 downto 0);
signal doutb1 : std_logic_vector(31 downto 0);
signal doutb2 : std_logic_vector(31 downto 0);
 
begin
 
-- WARNING: Very Important!
-- wea & web signals must never be high at the same time !!
-- web has priority
write_operand_i <= write_operand and not write_result;
web(0) <= write_result;
collision <= write_operand and write_result;
-- the dual port ram has a depth of 4 (each layer contains an operand)
-- result is always stored in position 3
-- doutb is always result
with write_operand_i select
addra <= operand_in_sel & operand_addr(3 downto 0) when '1',
operand_out_sel & "0000" when others;
with operand_addr(5 downto 4) select
part_enable <= "0001" when "00",
"0010" when "01",
"0100" when "10",
"1000" when others;
 
with write_operand_i select
wea <= part_enable when '1',
"0000" when others;
-- we can only read back from the result (stored in result_dest_op)
addrb <= result_dest_op & operand_addr(3 downto 0);
with operand_addr(5 downto 4) select
result_out <= doutb0 when "00",
doutb1 when "01",
doutb2 when others;
-- 3 instances of a dual port ram to store the parts of the operand
op_0 : operand_dp
port map (
clka => clk,
wea => wea(0 downto 0),
addra => addra,
dina => operand_in,
douta => operand_out(511 downto 0),
clkb => clk,
web => web,
addrb => addrb,
dinb => result_in(511 downto 0),
doutb => doutb0
);
 
op_1 : operand_dp
port map (
clka => clk,
wea => wea(1 downto 1),
addra => addra,
dina => operand_in,
douta => operand_out(1023 downto 512),
clkb => clk,
web => web,
addrb => addrb,
dinb => result_in(1023 downto 512),
doutb => doutb1
);
 
op_2 : operand_dp
port map (
clka => clk,
wea => wea(2 downto 2),
addra => addra,
dina => operand_in,
douta => operand_out(1535 downto 1024),
clkb => clk,
web => web,
addrb => addrb,
dinb => result_in(1535 downto 1024),
doutb => doutb2
);
 
end Behavioral;
/core/sys_pipeline.vhd
0,0 → 1,314
----------------------------------------------------------------------
---- sys_pipeline ----
---- ----
---- This file is part of the ----
---- Modular Simultaneous Exponentiation Core project ----
---- http://www.opencores.org/cores/mod_sim_exp/ ----
---- ----
---- Description ----
---- the pipelined systolic array for a montgommery multiplier ----
---- ----
---- Dependencies: ----
---- - sys_stage ----
---- - register_n ----
---- - d_flip_flop ----
---- - cell_1b_adder ----
---- - cell_1b_mux ----
---- ----
---- Authors: ----
---- - Geoffrey Ottoy, DraMCo research group ----
---- - Jonas De Craene, JonasDC@opencores.org ----
---- ----
----------------------------------------------------------------------
---- ----
---- Copyright (C) 2011 DraMCo research group and OPENCORES.ORG ----
---- ----
---- This source file may be used and distributed without ----
---- restriction provided that this copyright statement is not ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer. ----
---- ----
---- This source file is free software; you can redistribute 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 source 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. ----
---- ----
---- You should have received a copy of the GNU Lesser General ----
---- Public License along with this source; if not, download it ----
---- from http://www.opencores.org/lgpl.shtml ----
---- ----
----------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
library mod_sim_exp;
use mod_sim_exp.mod_sim_exp_pkg.all;
 
-- the pipelined systolic array for a montgommery multiplier
-- contains a structural description of the pipeline using the systolic stages
entity sys_pipeline is
generic(
n : integer := 1536; -- width of the operands (# bits)
t : integer := 192; -- total number of stages (minimum 2)
tl : integer := 64; -- lower number of stages (minimum 1)
split : boolean := true -- if true the pipeline wil be split in 2 parts,
-- if false there are no lower stages, only t counts
);
port(
-- clock input
core_clk : in std_logic;
-- modulus and y opperand input (n)-bit
y : in std_logic_vector((n-1) downto 0);
m : in std_logic_vector((n-1) downto 0);
-- x operand input (serial)
xi : in std_logic;
next_x : out std_logic; -- next x operand bit
-- control signals
start : in std_logic; -- start multiplier
reset : in std_logic;
p_sel : in std_logic_vector(1 downto 0); -- select which piece of the pipeline will be used
-- result out
r : out std_logic_vector((n-1) downto 0)
);
end sys_pipeline;
 
architecture Structural of sys_pipeline is
constant s : integer := n/t;
signal m_i : std_logic_vector(n downto 0);
signal y_i : std_logic_vector(n downto 0);
-- systolic stages signals
signal my_cin_stage : std_logic_vector((t-1) downto 0);
signal my_cout_stage : std_logic_vector((t-1) downto 0);
signal xin_stage : std_logic_vector((t-1) downto 0);
signal qin_stage : std_logic_vector((t-1) downto 0);
signal xout_stage : std_logic_vector((t-1) downto 0);
signal qout_stage : std_logic_vector((t-1) downto 0);
signal a_msb_stage : std_logic_vector((t-1) downto 0);
signal a_0_stage : std_logic_vector((t-1) downto 0);
signal cin_stage : std_logic_vector((t-1) downto 0);
signal cout_stage : std_logic_vector((t-1) downto 0);
signal red_cin_stage : std_logic_vector((t-1) downto 0);
signal red_cout_stage : std_logic_vector((t-1) downto 0);
signal start_stage : std_logic_vector((t-1) downto 0);
signal done_stage : std_logic_vector((t-1) downto 0);
signal r_sel_stage : std_logic_vector((t-1) downto 0);
-- end logic signals
signal r_sel_end : std_logic;
-- signals needed if pipeline is split
---------------------------------------
signal r_sel_l : std_logic;
signal r_sel_h : std_logic;
-- mid end logic signals
signal a_0_midend : std_logic;
signal r_sel_midend : std_logic;
-- mid start logic signals
signal my_cout_midstart : std_logic;
signal xout_midstart : std_logic;
signal qout_midstart : std_logic;
signal cout_midstart : std_logic;
signal red_cout_midstart : std_logic;
 
begin
 
m_i <= '0' & m;
y_i <= '0' & y;
 
-- generate the stages for the full pipeline
pipeline_stages : for i in 0 to (t-1) generate
stage : sys_stage
generic map(
width => s
)
port map(
core_clk => core_clk,
y => y_i((i+1)*s downto (i*s)+1),
m => m_i((i+1)*s downto (i*s)),
my_cin => my_cin_stage(i),
my_cout => my_cout_stage(i),
xin => xin_stage(i),
qin => qin_stage(i),
xout => xout_stage(i),
qout => qout_stage(i),
a_0 => a_0_stage(i),
a_msb => a_msb_stage(i),
cin => cin_stage(i),
cout => cout_stage(i),
red_cin => red_cin_stage(i),
red_cout => red_cout_stage(i),
start => start_stage(i),
reset => reset,
done => done_stage(i),
r_sel => r_sel_stage(i),
r => r(((i+1)*s)-1 downto (i*s))
);
end generate;
-- first cell logic
--------------------
first_cell : sys_first_cell_logic
port map (
m0 => m_i(0),
y0 => y_i(0),
my_cout => my_cin_stage(0),
xi => xi,
xout => xin_stage(0),
qout => qin_stage(0),
cout => cin_stage(0),
a_0 => a_0_stage(0),
red_cout => red_cin_stage(0)
);
-- last cell logic
-------------------
last_cell : sys_last_cell_logic
port map (
core_clk => core_clk,
reset => reset,
a_0 => a_msb_stage(t-1),
cin => cout_stage(t-1),
red_cin => red_cout_stage(t-1),
r_sel => r_sel_end,
start => done_stage(t-1)
);
------------------------------------
-- SINGLE PART PIPELINE CONNECTIONS
------------------------------------
single_pipeline : if split=false generate
-- link stages to eachother
stage_connect : for i in 1 to (t-1) generate
my_cin_stage(i) <= my_cout_stage(i-1);
cin_stage(i) <= cout_stage(i-1);
xin_stage(i) <= xout_stage(i-1);
qin_stage(i) <= qout_stage(i-1);
red_cin_stage(i) <= red_cout_stage(i-1);
start_stage(i) <= done_stage(i-1);
a_msb_stage(i-1) <= a_0_stage(i);
r_sel_stage(i) <= r_sel_end;
end generate;
r_sel_stage(0) <= r_sel_end;
start_stage(0) <= start;
next_x <= done_stage(0);
end generate;
 
----------------------------------------
-- SPLIT PIPELINE CONNECTIONS AND LOGIC
----------------------------------------
split_pipeline : if split=true generate
-- only start first stage if lower part is used
with p_sel select
start_stage(0) <= '0' when "10",
start when others;
-- select start or midstart stage for requesting new xi bit
with p_sel select
next_x <= done_stage(tl) when "10",
done_stage(0) when others;
-- link lower stages to eachother
stage_connect_l : for i in 1 to (tl-1) generate
my_cin_stage(i) <= my_cout_stage(i-1);
cin_stage(i) <= cout_stage(i-1);
xin_stage(i) <= xout_stage(i-1);
qin_stage(i) <= qout_stage(i-1);
red_cin_stage(i) <= red_cout_stage(i-1);
start_stage(i) <= done_stage(i-1);
a_msb_stage(i-1) <= a_0_stage(i);
r_sel_stage(i) <= r_sel_l;
end generate;
r_sel_stage(0) <= r_sel_l;
-- mid end logic
-----------------
mid_end_cell : sys_last_cell_logic
port map (
core_clk => core_clk,
reset => reset,
a_0 => a_0_midend,
cin => cout_stage(tl-1),
red_cin => red_cout_stage(tl-1),
r_sel => r_sel_midend,
start => done_stage(tl-1)
);
--muxes for midend signals
with p_sel select
a_msb_stage(tl-1) <= a_0_midend when "01",
a_0_stage(tl) when others;
-- mid start logic
-------------------
mid_start_logic : sys_first_cell_logic
port map (
m0 => m_i(tl*s),
y0 => y_i(tl*s),
my_cout => my_cout_midstart,
xi => xi,
xout => xout_midstart,
qout => qout_midstart,
cout => cout_midstart,
a_0 => a_0_stage(tl),
red_cout => red_cout_midstart
);
-- only start stage tl if only higher part is used
with p_sel select
start_stage(tl) <= start when "10",
done_stage(tl-1) when "11",
'0' when others;
with p_sel select
my_cin_stage(tl) <= my_cout_midstart when "10",
my_cout_stage(tl-1) when others;
with p_sel select
xin_stage(tl) <= xout_midstart when "10",
xout_stage(tl-1) when others;
with p_sel select
qin_stage(tl) <= qout_midstart when "10",
qout_stage(tl-1) when others;
with p_sel select
cin_stage(tl) <= cout_midstart when "10",
cout_stage(tl-1) when others;
with p_sel select
red_cin_stage(tl) <= red_cout_midstart when "10",
red_cout_stage(tl-1) when others;
-- link higher stages to eachother
stage_connect_h : for i in (tl+1) to (t-1) generate
my_cin_stage(i) <= my_cout_stage(i-1);
cin_stage(i) <= cout_stage(i-1);
xin_stage(i) <= xout_stage(i-1);
qin_stage(i) <= qout_stage(i-1);
red_cin_stage(i) <= red_cout_stage(i-1);
start_stage(i) <= done_stage(i-1);
a_msb_stage(i-1) <= a_0_stage(i);
r_sel_stage(i) <= r_sel_h;
end generate;
r_sel_stage(tl) <= r_sel_h;
with p_sel select
r_sel_l <= r_sel_midend when "01",
r_sel_end when "11",
'0' when others;
with p_sel select
r_sel_h <= '0' when "01",
r_sel_end when others;
end generate;
 
end Structural;
/core/mont_multiplier.vhd
0,0 → 1,204
----------------------------------------------------------------------
---- mont_multiplier ----
---- ----
---- This file is part of the ----
---- Modular Simultaneous Exponentiation Core project ----
---- http://www.opencores.org/cores/mod_sim_exp/ ----
---- ----
---- Description ----
---- n-bit montgomery multiplier with a pipelined systolic ----
---- array ----
---- ----
---- Dependencies: ----
---- - x_shift_reg ----
---- - adder_n ----
---- - d_flip_flop ----
---- - sys_pipeline ----
---- - cell_1b_adder ----
---- ----
---- Authors: ----
---- - Geoffrey Ottoy, DraMCo research group ----
---- - Jonas De Craene, JonasDC@opencores.org ----
---- ----
----------------------------------------------------------------------
---- ----
---- Copyright (C) 2011 DraMCo research group and OPENCORES.ORG ----
---- ----
---- This source file may be used and distributed without ----
---- restriction provided that this copyright statement is not ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer. ----
---- ----
---- This source file is free software; you can redistribute 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 source 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. ----
---- ----
---- You should have received a copy of the GNU Lesser General ----
---- Public License along with this source; if not, download it ----
---- from http://www.opencores.org/lgpl.shtml ----
---- ----
----------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
library mod_sim_exp;
use mod_sim_exp.mod_sim_exp_pkg.all;
 
-- Structural description of the montgommery multiply pipeline
-- contains the x operand shift register, my adder, the pipeline and
-- reduction adder. To do a multiplication, the following actions must take place:
--
-- * load in the x operand in the shift register using the xy bus and load_x
-- * place the y operand on the xy bus for the rest of the operation
-- * generate a start pulse of 1 clk cycle long on start
-- * wait for ready signal
-- * result is avaiable on the r bus
--
entity mont_multiplier is
generic (
n : integer := 1536; -- width of the operands
t : integer := 96; -- total number of stages (minimum 2)
tl : integer := 32; -- lower number of stages (minimum 1)
split : boolean := true -- if true the pipeline wil be split in 2 parts,
-- if false there are no lower stages, only t counts
);
port (
-- clock input
core_clk : in std_logic;
-- operand inputs
xy : in std_logic_vector((n-1) downto 0); -- bus for x or y operand
m : in std_logic_vector((n-1) downto 0); -- modulus
-- result output
r : out std_logic_vector((n-1) downto 0); -- result
-- control signals
start : in std_logic;
reset : in std_logic;
p_sel : in std_logic_vector(1 downto 0);
load_x : in std_logic;
ready : out std_logic
);
end mont_multiplier;
 
architecture Structural of mont_multiplier is
constant s : integer := n/t; -- stage width (# bits)
constant nl : integer := s*tl; -- lower pipeline width (# bits)
constant nh : integer := n - nl; -- higher pipeline width (# bits)
signal reset_multiplier : std_logic;
signal start_multiplier : std_logic;
signal p_sel_i : std_logic_vector(1 downto 0);
signal t_sel : integer range 0 to t; -- width in stages of selected pipeline part
signal n_sel : integer range 0 to n; -- width in bits of selected pipeline part
signal next_xi : std_logic;
signal xi : std_logic;
signal start_first_stage : std_logic;
begin
-- multiplier is reset every calculation or reset
reset_multiplier <= reset or start;
 
-- start is delayed 1 cycle
delay_1_cycle : d_flip_flop
port map(
core_clk => core_clk,
reset => reset,
din => start,
dout => start_multiplier
);
-- register to store the x value in
-- outputs the operand in serial using a shift register
x_selection : x_shift_reg
generic map(
n => n,
t => t,
tl => tl
)
port map(
clk => core_clk,
reset => reset,
x_in => xy,
load_x => load_x,
next_x => next_xi,
p_sel => p_sel_i,
xi => xi
);
----------------------------------------
-- SINGLE PIPELINE ASSIGNMENTS
----------------------------------------
single_pipeline : if split=false generate
p_sel_i <= "11";
t_sel <= t;
n_sel <= n-1;
end generate;
 
----------------------------------------
-- SPLIT PIPELINE ASSIGNMENTS
----------------------------------------
split_pipeline : if split=true generate
-- this module controls the pipeline operation
-- width in stages for selected pipeline
with p_sel select
t_sel <= tl when "01", -- lower pipeline part
t-tl when "10", -- higher pipeline part
t when others; -- full pipeline
 
-- width in bits for selected pipeline
with p_sel select
n_sel <= nl-1 when "01", -- lower pipeline part
nh-1 when "10", -- higher pipeline part
n-1 when others; -- full pipeline
p_sel_i <= p_sel;
end generate;
 
-- stepping control logic to keep track off the multiplication and when it is done
stepping_control : stepping_logic
generic map(
n => n, -- max nr of steps required to complete a multiplication
t => t -- total nr of steps in the pipeline
)
port map(
core_clk => core_clk,
start => start_multiplier,
reset => reset_multiplier,
t_sel => t_sel,
n_sel => n_sel,
start_first_stage => start_first_stage,
stepping_done => ready
);
systolic_array : sys_pipeline
generic map(
n => n,
t => t,
tl => tl,
split => split
)
port map(
core_clk => core_clk,
y => xy,
m => m,
xi => xi,
next_x => next_xi,
start => start_first_stage,
reset => reset_multiplier,
p_sel => p_sel_i,
r => r
);
end Structural;
/core/sys_first_cell_logic.vhd
0,0 → 1,97
----------------------------------------------------------------------
---- sys_first_cell_logic ----
---- ----
---- This file is part of the ----
---- Modular Simultaneous Exponentiation Core project ----
---- http://www.opencores.org/cores/mod_sim_exp/ ----
---- ----
---- Description ----
---- first cell logic for use int the montogommery mulitplier ----
---- pipelined systolic array ----
---- ----
---- Dependencies: ----
---- - register_n ----
---- - cell_1b_adder ----
---- ----
---- Authors: ----
---- - Geoffrey Ottoy, DraMCo research group ----
---- - Jonas De Craene, JonasDC@opencores.org ----
---- ----
----------------------------------------------------------------------
---- ----
---- Copyright (C) 2011 DraMCo research group and OPENCORES.ORG ----
---- ----
---- This source file may be used and distributed without ----
---- restriction provided that this copyright statement is not ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer. ----
---- ----
---- This source file is free software; you can redistribute 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 source 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. ----
---- ----
---- You should have received a copy of the GNU Lesser General ----
---- Public License along with this source; if not, download it ----
---- from http://www.opencores.org/lgpl.shtml ----
---- ----
----------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
library mod_sim_exp;
use mod_sim_exp.mod_sim_exp_pkg.all;
 
-- logic needed as the first piece in the systolic array pipeline
-- calculates the first my_cout and generates q signal
entity sys_first_cell_logic is
port (
m0 : in std_logic; -- lsb from m operand
y0 : in std_logic; -- lsb from y operand
my_cout : out std_logic; -- my_cin for first stage
xi : in std_logic; -- xi operand input
xout : out std_logic; -- xin for first stage
qout : out std_logic; -- qin for first stage
cout : out std_logic; -- cin for first stage
a_0 : in std_logic; -- a_0 from first stage
red_cout : out std_logic -- red_cin for first stage
);
end sys_first_cell_logic;
 
architecture Behavorial of sys_first_cell_logic is
-- first cell signals
signal my0_mux_result : std_logic;
signal my0 : std_logic;
signal qout_i : std_logic;
begin
-- half adder for m0 +y0
my0 <= m0 xor y0;
my_cout <= m0 and y0; -- carry
xout <= xi;
qout_i <= (xi and y0) xor a_0;
cout <= my0_mux_result and a_0;
red_cout <= '1'; -- add 1 for 2s complement
my0_mux : cell_1b_mux
port map(
my => my0,
m => m0,
y => y0,
x => xi,
q => qout_i,
result => my0_mux_result
);
qout <= qout_i;
end Behavorial;
/core/sys_stage.vhd
0,0 → 1,226
----------------------------------------------------------------------
---- sys_stage ----
---- ----
---- This file is part of the ----
---- Modular Simultaneous Exponentiation Core project ----
---- http://www.opencores.org/cores/mod_sim_exp/ ----
---- ----
---- Description ----
---- stage for use in the montgommery multiplier pipelined ----
---- systolic array ----
---- ----
---- Dependencies: ----
---- - adder_block ----
---- - standard_cell_block ----
---- - d_flip_flop ----
---- - register_n ----
---- - register_1b ----
---- ----
---- Authors: ----
---- - Geoffrey Ottoy, DraMCo research group ----
---- - Jonas De Craene, JonasDC@opencores.org ----
---- ----
----------------------------------------------------------------------
---- ----
---- Copyright (C) 2011 DraMCo research group and OPENCORES.ORG ----
---- ----
---- This source file may be used and distributed without ----
---- restriction provided that this copyright statement is not ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer. ----
---- ----
---- This source file is free software; you can redistribute 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 source 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. ----
---- ----
---- You should have received a copy of the GNU Lesser General ----
---- Public License along with this source; if not, download it ----
---- from http://www.opencores.org/lgpl.shtml ----
---- ----
----------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
library mod_sim_exp;
use mod_sim_exp.mod_sim_exp_pkg.all;
 
entity sys_stage is
generic(
width : integer := 32 -- width of the stage
);
port(
-- clock input
core_clk : in std_logic;
-- modulus and y operand input (width)-bit
y : in std_logic_vector((width-1) downto 0);
m : in std_logic_vector((width) downto 0);
my_cin : in std_logic;
my_cout : out std_logic;
-- q and x operand input (serial input)
xin : in std_logic;
qin : in std_logic;
-- q and x operand output (serial output)
xout : out std_logic;
qout : out std_logic;
-- msb input (lsb from next stage, for shift right operation)
a_msb : in std_logic;
a_0 : out std_logic;
-- carry out(clocked) and in
cin : in std_logic;
cout : out std_logic;
-- reduction adder carry's
red_cin : in std_logic;
red_cout : out std_logic;
-- control singals
start : in std_logic;
reset : in std_logic;
done : out std_logic;
-- result out
r_sel : in std_logic; -- result selection: 0 -> pipeline result, 1 -> reducted result
r : out std_logic_vector((width-1) downto 0)
);
end sys_stage;
 
architecture Structural of sys_stage is
signal my : std_logic_vector((width-1) downto 0);
signal m_inv : std_logic_vector((width-1) downto 0);
signal a : std_logic_vector((width-1) downto 0);
signal cell_result : std_logic_vector((width-1) downto 0);
signal cell_result_reg : std_logic_vector((width-1) downto 0);
signal red_r : std_logic_vector((width-1) downto 0);
signal cout_i : std_logic;
begin
-- my adder
------------
my_adder : adder_block
generic map (
width => width
)
port map(
core_clk => core_clk,
a => m(width downto 1),
b => y,
cin => my_cin,
cout => my_cout,
r => my
);
-- systolic pipeline cells
---------------------------
a <= a_msb & cell_result_reg((width-1) downto 1);
a_0 <= cell_result_reg(0);
sys_cells : standard_cell_block
generic map (
width => width
)
port map (
-- modulus and y operand input (width)-bit
my => my,
y => y,
m => m(width downto 1),
-- q and x operand input (serial input)
x => xin,
q => qin,
-- previous result in (width)-bit
a => a,
-- carry in and out
cin => cin,
cout => cout_i,
-- result out (width)-bit
r => cell_result
);
-- cell result register (width)-bit
result_reg : register_n
generic map(
width => width
)
port map(
core_clk => core_clk,
ce => start,
reset => reset,
din => cell_result,
dout => cell_result_reg
);
-- result reduction
--------------------
m_inv <= not(m(width-1 downto 0));
reduction_adder : adder_block
generic map (
width => width
)
port map(
core_clk => core_clk,
a => m_inv,
b => cell_result_reg,
cin => red_cin,
cout => red_cout,
r => red_r
);
with r_sel select
r <= cell_result_reg when '0',
red_r when others;
-- stage clocked outputs
-------------------------
-- stage done signal
-- 1 cycle after start of stage
done_signal : d_flip_flop
port map(
core_clk => core_clk,
reset => reset,
din => start,
dout => done
);
-- xout register
xout_reg : register_1b
port map(
core_clk => core_clk,
ce => start,
reset => reset,
din => xin,
dout => xout
);
-- qout register
qout_reg : register_1b
port map(
core_clk => core_clk,
ce => start,
reset => reset,
din => qin,
dout => qout
);
 
-- carry out register
cout_reg : register_1b
port map(
core_clk => core_clk,
ce => start,
reset => reset,
din => cout_i,
dout => cout
);
end Structural;
 
/core/x_shift_reg.vhd
0,0 → 1,100
----------------------------------------------------------------------
---- x_shift_reg ----
---- ----
---- This file is part of the ----
---- Modular Simultaneous Exponentiation Core project ----
---- http://www.opencores.org/cores/mod_sim_exp/ ----
---- ----
---- Description ----
---- n bit shift register for the x operand of the multiplier ----
---- with bit output ----
---- ----
---- Dependencies: none ----
---- ----
---- Authors: ----
---- - Geoffrey Ottoy, DraMCo research group ----
---- - Jonas De Craene, JonasDC@opencores.org ----
---- ----
----------------------------------------------------------------------
---- ----
---- Copyright (C) 2011 DraMCo research group and OPENCORES.ORG ----
---- ----
---- This source file may be used and distributed without ----
---- restriction provided that this copyright statement is not ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer. ----
---- ----
---- This source file is free software; you can redistribute 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 source 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. ----
---- ----
---- You should have received a copy of the GNU Lesser General ----
---- Public License along with this source; if not, download it ----
---- from http://www.opencores.org/lgpl.shtml ----
---- ----
----------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
 
-- shift register for the x operand of the multiplier
-- outputs the lsb of the register or bit at offset according to the
-- selected pipeline part
entity x_shift_reg is
generic(
n : integer := 1536; -- width of the operands (# bits)
t : integer := 48; -- total number of stages
tl : integer := 16 -- lower number of stages
);
port(
-- clock input
clk : in std_logic;
-- x operand in (n-bit)
x_in : in std_logic_vector((n-1) downto 0);
-- control signals
reset : in std_logic; -- reset, clears register
load_x : in std_logic; -- load operand into shift register
next_x : in std_logic; -- next bit of x
p_sel : in std_logic_vector(1 downto 0); -- pipeline selection
-- x operand bit out (serial)
xi : out std_logic
);
end x_shift_reg;
 
 
architecture Behavioral of x_shift_reg is
signal x_reg : std_logic_vector((n-1) downto 0); -- register
constant s : integer := n/t; -- stage width
constant offset : integer := s*tl; -- calculate startbit pos of higher part of pipeline
begin
 
REG_PROC: process(reset, clk)
begin
if reset = '1' then -- Reset, clear the register
x_reg <= (others => '0');
elsif rising_edge(clk) then
if load_x = '1' then -- Load_x, load the register with x_in
x_reg <= x_in;
elsif next_x = '1' then -- next_x, shift to right. LSbit gets lost and zero's are shifted in
x_reg((n-2) downto 0) <= x_reg((n-1) downto 1);
else -- else remember state
x_reg <= x_reg;
end if;
end if;
end process;
 
with p_sel select -- pipeline select
xi <= x_reg(offset) when "10", -- use bit at offset for high part of pipeline
x_reg(0) when others; -- use LS bit for lower part of pipeline
 
end Behavioral;
/core/stepping_logic.vhd
0,0 → 1,166
----------------------------------------------------------------------
---- stepping_logic ----
---- ----
---- This file is part of the ----
---- Modular Simultaneous Exponentiation Core project ----
---- http://www.opencores.org/cores/mod_sim_exp/ ----
---- ----
---- Description ----
---- stepping logic to control the pipeline for one ----
---- montgommery multiplication ----
---- ----
---- Dependencies: ----
---- - d_flip_flop ----
---- - counter_sync ----
---- ----
---- Authors: ----
---- - Geoffrey Ottoy, DraMCo research group ----
---- - Jonas De Craene, JonasDC@opencores.org ----
---- ----
----------------------------------------------------------------------
---- ----
---- Copyright (C) 2011 DraMCo research group and OPENCORES.ORG ----
---- ----
---- This source file may be used and distributed without ----
---- restriction provided that this copyright statement is not ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer. ----
---- ----
---- This source file is free software; you can redistribute 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 source 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. ----
---- ----
---- You should have received a copy of the GNU Lesser General ----
---- Public License along with this source; if not, download it ----
---- from http://www.opencores.org/lgpl.shtml ----
---- ----
----------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
 
library mod_sim_exp;
use mod_sim_exp.mod_sim_exp_pkg.all;
 
 
-- stepping logic for the pipeline, generates the start pulses for the
-- first stage and keeps track of when the last stages are done
entity stepping_logic is
generic(
n : integer := 1536; -- max nr of steps required to complete a multiplication
t : integer := 192 -- total nr of steps in the pipeline
);
port(
core_clk : in std_logic; -- clock input
start : in std_logic; -- start signal for pipeline (one multiplication)
reset : in std_logic; -- reset signal
t_sel : in integer range 0 to t; -- nr of stages in the pipeline piece
n_sel : in integer range 0 to n; -- nr of steps(bits in operands) required for a complete multiplication
start_first_stage : out std_logic; -- start pulse output for first stage
stepping_done : out std_logic -- done signal
);
end stepping_logic;
 
 
architecture Behavioral of stepping_logic is
 
-- signals for the first stage control, pulses and counters
signal first_stage_done : std_logic; -- indicates the first stage is done running for this multiplication
signal first_stage_active : std_logic; -- indicates the first stage is active
signal first_stage_active_d : std_logic; -- delayed version of first_stage_active
signal start_first_stage_i : std_logic; -- internal version of start_first_stage output
 
-- signals for the last stages control and counter
signal last_stages_done : std_logic; -- indicates the last stages are done running for this multiplication
signal last_stages_active : std_logic; -- indicates the last stages are active
signal last_stages_active_d : std_logic; -- delayed version of last_stages_active
 
begin
 
-- map outputs
stepping_done <= last_stages_done;
-- internal signals
--------------------
-- first_stage_active signal gets active from a start pulse
-- inactive from first_stage_done pulse
first_stage_active <= start or (first_stage_active_d and not first_stage_done);
-- done signal gets active from a first_stage_done pulse
-- inactive from last_stages_done pulse
last_stages_active <= first_stage_done or (last_stages_active_d and not last_stages_done);
-- map start_first_stage_i to output, but also use the initial start pulse
start_first_stage <= start or start_first_stage_i;
last_stages_active_delay : d_flip_flop
port map(
core_clk => core_clk,
reset => reset,
din => last_stages_active,
dout => last_stages_active_d
);
 
first_stage_active_delay : d_flip_flop
port map(
core_clk => core_clk,
reset => reset,
din => first_stage_active,
dout => first_stage_active_d
);
-- the counters
----------------
-- for counting the last steps (waiting for the other stages to stop)
-- counter for keeping track of how many stages are done
laststeps_counter : counter_sync
generic map(
max_value => t
)
port map(
reset_value => t_sel,
core_clk => core_clk,
ce => last_stages_active,
reset => reset,
overflow => last_stages_done
);
 
-- counter for keeping track of how many times the first stage is started
-- counts bits in operand x till operand width then generates pulse on first_stage_done
steps_counter : counter_sync
generic map(
max_value => n
)
port map(
reset_value => (n_sel),
core_clk => core_clk,
ce => start_first_stage_i,
reset => reset,
overflow => first_stage_done
);
 
-- the output (overflow) of this counter starts the first stage every 2 clock cycles
substeps_counter : counter_sync
generic map(
max_value => 2
)
port map(
reset_value => 2,
core_clk => core_clk,
ce => first_stage_active,
reset => reset,
overflow => start_first_stage_i
);
 
end Behavioral;
/core/standard_cell_block.vhd
0,0 → 1,105
----------------------------------------------------------------------
---- standard_cell_block ----
---- ----
---- This file is part of the ----
---- Modular Simultaneous Exponentiation Core project ----
---- http://www.opencores.org/cores/mod_sim_exp/ ----
---- ----
---- Description ----
---- a block of (width) cell_1b cells for use in the ----
---- montgommery multiplier systolic array ----
---- ----
---- Dependencies: ----
---- - cell_1b ----
---- ----
---- Authors: ----
---- - Geoffrey Ottoy, DraMCo research group ----
---- - Jonas De Craene, JonasDC@opencores.org ----
---- ----
----------------------------------------------------------------------
---- ----
---- Copyright (C) 2011 DraMCo research group and OPENCORES.ORG ----
---- ----
---- This source file may be used and distributed without ----
---- restriction provided that this copyright statement is not ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer. ----
---- ----
---- This source file is free software; you can redistribute 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 source 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. ----
---- ----
---- You should have received a copy of the GNU Lesser General ----
---- Public License along with this source; if not, download it ----
---- from http://www.opencores.org/lgpl.shtml ----
---- ----
----------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
 
library mod_sim_exp;
use mod_sim_exp.mod_sim_exp_pkg.all;
 
-- a standard cell block of (width)-bit for the montgommery multiplier
-- systolic array
entity standard_cell_block is
generic (
width : integer := 16
);
port (
-- modulus and y operand input (width)-bit
my : in std_logic_vector((width-1) downto 0);
y : in std_logic_vector((width-1) downto 0);
m : in std_logic_vector((width-1) downto 0);
-- q and x operand input (serial input)
x : in std_logic;
q : in std_logic;
-- previous result in (width)-bit
a : in std_logic_vector((width-1) downto 0);
-- carry in and out
cin : in std_logic;
cout : out std_logic;
-- result out (width)-bit
r : out std_logic_vector((width-1) downto 0)
);
end standard_cell_block;
 
 
architecture Structural of standard_cell_block is
-- vector for the carry bits
signal carry : std_logic_vector(width downto 0);
begin
-- carry in
carry(0) <= cin;
-- structure of (width) 1-bit cells
cell_block : for i in 0 to (width-1) generate
cells : cell_1b
port map(
my => my(i),
y => y(i),
m => m(i),
x => x,
q => q,
a => a(i),
cin => carry(i),
cout => carry(i+1),
r => r(i)
);
end generate;
-- carry out
cout <= carry(width);
end Structural;
/core/register_n.vhd
0,0 → 1,81
----------------------------------------------------------------------
---- register_n ----
---- ----
---- This file is part of the ----
---- Modular Simultaneous Exponentiation Core project ----
---- http://www.opencores.org/cores/mod_sim_exp/ ----
---- ----
---- Description ----
---- n bit register with active high asynchronious reset and ce----
---- used in montgommery multiplier systolic array stages ----
---- ----
---- Dependencies: none ----
---- ----
---- Authors: ----
---- - Geoffrey Ottoy, DraMCo research group ----
---- - Jonas De Craene, JonasDC@opencores.org ----
---- ----
----------------------------------------------------------------------
---- ----
---- Copyright (C) 2011 DraMCo research group and OPENCORES.ORG ----
---- ----
---- This source file may be used and distributed without ----
---- restriction provided that this copyright statement is not ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer. ----
---- ----
---- This source file is free software; you can redistribute 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 source 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. ----
---- ----
---- You should have received a copy of the GNU Lesser General ----
---- Public License along with this source; if not, download it ----
---- from http://www.opencores.org/lgpl.shtml ----
---- ----
----------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
 
-- n-bit register with asynchronous reset and clock enable
entity register_n is
generic(
width : integer := 4
);
port(
core_clk : in std_logic; -- clock input
ce : in std_logic; -- clock enable (active high)
reset : in std_logic; -- reset (active high)
din : in std_logic_vector((width-1) downto 0); -- data in (width)-bit
dout : out std_logic_vector((width-1) downto 0) -- data out (width)-bit
);
end register_n;
 
 
architecture Behavorial of register_n is
begin
-- process for (width)-bit register
reg_nb : process (reset, ce, core_clk, din)
begin
if reset='1' then -- asynchronous active high reset
dout <= (others=>'0');
else
if rising_edge(core_clk) then -- clock in data on rising edge
if ce='1' then -- active high clock enable to clock in data
dout <= din;
end if;
end if;
end if;
end process;
 
end Behavorial;
/core/cell_1b.vhd
0,0 → 1,102
----------------------------------------------------------------------
---- cell_1b ----
---- ----
---- This file is part of the ----
---- Modular Simultaneous Exponentiation Core project ----
---- http://www.opencores.org/cores/mod_sim_exp/ ----
---- ----
---- Description ----
---- 1-bit cell for use in the montgommery multiplier systolic ----
---- array ----
---- ----
---- Dependencies: ----
---- - cell_1bit_adder ----
---- - cell_1bit_mux ----
---- ----
---- Authors: ----
---- - Geoffrey Ottoy, DraMCo research group ----
---- - Jonas De Craene, JonasDC@opencores.org ----
---- ----
----------------------------------------------------------------------
---- ----
---- Copyright (C) 2011 DraMCo research group and OPENCORES.ORG ----
---- ----
---- This source file may be used and distributed without ----
---- restriction provided that this copyright statement is not ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer. ----
---- ----
---- This source file is free software; you can redistribute 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 source 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. ----
---- ----
---- You should have received a copy of the GNU Lesser General ----
---- Public License along with this source; if not, download it ----
---- from http://www.opencores.org/lgpl.shtml ----
---- ----
----------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
 
library mod_sim_exp;
use mod_sim_exp.mod_sim_exp_pkg.all;
 
-- 1-bit cell for the systolic array
entity cell_1b is
port (
-- operand input bits (m+y, y and m)
my : in std_logic;
y : in std_logic;
m : in std_logic;
-- operand x input bit and q
x : in std_logic;
q : in std_logic;
-- previous result input bit
a : in std_logic;
-- carry's
cin : in std_logic;
cout : out std_logic;
-- cell result out
r : out std_logic
);
end cell_1b;
 
 
architecture Structural of cell_1b is
-- mux to adder connection
signal mux2adder : std_logic;
begin
-- mux for my, y and m input bits
cell_mux : cell_1b_mux
port map(
my => my,
y => y,
m => m,
x => x,
q => q,
result => mux2adder
);
-- full adder for a+mux2adder
cell_adder : cell_1b_adder
port map(
a => a,
b => mux2adder,
cin => cin,
cout => cout,
r => r
);
 
end Structural;
/core/adder_block.vhd
0,0 → 1,106
----------------------------------------------------------------------
---- adder_block ----
---- ----
---- This file is part of the ----
---- Modular Simultaneous Exponentiation Core project ----
---- http://www.opencores.org/cores/mod_sim_exp/ ----
---- ----
---- Description ----
---- Adder block with a flipflop for the carry out so result ----
---- is available after 1 clock cycle ----
---- for use in the montgommery multiplier pre and post ----
---- computation adders ----
---- ----
---- Dependencies: ----
---- - cell_1b_adder ----
---- - d_flip_flop ----
---- ----
---- Authors: ----
---- - Geoffrey Ottoy, DraMCo research group ----
---- - Jonas De Craene, JonasDC@opencores.org ----
---- ----
----------------------------------------------------------------------
---- ----
---- Copyright (C) 2011 DraMCo research group and OPENCORES.ORG ----
---- ----
---- This source file may be used and distributed without ----
---- restriction provided that this copyright statement is not ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer. ----
---- ----
---- This source file is free software; you can redistribute 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 source 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. ----
---- ----
---- You should have received a copy of the GNU Lesser General ----
---- Public License along with this source; if not, download it ----
---- from http://www.opencores.org/lgpl.shtml ----
---- ----
----------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
 
library mod_sim_exp;
use mod_sim_exp.mod_sim_exp_pkg.all;
 
-- (width)-bit full adder block using cell_1b_adders
-- with buffered carry out -> result after 1 clock cycle
entity adder_block is
generic (
width : integer := 32 --adder operand widths
);
port (
-- clock input
core_clk : in std_logic;
-- adder input operands a, b (width)-bit
a : in std_logic_vector((width-1) downto 0);
b : in std_logic_vector((width-1) downto 0);
-- carry in, out
cin : in std_logic;
cout : out std_logic;
-- adder result out (width)-bit
r : out std_logic_vector((width-1) downto 0)
);
end adder_block;
 
 
architecture Structural of adder_block is
-- vector for the carry bits
signal carry : std_logic_vector(width downto 0);
begin
-- carry in
carry(0) <= cin;
 
-- structure of (width) cell_1b_adders
adder_chain : for i in 0 to (width-1) generate
adders : cell_1b_adder
port map(
a => a(i),
b => b(i),
cin => carry(i),
cout => carry(i+1),
r => r(i)
);
end generate;
-- buffer the carry every clock cycle
carry_reg : d_flip_flop
port map(
core_clk => core_clk,
reset => '0',
din => carry(width),
dout => cout
);
 
end Structural;
/core/cell_1b_adder.vhd
0,0 → 1,74
----------------------------------------------------------------------
---- cell_1b_adder ----
---- ----
---- This file is part of the ----
---- Modular Simultaneous Exponentiation Core project ----
---- http://www.opencores.org/cores/mod_sim_exp/ ----
---- ----
---- Description ----
---- This file contains the implementation of a 1-bit full ----
---- adder cell using combinatorial logic ----
---- used in adder_block ----
---- ----
---- Dependencies: none ----
---- ----
---- Authors: ----
---- - Geoffrey Ottoy, DraMCo research group ----
---- - Jonas De Craene, JonasDC@opencores.org ----
---- ----
----------------------------------------------------------------------
---- ----
---- Copyright (C) 2011 DraMCo research group and OPENCORES.ORG ----
---- ----
---- This source file may be used and distributed without ----
---- restriction provided that this copyright statement is not ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer. ----
---- ----
---- This source file is free software; you can redistribute 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 source 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. ----
---- ----
---- You should have received a copy of the GNU Lesser General ----
---- Public License along with this source; if not, download it ----
---- from http://www.opencores.org/lgpl.shtml ----
---- ----
----------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
 
-- 1-bit full adder cell
entity cell_1b_adder is
port (
-- input operands a, b
a : in std_logic;
b : in std_logic;
-- carry in, out
cin : in std_logic;
cout : out std_logic;
-- result out
r : out std_logic
);
end cell_1b_adder;
 
 
architecture Behavioral of cell_1b_adder is
signal a_xor_b : std_logic;
begin
-- 1-bit full adder with combinatorial logic
-- uses 2 XOR's, 2 AND's and 1 OR port
a_xor_b <= a xor b;
r <= a_xor_b xor cin;
cout <= (a and b) or (cin and a_xor_b);
end Behavioral;
/core/cell_1b_mux.vhd
0,0 → 1,78
----------------------------------------------------------------------
---- cel_1b_mux ----
---- ----
---- This file is part of the ----
---- Modular Simultaneous Exponentiation Core project ----
---- http://www.opencores.org/cores/mod_sim_exp/ ----
---- ----
---- Description ----
---- 1-bit mux for a standard cell in the montgommery ----
---- multiplier systolic array ----
---- ----
---- Dependencies: none ----
---- ----
---- Authors: ----
---- - Geoffrey Ottoy, DraMCo research group ----
---- - Jonas De Craene, JonasDC@opencores.org ----
---- ----
----------------------------------------------------------------------
---- ----
---- Copyright (C) 2011 DraMCo research group and OPENCORES.ORG ----
---- ----
---- This source file may be used and distributed without ----
---- restriction provided that this copyright statement is not ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer. ----
---- ----
---- This source file is free software; you can redistribute 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 source 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. ----
---- ----
---- You should have received a copy of the GNU Lesser General ----
---- Public License along with this source; if not, download it ----
---- from http://www.opencores.org/lgpl.shtml ----
---- ----
----------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
 
-- 1-bit mux for a standard cell in the montgommery multiplier systolic array
entity cell_1b_mux is
port (
-- input bits
my : in std_logic;
y : in std_logic;
m : in std_logic;
-- selection bits
x : in std_logic;
q : in std_logic;
-- mux out
result : out std_logic
);
end cell_1b_mux;
 
 
architecture Behavioral of cell_1b_mux is
signal sel : std_logic_vector(1 downto 0);
begin
-- selection bits
sel <= x & q;
-- multipexer
with sel select
result <= my when "11",
y when "10",
m when "01",
'0' when others;
 
end Behavioral;
/core/register_1b.vhd
0,0 → 1,79
----------------------------------------------------------------------
---- register_1b ----
---- ----
---- This file is part of the ----
---- Modular Simultaneous Exponentiation Core project ----
---- http://www.opencores.org/cores/mod_sim_exp/ ----
---- ----
---- Description ----
---- 1 bit register with active high asynchronious reset and ce----
---- used in montgommery multiplier systolic array stages ----
---- ----
---- Dependencies: none ----
---- ----
---- Authors: ----
---- - Geoffrey Ottoy, DraMCo research group ----
---- - Jonas De Craene, JonasDC@opencores.org ----
---- ----
----------------------------------------------------------------------
---- ----
---- Copyright (C) 2011 DraMCo research group and OPENCORES.ORG ----
---- ----
---- This source file may be used and distributed without ----
---- restriction provided that this copyright statement is not ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer. ----
---- ----
---- This source file is free software; you can redistribute 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 source 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. ----
---- ----
---- You should have received a copy of the GNU Lesser General ----
---- Public License along with this source; if not, download it ----
---- from http://www.opencores.org/lgpl.shtml ----
---- ----
----------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
 
-- 1-bit register with asynchronous reset and clock enable
entity register_1b is
port(
core_clk : in std_logic; -- clock input
ce : in std_logic; -- clock enable (active high)
reset : in std_logic; -- reset (active high)
din : in std_logic; -- data in
dout : out std_logic -- data out
);
end register_1b;
 
 
architecture Behavorial of register_1b is
begin
-- process for 1-bit register
reg_1b : process (reset, ce, core_clk, din)
begin
if reset='1' then -- asynchronous active high reset
dout <= '0';
else
if rising_edge(core_clk) then -- clock in data on rising edge
if ce='1' then -- active high clock enable to clock in data
dout <= din;
end if;
end if;
end if;
end process;
end Behavorial;
/core/d_flip_flop.vhd
0,0 → 1,76
----------------------------------------------------------------------
---- d_flip_flop ----
---- ----
---- This file is part of the ----
---- Modular Simultaneous Exponentiation Core project ----
---- http://www.opencores.org/cores/mod_sim_exp/ ----
---- ----
---- Description ----
---- 1-bit D flip-flop implemented with behavorial (generic) ----
---- description. With asynchronous active high reset. ----
---- ----
---- Dependencies: none ----
---- ----
---- Authors: ----
---- - Geoffrey Ottoy, DraMCo research group ----
---- - Jonas De Craene, JonasDC@opencores.org ----
---- ----
----------------------------------------------------------------------
---- ----
---- Copyright (C) 2011 DraMCo research group and OPENCORES.ORG ----
---- ----
---- This source file may be used and distributed without ----
---- restriction provided that this copyright statement is not ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer. ----
---- ----
---- This source file is free software; you can redistribute 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 source 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. ----
---- ----
---- You should have received a copy of the GNU Lesser General ----
---- Public License along with this source; if not, download it ----
---- from http://www.opencores.org/lgpl.shtml ----
---- ----
----------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
 
-- 1-bit D flip-flop with asynchronous active high reset
entity d_flip_flop is
port(
core_clk : in std_logic; -- clock signal
reset : in std_logic; -- active high reset
din : in std_logic; -- data in
dout : out std_logic -- data out
);
end d_flip_flop;
 
 
architecture Behavorial of d_flip_flop is
begin
-- process for 1-bit D flip-flop
d_FF : process (reset, core_clk, din)
begin
if reset='1' then -- asynchronous active high reset
dout <= '0';
else
if rising_edge(core_clk) then -- clock in data on rising edge
dout <= din;
end if;
end if;
end process;
end Behavorial;
/core/fifo_primitive.vhd
0,0 → 1,143
----------------------------------------------------------------------
---- fifo_primitive ----
---- ----
---- This file is part of the ----
---- Modular Simultaneous Exponentiation Core project ----
---- http://www.opencores.org/cores/mod_sim_exp/ ----
---- ----
---- Description ----
---- 512 x 32 bit fifo ----
---- ----
---- Dependencies: ----
---- - FIFO18E1 (xilinx primitive) ----
---- ----
---- Authors: ----
---- - Geoffrey Ottoy, DraMCo research group ----
---- - Jonas De Craene, JonasDC@opencores.org ----
---- ----
----------------------------------------------------------------------
---- ----
---- Copyright (C) 2011 DraMCo research group and OPENCORES.ORG ----
---- ----
---- This source file may be used and distributed without ----
---- restriction provided that this copyright statement is not ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer. ----
---- ----
---- This source file is free software; you can redistribute 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 source 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. ----
---- ----
---- You should have received a copy of the GNU Lesser General ----
---- Public License along with this source; if not, download it ----
---- from http://www.opencores.org/lgpl.shtml ----
---- ----
----------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
 
-- Xilinx primitives used in this code.
library UNISIM;
use UNISIM.VComponents.all;
 
 
entity fifo_primitive is
port (
clk : in std_logic;
din : in std_logic_vector (31 downto 0);
dout : out std_logic_vector (31 downto 0);
empty : out std_logic;
full : out std_logic;
push : in std_logic;
pop : in std_logic;
reset : in std_logic;
nopop : out std_logic;
nopush : out std_logic
);
end fifo_primitive;
 
 
architecture Behavioral of fifo_primitive is
signal rdcount : std_logic_vector(11 downto 0); -- debugging
signal wrcount : std_logic_vector(11 downto 0); -- debugging
signal reset_i, pop_i, push_i, empty_i, full_i, wrerr_i, rderr_i : std_logic;
begin
empty <= empty_i;
full <= full_i;
-- these logical equations need to be extended where necessary
nopop <= rderr_i or (pop and reset_i);
nopush <= wrerr_i or (push and reset_i);
pop_i <= pop and (not reset_i);
push_i <= push and (not reset_i);
-- makes the reset at least three clk_cycles long
RESET_PROC: process (reset, clk)
variable clk_counter : integer range 0 to 3 := 3;
begin
if reset = '1' then
reset_i <= '1';
clk_counter := 3;
elsif rising_edge(clk) then
if clk_counter = 0 then
clk_counter := 0;
reset_i <= '0';
else
clk_counter := clk_counter - 1;
reset_i <= '1';
end if;
end if;
end process;
 
FIFO18E1_inst : FIFO18E1
generic map (
ALMOST_EMPTY_OFFSET => X"00080", -- Sets the almost empty threshold
ALMOST_FULL_OFFSET => X"00080", -- Sets almost full threshold
DATA_WIDTH => 36, -- Sets data width to 4, 9, 18, or 36
DO_REG => 1, -- Enable output register (0 or 1) Must be 1 if EN_SYN = "FALSE"
EN_SYN => TRUE, -- Specifies FIFO as dual-clock ("FALSE") or Synchronous ("TRUE")
FIFO_MODE => "FIFO18_36", -- Sets mode to FIFO18 or FIFO18_36
FIRST_WORD_FALL_THROUGH => FALSE, -- Sets the FIFO FWFT to "TRUE" or "FALSE"
INIT => X"000000000", -- Initial values on output port
SRVAL => X"000000000" -- Set/Reset value for output port
)
port map (
-- ALMOSTEMPTY => ALMOSTEMPTY, -- 1-bit almost empty output flag
-- ALMOSTFULL => ALMOSTFULL, -- 1-bit almost full output flag
DO => dout, -- 32-bit data output
-- DOP => DOP, -- 4-bit parity data output
EMPTY => empty_i, -- 1-bit empty output flag
FULL => full_i, -- 1-bit full output flag
-- WRCOUNT, RDCOUNT: 12-bit (each) FIFO pointers
RDCOUNT => RDCOUNT, -- 12-bit read count output
WRCOUNT => WRCOUNT, -- 12-bit write count output
-- WRERR, RDERR: 1-bit (each) FIFO full or empty error
RDERR => rderr_i, -- 1-bit read error output
WRERR => wrerr_i, -- 1-bit write error
DI => din, -- 32-bit data input
DIP => "0000", -- 4-bit parity input
RDEN => pop_i, -- 1-bit read enable input
REGCE => '1', -- 1-bit clock enable input
RST => reset_i, -- 1-bit reset input
RSTREG => reset_i, -- 1-bit output register set/reset
-- WRCLK, RDCLK: 1-bit (each) Clocks
RDCLK => clk, -- 1-bit read clock input
WRCLK => clk, -- 1-bit write clock input
WREN => push_i -- 1-bit write enable input
);
 
end Behavioral;
/core/operand_dp.vhd
0,0 → 1,195
----------------------------------------------------------------------
---- operand_dp ----
---- ----
---- This file is part of the ----
---- Modular Simultaneous Exponentiation Core project ----
---- http://www.opencores.org/cores/mod_sim_exp/ ----
---- ----
---- Description ----
---- 4 x 512 bit dual port ram for the operands ----
---- 32 bit read and write for bus side and 512 bit read and ----
---- write for multiplier side ----
---- ----
---- Dependencies: none ----
---- ----
---- Authors: ----
---- - Geoffrey Ottoy, DraMCo research group ----
---- - Jonas De Craene, JonasDC@opencores.org ----
---- ----
----------------------------------------------------------------------
---- ----
---- Copyright (C) 2011 DraMCo research group and OPENCORES.ORG ----
---- ----
---- This source file may be used and distributed without ----
---- restriction provided that this copyright statement is not ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer. ----
---- ----
---- This source file is free software; you can redistribute 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 source 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. ----
---- ----
---- You should have received a copy of the GNU Lesser General ----
---- Public License along with this source; if not, download it ----
---- from http://www.opencores.org/lgpl.shtml ----
---- ----
----------------------------------------------------------------------
----------------------------------------------------------------------
-- This file is owned and controlled by Xilinx and must be used --
-- solely for design, simulation, implementation and creation of --
-- design files limited to Xilinx devices or technologies. Use --
-- with non-Xilinx devices or technologies is expressly prohibited --
-- and immediately terminates your license. --
-- --
-- XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" --
-- SOLELY FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR --
-- XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION --
-- AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION --
-- OR STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS --
-- IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT, --
-- AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE --
-- FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY --
-- WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE --
-- IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR --
-- REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF --
-- INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS --
-- FOR A PARTICULAR PURPOSE. --
-- --
-- Xilinx products are not intended for use in life support --
-- appliances, devices, or systems. Use in such applications are --
-- expressly prohibited. --
-- --
-- (c) Copyright 1995-2009 Xilinx, Inc. --
-- All rights reserved. --
----------------------------------------------------------------------
-- You must compile the wrapper file operand_dp.vhd when simulating
-- the core, operand_dp. When compiling the wrapper file, be sure to
-- reference the XilinxCoreLib VHDL simulation library. For detailed
-- instructions, please refer to the "CORE Generator Help".
 
-- The synthesis directives "translate_off/translate_on" specified
-- below are supported by Xilinx, Mentor Graphics and Synplicity
-- synthesis tools. Ensure they are correct for your synthesis tool(s).
 
 
library ieee;
use ieee.std_logic_1164.ALL;
-- synthesis translate_off
library XilinxCoreLib;
-- synthesis translate_on
 
 
entity operand_dp is
port (
clka : in std_logic;
wea : in std_logic_vector(0 downto 0);
addra : in std_logic_vector(5 downto 0);
dina : in std_logic_vector(31 downto 0);
douta : out std_logic_vector(511 downto 0);
clkb : in std_logic;
web : in std_logic_vector(0 downto 0);
addrb : in std_logic_vector(5 downto 0);
dinb : in std_logic_vector(511 downto 0);
doutb : out std_logic_vector(31 downto 0)
);
end operand_dp;
 
 
architecture operand_dp_a of operand_dp is
-- synthesis translate_off
component wrapped_operand_dp
port (
clka : in std_logic;
wea : in std_logic_vector(0 downto 0);
addra : in std_logic_vector(5 downto 0);
dina : in std_logic_vector(31 downto 0);
douta : out std_logic_vector(511 downto 0);
clkb : in std_logic;
web : in std_logic_vector(0 downto 0);
addrb : in std_logic_vector(5 downto 0);
dinb : in std_logic_vector(511 downto 0);
doutb : out std_logic_vector(31 downto 0)
);
end component;
 
-- Configuration specification
for all : wrapped_operand_dp use entity XilinxCoreLib.blk_mem_gen_v3_3(behavioral)
generic map(
c_has_regceb => 0,
c_has_regcea => 0,
c_mem_type => 2,
c_rstram_b => 0,
c_rstram_a => 0,
c_has_injecterr => 0,
c_rst_type => "SYNC",
c_prim_type => 1,
c_read_width_b => 32,
c_initb_val => "0",
c_family => "virtex6",
c_read_width_a => 512,
c_disable_warn_bhv_coll => 0,
c_write_mode_b => "WRITE_FIRST",
c_init_file_name => "no_coe_file_loaded",
c_write_mode_a => "WRITE_FIRST",
c_mux_pipeline_stages => 0,
c_has_mem_output_regs_b => 0,
c_has_mem_output_regs_a => 0,
c_load_init_file => 0,
c_xdevicefamily => "virtex6",
c_write_depth_b => 4,
c_write_depth_a => 64,
c_has_rstb => 0,
c_has_rsta => 0,
c_has_mux_output_regs_b => 0,
c_inita_val => "0",
c_has_mux_output_regs_a => 0,
c_addra_width => 6,
c_addrb_width => 6,
c_default_data => "0",
c_use_ecc => 0,
c_algorithm => 1,
c_disable_warn_bhv_range => 0,
c_write_width_b => 512,
c_write_width_a => 32,
c_read_depth_b => 64,
c_read_depth_a => 4,
c_byte_size => 9,
c_sim_collision_check => "ALL",
c_common_clk => 0,
c_wea_width => 1,
c_has_enb => 0,
c_web_width => 1,
c_has_ena => 0,
c_use_byte_web => 0,
c_use_byte_wea => 0,
c_rst_priority_b => "CE",
c_rst_priority_a => "CE",
c_use_default_data => 0
);
-- synthesis translate_on
begin
-- synthesis translate_off
U0 : wrapped_operand_dp
port map (
clka => clka,
wea => wea,
addra => addra,
dina => dina,
douta => douta,
clkb => clkb,
web => web,
addrb => addrb,
dinb => dinb,
doutb => doutb
);
-- synthesis translate_on
 
end operand_dp_a;
/core/operands_sp.vhd
0,0 → 1,180
----------------------------------------------------------------------
---- operands_sp ----
---- ----
---- This file is part of the ----
---- Modular Simultaneous Exponentiation Core project ----
---- http://www.opencores.org/cores/mod_sim_exp/ ----
---- ----
---- Description ----
---- 512 bit single port ram for the modulus ----
---- 32 write for bus side and 512 bit read for multplier side ----
---- ----
---- Dependencies: none ----
---- ----
---- Authors: ----
---- - Geoffrey Ottoy, DraMCo research group ----
---- - Jonas De Craene, JonasDC@opencores.org ----
---- ----
----------------------------------------------------------------------
---- ----
---- Copyright (C) 2011 DraMCo research group and OPENCORES.ORG ----
---- ----
---- This source file may be used and distributed without ----
---- restriction provided that this copyright statement is not ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer. ----
---- ----
---- This source file is free software; you can redistribute 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 source 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. ----
---- ----
---- You should have received a copy of the GNU Lesser General ----
---- Public License along with this source; if not, download it ----
---- from http://www.opencores.org/lgpl.shtml ----
---- ----
----------------------------------------------------------------------
----------------------------------------------------------------------
-- This file is owned and controlled by Xilinx and must be used --
-- solely for design, simulation, implementation and creation of --
-- design files limited to Xilinx devices or technologies. Use --
-- with non-Xilinx devices or technologies is expressly prohibited --
-- and immediately terminates your license. --
-- --
-- XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" --
-- SOLELY FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR --
-- XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION --
-- AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION --
-- OR STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS --
-- IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT, --
-- AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE --
-- FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY --
-- WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE --
-- IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR --
-- REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF --
-- INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS --
-- FOR A PARTICULAR PURPOSE. --
-- --
-- Xilinx products are not intended for use in life support --
-- appliances, devices, or systems. Use in such applications are --
-- expressly prohibited. --
-- --
-- (c) Copyright 1995-2009 Xilinx, Inc. --
-- All rights reserved. --
----------------------------------------------------------------------
-- You must compile the wrapper file operand_dp.vhd when simulating
-- the core, operand_dp. When compiling the wrapper file, be sure to
-- reference the XilinxCoreLib VHDL simulation library. For detailed
-- instructions, please refer to the "CORE Generator Help".
 
-- The synthesis directives "translate_off/translate_on" specified
-- below are supported by Xilinx, Mentor Graphics and Synplicity
-- synthesis tools. Ensure they are correct for your synthesis tool(s).
 
 
library ieee;
use ieee.std_logic_1164.all;
-- synthesis translate_off
library XilinxCoreLib;
-- synthesis translate_on
 
 
entity operands_sp is
port (
clka : in std_logic;
wea : in std_logic_vector(0 downto 0);
addra : in std_logic_vector(4 downto 0);
dina : in std_logic_vector(31 downto 0);
douta : out std_logic_vector(511 downto 0)
);
end operands_sp;
 
 
architecture operands_sp_a of operands_sp is
-- synthesis translate_off
component wrapped_operands_sp
port (
clka : in std_logic;
wea : in std_logic_vector(0 downto 0);
addra : in std_logic_vector(4 downto 0);
dina : in std_logic_vector(31 downto 0);
douta : out std_logic_vector(511 downto 0)
);
end component;
 
-- Configuration specification
for all : wrapped_operands_sp use entity XilinxCoreLib.blk_mem_gen_v3_3(behavioral)
generic map(
c_has_regceb => 0,
c_has_regcea => 0,
c_mem_type => 0,
c_rstram_b => 0,
c_rstram_a => 0,
c_has_injecterr => 0,
c_rst_type => "SYNC",
c_prim_type => 1,
c_read_width_b => 32,
c_initb_val => "0",
c_family => "virtex6",
c_read_width_a => 512,
c_disable_warn_bhv_coll => 0,
c_write_mode_b => "WRITE_FIRST",
c_init_file_name => "no_coe_file_loaded",
c_write_mode_a => "WRITE_FIRST",
c_mux_pipeline_stages => 0,
c_has_mem_output_regs_b => 0,
c_has_mem_output_regs_a => 0,
c_load_init_file => 0,
c_xdevicefamily => "virtex6",
c_write_depth_b => 32,
c_write_depth_a => 32,
c_has_rstb => 0,
c_has_rsta => 0,
c_has_mux_output_regs_b => 0,
c_inita_val => "0",
c_has_mux_output_regs_a => 0,
c_addra_width => 5,
c_addrb_width => 5,
c_default_data => "0",
c_use_ecc => 0,
c_algorithm => 1,
c_disable_warn_bhv_range => 0,
c_write_width_b => 32,
c_write_width_a => 32,
c_read_depth_b => 32,
c_read_depth_a => 2,
c_byte_size => 9,
c_sim_collision_check => "ALL",
c_common_clk => 0,
c_wea_width => 1,
c_has_enb => 0,
c_web_width => 1,
c_has_ena => 0,
c_use_byte_web => 0,
c_use_byte_wea => 0,
c_rst_priority_b => "CE",
c_rst_priority_a => "CE",
c_use_default_data => 0
);
-- synthesis translate_on
 
begin
-- synthesis translate_off
u0 : wrapped_operands_sp
port map (
clka => clka,
wea => wea,
addra => addra,
dina => dina,
douta => douta
);
-- synthesis translate_on
 
end operands_sp_a;
/core/modulus_ram.vhd
0,0 → 1,113
----------------------------------------------------------------------
---- modulus_ram ----
---- ----
---- This file is part of the ----
---- Modular Simultaneous Exponentiation Core project ----
---- http://www.opencores.org/cores/mod_sim_exp/ ----
---- ----
---- Description ----
---- BRAM memory and logic to store the 1536-bit modulus ----
---- ----
---- Dependencies: ----
---- - operands_sp (coregen) ----
---- ----
---- Authors: ----
---- - Geoffrey Ottoy, DraMCo research group ----
---- - Jonas De Craene, JonasDC@opencores.org ----
---- ----
----------------------------------------------------------------------
---- ----
---- Copyright (C) 2011 DraMCo research group and OPENCORES.ORG ----
---- ----
---- This source file may be used and distributed without ----
---- restriction provided that this copyright statement is not ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer. ----
---- ----
---- This source file is free software; you can redistribute 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 source 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. ----
---- ----
---- You should have received a copy of the GNU Lesser General ----
---- Public License along with this source; if not, download it ----
---- from http://www.opencores.org/lgpl.shtml ----
---- ----
----------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
 
library mod_sim_exp;
use mod_sim_exp.mod_sim_exp_pkg.all;
 
 
entity modulus_ram is
port(
clk : in std_logic;
modulus_addr : in std_logic_vector(5 downto 0);
write_modulus : in std_logic;
modulus_in : in std_logic_vector(31 downto 0);
modulus_out : out std_logic_vector(1535 downto 0)
);
end modulus_ram;
 
 
architecture Behavioral of modulus_ram is
signal part_enable : std_logic_vector(3 downto 0);
signal wea : std_logic_vector(3 downto 0);
signal addra : std_logic_vector(4 downto 0);
begin
 
-- the blockram has a write depth of 2 but we only use the lower half
addra <= '0' & modulus_addr(3 downto 0);
-- the two highest bits of the address are used to select the bloc
with modulus_addr(5 downto 4) select
part_enable <= "0001" when "00",
"0010" when "01",
"0100" when "10",
"1000" when others;
 
with write_modulus select
wea <= part_enable when '1',
"0000" when others;
-- 4 instances of 512 bits blockram
modulus_0 : operands_sp
port map (
clka => clk,
wea => wea(0 downto 0),
addra => addra,
dina => modulus_in,
douta => modulus_out(511 downto 0)
);
 
modulus_1 : operands_sp
port map (
clka => clk,
wea => wea(1 downto 1),
addra => addra,
dina => modulus_in,
douta => modulus_out(1023 downto 512)
);
 
modulus_2 : operands_sp
port map (
clka => clk,
wea => wea(2 downto 2),
addra => addra,
dina => modulus_in,
douta => modulus_out(1535 downto 1024)
);
 
end Behavioral;
/ram/tdpram_asym.vhd
0,0 → 1,175
----------------------------------------------------------------------
---- tdpram_asym ----
---- ----
---- This file is part of the ----
---- Modular Simultaneous Exponentiation Core project ----
---- http://www.opencores.org/cores/mod_sim_exp/ ----
---- ----
---- Description ----
---- behavorial description of an asymmetric true dual port ----
---- ram with one (widthA)-bit read/write port and one 32-bit ----
---- read/write port. Made using the templates of xilinx and ----
---- altera for asymmetric ram. ----
---- ----
---- Dependencies: none ----
---- ----
---- Authors: ----
---- - Geoffrey Ottoy, DraMCo research group ----
---- - Jonas De Craene, JonasDC@opencores.org ----
---- ----
----------------------------------------------------------------------
---- ----
---- Copyright (C) 2011 DraMCo research group and OPENCORES.ORG ----
---- ----
---- This source file may be used and distributed without ----
---- restriction provided that this copyright statement is not ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer. ----
---- ----
---- This source file is free software; you can redistribute 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 source 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. ----
---- ----
---- You should have received a copy of the GNU Lesser General ----
---- Public License along with this source; if not, download it ----
---- from http://www.opencores.org/lgpl.shtml ----
---- ----
----------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
 
library mod_sim_exp;
use mod_sim_exp.std_functions.all;
 
-- altera infers ramblocks from a depth of 9 (or 2 with any ram size recognition
-- option on or contstraint below on) and widthA 1,2,4,8,16
-- xilinx infers ramblocks from a depth of 2 and widthA 1,2,4,8,16,32
entity tdpram_asym is
generic (
depthB : integer := 4; -- nr of 32-bit words
widthA : integer := 2; -- port A width, must be smaller than or equal to 32
device : string := "xilinx"
);
port (
clk : in std_logic;
-- port A (widthA)-bit
addrA : in std_logic_vector(log2((depthB*32)/widthA)-1 downto 0);
weA : in std_logic;
dinA : in std_logic_vector(widthA-1 downto 0);
doutA : out std_logic_vector(widthA-1 downto 0);
-- port B 32-bit
addrB : in std_logic_vector(log2(depthB)-1 downto 0);
weB : in std_logic;
dinB : in std_logic_vector(31 downto 0);
doutB : out std_logic_vector(31 downto 0)
);
end tdpram_asym;
 
architecture behavorial of tdpram_asym is
-- constants
constant R : natural := 32/widthA; -- ratio
begin
 
xilinx_device : if device="xilinx" generate
-- An asymmetric RAM is modelled in a similar way as a symmetric RAM, with an
-- array of array object. Its aspect ratio corresponds to the port with the
-- lower data width (larger depth)
type ramType is array (0 to ((depthB*32)/widthA)-1) of std_logic_vector(widthA-1 downto 0);
-- You need to declare ram as a shared variable when :
-- - the RAM has two write ports,
-- - the RAM has only one write port whose data width is maxWIDTH
-- In all other cases, ram can be a signal.
shared variable ram : ramType := (others => (others => '0'));
signal clkA : std_logic;
signal clkB : std_logic;
begin
clkA <= clk;
process (clkA)
begin
if rising_edge(clkA) then
if weA = '1' then
ram(conv_integer(addrA)) := dinA;
end if;
doutA <= ram(conv_integer(addrA));
end if;
end process;
clkB <= clk;
process (clkB)
begin
if rising_edge(clkB) then
for i in 0 to R-1 loop
if weB = '1' then
ram(conv_integer(addrB & conv_std_logic_vector(i,log2(R))))
:= dinB((i+1)*widthA-1 downto i*widthA);
end if;
doutB((i+1)*widthA-1 downto i*widthA)
<= ram(conv_integer(addrB & conv_std_logic_vector(i,log2(R))));
end loop;
end if;
end process;
end generate;
altera_device : if device="altera" generate
-- Use a multidimensional array to model mixed-width
type word_t is array(R-1 downto 0) of std_logic_vector(widthA-1 downto 0);
type ram_t is array (0 to depthB-1) of word_t;
-- altera constraints:
-- for smal depths:
-- if the synthesis option "allow any size of RAM to be inferred" is on, these lines
-- may be left commented.
-- uncomment this attribute if that option is off and you know wich primitives should be used.
--attribute ramstyle : string;
--attribute ramstyle of RAM : signal is "M9K, no_rw_check";
-- delcare the RAM
signal ram : ram_t;
signal wB_local : word_t;
signal qB_local : word_t;
begin -- rtl
-- Re-organize the write data to match the RAM word type
unpack: for i in 0 to R-1 generate
wB_local(i) <= dinB(widthA*(i+1)-1 downto widthA*i);
doutB(widthA*(i+1)-1 downto widthA*i) <= qB_local(i);
end generate unpack;
--port B
process(clk)
begin
if(rising_edge(clk)) then
if(weB = '1') then
ram(conv_integer(addrB)) <= wB_local;
end if;
qB_local <= ram(conv_integer(addrB));
end if;
end process;
-- port A
process(clk)
begin
if(rising_edge(clk)) then
doutA <= ram(conv_integer(addrA) / R )(conv_integer(addrA) mod R);
if(weA ='1') then
ram(conv_integer(addrA) / R)(conv_integer(addrA) mod R) <= dinA;
end if;
end if;
end process;
end generate;
end behavorial;
 
/ram/dpramblock_asym.vhd
0,0 → 1,109
----------------------------------------------------------------------
---- dpramblock_asym ----
---- ----
---- This file is part of the ----
---- Modular Simultaneous Exponentiation Core project ----
---- http://www.opencores.org/cores/mod_sim_exp/ ----
---- ----
---- Description ----
---- structural description of an asymmetric dual port ram ----
---- with one 32-bit write port and one (width)-bit read ----
---- port. ----
---- ----
---- Dependencies: dpram_asym ----
---- ----
---- Authors: ----
---- - Geoffrey Ottoy, DraMCo research group ----
---- - Jonas De Craene, JonasDC@opencores.org ----
---- ----
----------------------------------------------------------------------
---- ----
---- Copyright (C) 2011 DraMCo research group and OPENCORES.ORG ----
---- ----
---- This source file may be used and distributed without ----
---- restriction provided that this copyright statement is not ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer. ----
---- ----
---- This source file is free software; you can redistribute 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 source 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. ----
---- ----
---- You should have received a copy of the GNU Lesser General ----
---- Public License along with this source; if not, download it ----
---- from http://www.opencores.org/lgpl.shtml ----
---- ----
----------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
 
library mod_sim_exp;
use mod_sim_exp.std_functions.all;
 
-- altera infers ramblocks from a depth of 9 (or 2 with any ram size recognition option on)
-- and width 64,128,256,512,1024
-- xilinx infers ramblocks from a depth of 2 and width 32,64,128,256,512,1024
entity dpramblock_asym is
generic (
width : integer := 256; -- read width
depth : integer := 2; -- nr of (width)-bit words
device : string := "xilinx"
);
port (
clk : in std_logic;
-- write port
waddr : in std_logic_vector(log2((width*depth)/32)-1 downto 0);
we : in std_logic;
din : in std_logic_vector(31 downto 0);
-- read port
raddr : in std_logic_vector(log2(depth)-1 downto 0);
dout : out std_logic_vector(width-1 downto 0)
);
end dpramblock_asym;
 
architecture structural of dpramblock_asym is
-- constants
constant nrRAMs : integer := width/32;
constant RAMwrwidth : integer := 32/nrRAMs;
-- interconnection signals
type word_array is array (nrRAMs-1 downto 0) of std_logic_vector(31 downto 0);
signal dout_RAM : word_array;
begin
-- generate (width/32) blocks of 32-bit ram with a given depth
-- these rams outputs are concatenated to a width-bit signal
ramblocks : for i in 0 to nrRAMs-1 generate
ramblock: entity mod_sim_exp.dpram_asym
generic map(
rddepth => depth,
wrwidth => RAMwrwidth,
device => device
)
port map(
clk => clk,
-- write port
waddr => waddr,
we => we,
din => din((i+1)*RAMwrwidth-1 downto RAMwrwidth*i),
-- read port
raddr => raddr,
dout => dout_RAM(i)
);
map_output : for j in 0 to nrRAMs-1 generate
dout(j*32+(i+1)*RAMwrwidth-1 downto j*32+i*RAMwrwidth)
<= dout_RAM(i)((j+1)*RAMwrwidth-1 downto j*RAMwrwidth);
end generate;
end generate;
end structural;
/ram/tdpramblock_asym.vhd
0,0 → 1,121
----------------------------------------------------------------------
---- tdpramblock_asym ----
---- ----
---- This file is part of the ----
---- Modular Simultaneous Exponentiation Core project ----
---- http://www.opencores.org/cores/mod_sim_exp/ ----
---- ----
---- Description ----
---- structural description of an asymmetric true dual port ----
---- ram with one 32-bit read/write port and one (width)-bit ----
---- read/write port. ----
---- ----
---- Dependencies: tdpram_asym ----
---- ----
---- Authors: ----
---- - Geoffrey Ottoy, DraMCo research group ----
---- - Jonas De Craene, JonasDC@opencores.org ----
---- ----
----------------------------------------------------------------------
---- ----
---- Copyright (C) 2011 DraMCo research group and OPENCORES.ORG ----
---- ----
---- This source file may be used and distributed without ----
---- restriction provided that this copyright statement is not ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer. ----
---- ----
---- This source file is free software; you can redistribute 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 source 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. ----
---- ----
---- You should have received a copy of the GNU Lesser General ----
---- Public License along with this source; if not, download it ----
---- from http://www.opencores.org/lgpl.shtml ----
---- ----
----------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
 
library mod_sim_exp;
use mod_sim_exp.std_functions.all;
 
-- altera infers ramblocks from a depth of 9 (or 2 with any ram size recognition option on)
-- and width 64,128,256,512
-- xilinx infers ramblocks from a depth of 2 and width 32,64,128,256,512
entity tdpramblock_asym is
generic (
depth : integer := 4; -- nr of (width)-bit words
width : integer := 512; -- width of portB
device : string := "xilinx"
);
port (
clk : in std_logic;
-- port A 32-bit
addrA : in std_logic_vector(log2((width*depth)/32)-1 downto 0);
weA : in std_logic;
dinA : in std_logic_vector(31 downto 0);
doutA : out std_logic_vector(31 downto 0);
-- port B (width)-bit
addrB : in std_logic_vector(log2(depth)-1 downto 0);
weB : in std_logic;
dinB : in std_logic_vector(width-1 downto 0);
doutB : out std_logic_vector(width-1 downto 0)
);
end tdpramblock_asym;
 
architecture structural of tdpramblock_asym is
-- constants
constant nrRAMs : integer := width/32;
constant RAMwidthA : integer := 32/nrRAMs;
 
-- interconnection signals
type word_array is array (nrRAMs-1 downto 0) of std_logic_vector(31 downto 0);
signal doutB_RAM : word_array;
signal dinB_RAM : word_array;
begin
 
ramblocks : for i in 0 to nrRAMs-1 generate
ramblock : entity mod_sim_exp.tdpram_asym
generic map(
widthA => RAMwidthA,
depthB => depth,
device => device
)
port map(
clk => clk,
-- port A (widthA)-bit
addrA => addrA,
weA => weA,
dinA => dinA((i+1)*RAMwidthA-1 downto RAMwidthA*i),
doutA => doutA((i+1)*RAMwidthA-1 downto RAMwidthA*i),
-- port B 32-bit
addrB => addrB,
weB => weB,
dinB => dinB_RAM(i),
doutB => doutB_RAM(i)
);
map_ioB : for j in 0 to nrRAMs-1 generate
-- output
doutB(j*32+(i+1)*RAMwidthA-1 downto j*32+i*RAMwidthA)
<= doutB_RAM(i)((j+1)*RAMwidthA-1 downto j*RAMwidthA);
-- input
dinB_RAM(i)((j+1)*RAMwidthA-1 downto j*RAMwidthA)
<= dinB(j*32+(i+1)*RAMwidthA-1 downto j*32+i*RAMwidthA);
end generate;
end generate;
end structural;
 
/ram/dpram_asym.vhd
0,0 → 1,135
----------------------------------------------------------------------
---- dpram_asym ----
---- ----
---- This file is part of the ----
---- Modular Simultaneous Exponentiation Core project ----
---- http://www.opencores.org/cores/mod_sim_exp/ ----
---- ----
---- Description ----
---- behavorial description of an asymmetric dual port ram ----
---- with one (wrwidth)-bit write port and one 32-bit read ----
---- port. Made using the templates of xilinx and altera for ----
---- asymmetric ram. ----
---- ----
---- Dependencies: none ----
---- ----
---- Authors: ----
---- - Geoffrey Ottoy, DraMCo research group ----
---- - Jonas De Craene, JonasDC@opencores.org ----
---- ----
----------------------------------------------------------------------
---- ----
---- Copyright (C) 2011 DraMCo research group and OPENCORES.ORG ----
---- ----
---- This source file may be used and distributed without ----
---- restriction provided that this copyright statement is not ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer. ----
---- ----
---- This source file is free software; you can redistribute 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 source 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. ----
---- ----
---- You should have received a copy of the GNU Lesser General ----
---- Public License along with this source; if not, download it ----
---- from http://www.opencores.org/lgpl.shtml ----
---- ----
----------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
 
library mod_sim_exp;
use mod_sim_exp.std_functions.all;
 
-- altera infers ramblocks from a depth of 9 (or 2 with any ram size recognition
-- option on or contstraint below on) and wrwidth 1,2,4,8,16
-- xilinx infers ramblocks from a depth of 2 and wrwidth 1,2,4,8,16,32
entity dpram_asym is
generic (
rddepth : integer := 4; -- nr of 32-bit words
wrwidth : integer := 2; -- write width, must be smaller than or equal to 32
device : string := "xilinx" -- device template to use
);
port (
clk : in std_logic;
-- write port
waddr : in std_logic_vector(log2((rddepth*32)/wrwidth)-1 downto 0);
we : in std_logic;
din : in std_logic_vector(wrwidth-1 downto 0);
-- read port
raddr : in std_logic_vector(log2(rddepth)-1 downto 0);
dout : out std_logic_vector(31 downto 0)
);
end dpram_asym;
 
architecture behavorial of dpram_asym is
-- constants
constant R : natural := 32/wrwidth; -- ratio
constant wrdepth : integer := (rddepth*32)/wrwidth;
begin
 
xilinx_device : if device="xilinx" generate
-- the memory
type ram_type is array (wrdepth-1 downto 0) of std_logic_vector (wrwidth-1 downto 0);
signal RAM : ram_type := (others => (others => '0'));
-- xilinx constraint to use blockram resources
attribute ram_style : string;
attribute ram_style of ram:signal is "block";
begin
process (clk)
begin
if (clk'event and clk = '1') then
if (we = '1') then
RAM(conv_integer(waddr)) <= din;
end if;
for i in 0 to R-1 loop
dout((i+1)*wrwidth-1 downto i*wrwidth)
<= RAM(conv_integer(raddr & conv_std_logic_vector(i,log2(R))));
end loop;
end if;
end process;
end generate;
altera_device : if device="altera" generate
-- Use a multidimensional array to model mixed-width
type word_t is array(R-1 downto 0) of std_logic_vector(wrwidth-1 downto 0);
type ram_t is array (0 to rddepth-1) of word_t;
signal ram : ram_t;
signal q_local : word_t;
-- altera constraints:
-- for smal depths:
-- if the synthesis option "allow any size of RAM to be inferred" is on, these lines
-- may be left commented.
-- uncomment this attribute if that option is off and you know wich primitives should be used.
--attribute ramstyle : string;
--attribute ramstyle of RAM : signal is "M9K, no_rw_check";
begin
unpack: for i in 0 to R - 1 generate
dout(wrwidth*(i+1) - 1 downto wrwidth*i) <= q_local(i);
end generate unpack;
process(clk, we)
begin
if(rising_edge(clk)) then
if(we = '1') then
ram(conv_integer(waddr)/R)(conv_integer(waddr) mod R) <= din;
end if;
q_local <= ram(conv_integer(raddr));
end if;
end process;
end generate;
end behavorial;
/ram/dpram_generic.vhd
0,0 → 1,96
----------------------------------------------------------------------
---- dpram_generic ----
---- ----
---- This file is part of the ----
---- Modular Simultaneous Exponentiation Core project ----
---- http://www.opencores.org/cores/mod_sim_exp/ ----
---- ----
---- Description ----
---- behavorial description of a dual port ram with one 32-bit ----
---- write port and one 32-bit read port ----
---- ----
---- Dependencies: none ----
---- ----
---- Authors: ----
---- - Geoffrey Ottoy, DraMCo research group ----
---- - Jonas De Craene, JonasDC@opencores.org ----
---- ----
----------------------------------------------------------------------
---- ----
---- Copyright (C) 2011 DraMCo research group and OPENCORES.ORG ----
---- ----
---- This source file may be used and distributed without ----
---- restriction provided that this copyright statement is not ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer. ----
---- ----
---- This source file is free software; you can redistribute 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 source 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. ----
---- ----
---- You should have received a copy of the GNU Lesser General ----
---- Public License along with this source; if not, download it ----
---- from http://www.opencores.org/lgpl.shtml ----
---- ----
----------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
library mod_sim_exp;
use mod_sim_exp.std_functions.all;
 
-- altera infers ramblocks from a depth of 9
-- xilinx infers ramblocks from a depth of 2
entity dpram_generic is
generic (
depth : integer := 2
);
port (
clk : in std_logic;
-- write port
waddr : in std_logic_vector(log2(depth)-1 downto 0);
we : in std_logic;
din : in std_logic_vector(31 downto 0);
-- read port
raddr : in std_logic_vector(log2(depth)-1 downto 0);
dout : out std_logic_vector(31 downto 0)
);
end dpram_generic;
 
architecture behavorial of dpram_generic is
-- the memory
type ram_type is array (depth-1 downto 0) of std_logic_vector (31 downto 0);
signal RAM : ram_type := (others => (others => '0'));
-- xilinx constraint to use blockram resources
attribute ram_style : string;
attribute ram_style of ram:signal is "block";
-- altera constraints:
-- for smal depths:
-- if the synthesis option "allow any size of RAM to be inferred" is on, these lines
-- may be left commented.
-- uncomment this attribute if that option is off and you know wich primitives should be used.
--attribute ramstyle : string;
--attribute ramstyle of RAM : signal is "M9K, no_rw_check";
begin
process (clk)
begin
if (clk'event and clk = '1') then
if (we = '1') then
RAM(conv_integer(waddr)) <= din;
end if;
dout <= RAM(conv_integer(raddr));
end if;
end process;
end behavorial;
 
/ram/tdpram_generic.vhd
0,0 → 1,112
----------------------------------------------------------------------
---- tdpram_generic ----
---- ----
---- This file is part of the ----
---- Modular Simultaneous Exponentiation Core project ----
---- http://www.opencores.org/cores/mod_sim_exp/ ----
---- ----
---- Description ----
---- behavorial description of a true dual port ram with 2 ----
---- 32-bit write/read ports ----
---- ----
---- Dependencies: none ----
---- ----
---- Authors: ----
---- - Geoffrey Ottoy, DraMCo research group ----
---- - Jonas De Craene, JonasDC@opencores.org ----
---- ----
----------------------------------------------------------------------
---- ----
---- Copyright (C) 2011 DraMCo research group and OPENCORES.ORG ----
---- ----
---- This source file may be used and distributed without ----
---- restriction provided that this copyright statement is not ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer. ----
---- ----
---- This source file is free software; you can redistribute 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 source 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. ----
---- ----
---- You should have received a copy of the GNU Lesser General ----
---- Public License along with this source; if not, download it ----
---- from http://www.opencores.org/lgpl.shtml ----
---- ----
----------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
library mod_sim_exp;
use mod_sim_exp.std_functions.all;
 
-- altera infers ramblocks from a depth of 9
-- xilinx infers ramblocks from a depth of 2
entity tdpram_generic is
generic (
depth : integer := 9
);
port (
-- port A
clkA : in std_logic;
addrA : in std_logic_vector(log2(depth)-1 downto 0);
weA : in std_logic;
dinA : in std_logic_vector(31 downto 0);
doutA : out std_logic_vector(31 downto 0);
-- port B
clkB : in std_logic;
addrB : in std_logic_vector(log2(depth)-1 downto 0);
weB : in std_logic;
dinB : in std_logic_vector(31 downto 0);
doutB : out std_logic_vector(31 downto 0)
);
end tdpram_generic;
 
architecture behavorial of tdpram_generic is
-- the memory
type ram_type is array (depth-1 downto 0) of std_logic_vector (31 downto 0);
shared variable RAM: ram_type := (others => (others => '0'));
-- xilinx constraint to use blockram resources
attribute ram_style : string;
attribute ram_style of RAM:variable is "block";
-- altera constraints:
-- for smal depths:
-- if the synthesis option "allow any size of RAM to be inferred" is on, these lines
-- may be left commented.
-- uncomment this attribute if that option is off and you know wich primitives should be used.
--attribute ramstyle : string;
--attribute ramstyle of RAM : signal is "M9K, no_rw_check";
begin
-- port A
process (clkA)
begin
if (clkA'event and clkA = '1') then
if ( weA = '1') then
RAM(conv_integer(addrA)) := dinA ;
end if;
doutA <= RAM(conv_integer(addrA));
end if;
end process;
-- port B
process (clkB)
begin
if (clkB'event and clkB = '1') then
if ( weB = '1') then
RAM(conv_integer(addrB)) := dinB ;
end if;
doutB <= RAM(conv_integer(addrB));
end if;
end process;
end behavorial;
 

powered by: WebSVN 2.1.0

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