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; |
|