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
- from Rev 47 to Rev 48
- ↔ Reverse comparison
Rev 47 → Rev 48
/tags/start_version/bench/vhdl/tb_multiplier_core.vhd
0,0 → 1,672
-------------------------------------------------------------------------------- |
-- Entity: tb_multiplier_core |
-- Date:2012-10-02 |
-- Author: Dinghe |
-- |
-- Description ${cursor} |
-------------------------------------------------------------------------------- |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_unsigned.all; |
use ieee.std_logic_arith.all; |
|
library std; |
use std.textio.all; |
|
library ieee; |
use ieee.std_logic_textio.all; |
|
entity tb_multiplier_core is |
end tb_multiplier_core; |
|
architecture test of tb_multiplier_core is |
constant nr_stages : integer := 96; |
constant clk_period : time := 10 ns; |
signal clk : std_logic := '0'; |
signal reset : std_logic := '1'; |
file input : text open read_mode is "sim_input.txt"; |
file output : text open write_mode is "sim_output.txt"; |
|
------------------------------------------------------------------ |
-- Signals for multiplier core memory space |
------------------------------------------------------------------ |
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 core_data_out : std_logic_vector(31 downto 0); |
signal core_write_enable : std_logic; |
signal core_fifo_push : std_logic; |
------------------------------------------------------------------ |
-- Signals for multiplier core control |
------------------------------------------------------------------ |
signal core_start : std_logic; |
signal core_run_auto : 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 calc_time : std_logic; |
------------------------------------------------------------------ |
-- Signals for multiplier core interrupt |
------------------------------------------------------------------ |
signal core_fifo_full : std_logic; |
signal core_fifo_nopush : std_logic; |
signal core_ready : std_logic; |
signal core_mem_collision : std_logic; |
|
component multiplier_core is |
port( |
clk : in std_logic; |
reset : in std_logic; |
-- operand memory interface (plb shared memory) |
write_enable : in std_logic; |
data_in : in std_logic_vector (31 downto 0); |
rw_address : in std_logic_vector (8 downto 0); |
data_out : out std_logic_vector (31 downto 0); |
collision : out std_logic; |
-- op_sel fifo interface |
fifo_din : in std_logic_vector (31 downto 0); |
fifo_push : in std_logic; |
fifo_full : out std_logic; |
fifo_nopush : out std_logic; |
-- ctrl signals |
start : in std_logic; |
run_auto : in std_logic; |
ready : out std_logic; |
x_sel_single : in std_logic_vector (1 downto 0); |
y_sel_single : in std_logic_vector (1 downto 0); |
dest_op_single : in std_logic_vector (1 downto 0); |
p_sel : in std_logic_vector (1 downto 0); |
calc_time : out std_logic |
); |
end component; |
|
|
begin |
|
------------------------------------------ |
-- Generate clk |
------------------------------------------ |
clk_process : process |
begin |
while (true) loop |
clk <= '0'; |
wait for clk_period/2; |
clk <= '1'; |
wait for clk_period/2; |
end loop; |
end process; |
|
------------------------------------------ |
-- Stimulus Process |
------------------------------------------ |
stim_proc : process |
procedure waitclk(n : natural := 1) is |
begin |
for i in 1 to n loop |
wait until rising_edge(clk); |
end loop; |
end waitclk; |
|
procedure loadOp(constant op_sel : std_logic_vector(2 downto 0); |
variable op_data : std_logic_vector(2047 downto 0)) is |
begin |
wait until rising_edge(clk); |
core_rw_address <= op_sel & "000000"; |
wait until rising_edge(clk); |
core_write_enable <= '1'; |
for i in 0 to (1536/32)-1 loop |
assert (core_mem_collision='0') |
report "collision detected while writing operand!!" severity failure; |
case (core_p_sel) is |
when "11" => |
core_data_in <= op_data(((i+1)*32)-1 downto (i*32)); |
when "01" => |
if (i < 16) then core_data_in <= op_data(((i+1)*32)-1 downto (i*32)); |
else core_data_in <= x"00000000"; end if; |
when "10" => |
if (i >= 16) then core_data_in <= op_data(((i-15)*32)-1 downto ((i-16)*32)); |
else core_data_in <= x"00000000"; end if; |
when others => |
core_data_in <= x"00000000"; |
end case; |
|
wait until rising_edge(clk); |
core_rw_address <= core_rw_address+"000000001"; |
end loop; |
core_write_enable <= '0'; |
wait until rising_edge(clk); |
end loadOp; |
|
|
procedure readOp(constant op_sel : std_logic_vector(2 downto 0); |
variable op_data : out std_logic_vector(2047 downto 0); |
variable op_width : integer) is |
begin |
wait until rising_edge(clk); |
core_dest_op_single <= op_sel(1 downto 0); |
if (core_p_sel = "10") then |
core_rw_address <= op_sel & "010000"; |
else |
core_rw_address <= op_sel & "000000"; |
end if; |
waitclk(2); |
|
for i in 0 to (op_width/32)-2 loop |
op_data(((i+1)*32)-1 downto (i*32)) := core_data_out; |
core_rw_address <= core_rw_address+"000000001"; |
waitclk(2); |
end loop; |
op_data(op_width-1 downto op_width-32) := core_data_out; |
wait until rising_edge(clk); |
end readOp; |
|
function ToString(constant Timeval : time) return string is |
variable StrPtr : line; |
begin |
write(StrPtr,Timeval); |
return StrPtr.all; |
end ToString; |
|
-- variables to read file |
variable L : line; |
variable Lw : line; |
variable base_width : integer; |
variable exponent_width : integer; |
variable g0 : std_logic_vector(2047 downto 0) := (others=>'0'); |
variable g1 : std_logic_vector(2047 downto 0) := (others=>'0'); |
variable e0 : std_logic_vector(2047 downto 0) := (others=>'0'); |
variable e1 : std_logic_vector(2047 downto 0) := (others=>'0'); |
variable m : std_logic_vector(2047 downto 0) := (others=>'0'); |
variable R2 : std_logic_vector(2047 downto 0) := (others=>'0'); |
variable R : std_logic_vector(2047 downto 0) := (others=>'0'); |
variable gt0 : std_logic_vector(2047 downto 0) := (others=>'0'); |
variable gt1 : std_logic_vector(2047 downto 0) := (others=>'0'); |
variable gt01 : std_logic_vector(2047 downto 0) := (others=>'0'); |
variable one : std_logic_vector(2047 downto 0) := std_logic_vector(conv_unsigned(1, 2048)); |
variable result : std_logic_vector(2047 downto 0) := (others=>'0'); |
variable data_read : std_logic_vector(2047 downto 0) := (others=>'0'); |
variable good_value : boolean; |
variable param_count : integer := 0; |
|
-- constants for operand selection |
constant op_modulus : std_logic_vector(2 downto 0) := "100"; |
constant op_0 : std_logic_vector(2 downto 0) := "000"; |
constant op_1 : std_logic_vector(2 downto 0) := "001"; |
constant op_2 : std_logic_vector(2 downto 0) := "010"; |
constant op_3 : std_logic_vector(2 downto 0) := "011"; |
|
variable timer : time; |
begin |
-- initialisation |
-- memory |
core_write_enable <= '0'; |
core_data_in <= x"00000000"; |
core_rw_address <= "000000000"; |
-- fifo |
core_fifo_din <= x"00000000"; |
core_fifo_push <= '0'; |
-- control |
core_start <= '0'; |
core_run_auto <= '0'; |
core_x_sel_single <= "00"; |
core_y_sel_single <= "01"; |
core_dest_op_single <= "01"; |
core_p_sel <= "11"; |
|
-- Generate active high reset signal |
reset <= '1'; |
waitclk(100); |
reset <= '0'; |
waitclk(100); |
|
while not endfile(input) loop |
readline(input, L); -- read next line |
next when L(1)='-'; -- skip comment lines |
-- read input values |
case param_count is |
when 0 => -- base width |
read(L, base_width, good_value); |
assert good_value report "Can not read base width" severity failure; |
assert false report "Simulating exponentiation" severity note; |
write(Lw, string'("----------------------------------------------")); |
writeline(output, Lw); |
write(Lw, string'("-- EXPONENTIATION --")); |
writeline(output, Lw); |
write(Lw, string'("----------------------------------------------")); |
writeline(output, Lw); |
write(Lw, string'("----- Variables used:")); |
writeline(output, Lw); |
write(Lw, string'("base width: ")); |
write(Lw, base_width); |
writeline(output, Lw); |
case (base_width) is |
when 1536 => when 1024 => when 512 => |
when others => |
write(Lw, string'("=> incompatible base width!!!")); writeline(output, Lw); |
assert false report "incompatible base width!!!" severity failure; |
end case; |
|
when 1 => -- exponent width |
read(L, exponent_width, good_value); |
assert good_value report "Can not read exponent width" severity failure; |
write(Lw, string'("exponent width: ")); |
write(Lw, exponent_width); |
writeline(output, Lw); |
|
when 2 => -- g0 |
hread(L, g0(base_width-1 downto 0), good_value); |
assert good_value report "Can not read g0! (wrong lenght?)" severity failure; |
write(Lw, string'("g0: ")); |
hwrite(Lw, g0(base_width-1 downto 0)); |
writeline(output, Lw); |
|
when 3 => -- g1 |
hread(L, g1(base_width-1 downto 0), good_value); |
assert good_value report "Can not read g1! (wrong lenght?)" severity failure; |
write(Lw, string'("g1: ")); |
hwrite(Lw, g1(base_width-1 downto 0)); |
writeline(output, Lw); |
|
when 4 => -- e0 |
hread(L, e0(exponent_width-1 downto 0), good_value); |
assert good_value report "Can not read e0! (wrong lenght?)" severity failure; |
write(Lw, string'("e0: ")); |
hwrite(Lw, e0(exponent_width-1 downto 0)); |
writeline(output, Lw); |
|
when 5 => -- e1 |
hread(L, e1(exponent_width-1 downto 0), good_value); |
assert good_value report "Can not read e1! (wrong lenght?)" severity failure; |
write(Lw, string'("e1: ")); |
hwrite(Lw, e1(exponent_width-1 downto 0)); |
writeline(output, Lw); |
|
when 6 => -- m |
hread(L, m(base_width-1 downto 0), good_value); |
assert good_value report "Can not read m! (wrong lenght?)" severity failure; |
write(Lw, string'("m: ")); |
hwrite(Lw, m(base_width-1 downto 0)); |
writeline(output, Lw); |
|
when 7 => -- R^2 |
hread(L, R2(base_width-1 downto 0), good_value); |
assert good_value report "Can not read R2! (wrong lenght?)" severity failure; |
write(Lw, string'("R2: ")); |
hwrite(Lw, R2(base_width-1 downto 0)); |
writeline(output, Lw); |
|
when 8 => -- R |
hread(L, R(base_width-1 downto 0), good_value); |
assert good_value report "Can not read R! (wrong lenght?)" severity failure; |
|
when 9 => -- gt0 |
hread(L, gt0(base_width-1 downto 0), good_value); |
assert good_value report "Can not read gt0! (wrong lenght?)" severity failure; |
|
when 10 => -- gt1 |
hread(L, gt1(base_width-1 downto 0), good_value); |
assert good_value report "Can not read gt1! (wrong lenght?)" severity failure; |
|
when 11 => -- gt01 |
hread(L, gt01(base_width-1 downto 0), good_value); |
assert good_value report "Can not read gt01! (wrong lenght?)" severity failure; |
|
-- select pipeline for all computations |
---------------------------------------- |
writeline(output, Lw); |
write(Lw, string'("----- Selecting pipeline: ")); |
writeline(output, Lw); |
case (base_width) is |
when 1536 => core_p_sel <= "11"; write(Lw, string'(" Full pipeline selected")); |
when 1024 => core_p_sel <= "10"; write(Lw, string'(" Upper pipeline selected")); |
when 512 => core_p_sel <= "01"; write(Lw, string'(" Lower pipeline selected")); |
when others => |
write(Lw, string'(" Invallid bitwidth for design")); |
assert false report "impossible basewidth!" severity failure; |
end case; |
writeline(output, Lw); |
|
writeline(output, Lw); |
write(Lw, string'("----- Writing operands:")); |
writeline(output, Lw); |
|
-- load the modulus |
-------------------- |
loadOp(op_modulus, m); -- visual check needed |
write(Lw, string'(" m written")); |
writeline(output, Lw); |
|
-- load g0 |
----------- |
loadOp(op_0, g0); |
-- verify |
readOp(op_0, data_read, base_width); |
if (g0(base_width-1 downto 0) = data_read(base_width-1 downto 0)) then |
write(Lw, string'(" g0 written in operand_0")); writeline(output, Lw); |
else |
write(Lw, string'(" failed to write g0 to operand_0!")); writeline(output, Lw); |
assert false report "Load g0 to op0 data verify failed!!" severity failure; |
end if; |
|
-- load g1 |
----------- |
loadOp(op_1, g1); |
-- verify |
readOp(op_1, data_read, base_width); |
if (g1(base_width-1 downto 0) = data_read(base_width-1 downto 0)) then |
write(Lw, string'(" g1 written in operand_1")); writeline(output, Lw); |
else |
write(Lw, string'(" failed to write g1 to operand_1!")); writeline(output, Lw); |
assert false report "Load g1 to op1 data verify failed!!" severity failure; |
end if; |
|
-- load R2 |
----------- |
loadOp(op_2, R2); |
-- verify |
readOp(op_2, data_read, base_width); |
if (R2(base_width-1 downto 0) = data_read(base_width-1 downto 0)) then |
write(Lw, string'(" R^2 written in operand_2")); writeline(output, Lw); |
else |
write(Lw, string'(" failed to write R^2 to operand_2!")); writeline(output, Lw); |
assert false report "Load R2 to op2 data verify failed!!" severity failure; |
end if; |
|
-- load a=1 |
------------ |
loadOp(op_3, one); |
-- verify |
readOp(op_3, data_read, base_width); |
if (one(base_width-1 downto 0) = data_read(base_width-1 downto 0)) then |
write(Lw, string'(" 1 written in operand_3")); writeline(output, Lw); |
else |
write(Lw, string'(" failed to write 1 to operand_3!")); writeline(output, Lw); |
assert false report "Load 1 to op3 data verify failed!!" severity failure; |
end if; |
|
writeline(output, Lw); |
write(Lw, string'("----- Pre-computations: ")); |
writeline(output, Lw); |
|
-- compute gt0 |
--------------- |
core_x_sel_single <= "00"; -- g0 |
core_y_sel_single <= "10"; -- R^2 |
core_dest_op_single <= "00"; -- op_0 = (g0 * R) mod m |
wait until rising_edge(clk); |
timer := NOW; |
core_start <= '1'; |
wait until rising_edge(clk); |
core_start <= '0'; |
wait until core_ready = '1'; |
timer := NOW-timer; |
waitclk(10); |
readOp(op_0, data_read, base_width); |
write(Lw, string'(" Computed gt0: ")); |
hwrite(Lw, data_read(base_width-1 downto 0)); |
writeline(output, Lw); |
write(Lw, string'(" Read gt0: ")); |
hwrite(Lw, gt0(base_width-1 downto 0)); |
writeline(output, Lw); |
write(Lw, string'(" => calc time is ")); |
write(Lw, string'(ToString(timer))); |
writeline(output, Lw); |
write(Lw, string'(" => expected time is ")); |
write(Lw, (nr_stages+(2*(base_width-1)))*clk_period); |
writeline(output, Lw); |
if (gt0(base_width-1 downto 0) = data_read(base_width-1 downto 0)) then |
write(Lw, string'(" => gt0 is correct!")); writeline(output, Lw); |
else |
write(Lw, string'(" => Error: gt0 is incorrect!!!")); writeline(output, Lw); |
assert false report "gt0 is incorrect!!!" severity failure; |
end if; |
|
-- compute gt1 |
--------------- |
core_x_sel_single <= "01"; -- g1 |
core_y_sel_single <= "10"; -- R^2 |
core_dest_op_single <= "01"; -- op_1 = (g1 * R) mod m |
wait until rising_edge(clk); |
timer := NOW; |
core_start <= '1'; |
wait until rising_edge(clk); |
core_start <= '0'; |
wait until core_ready = '1'; |
timer := NOW-timer; |
waitclk(10); |
readOp(op_1, data_read, base_width); |
write(Lw, string'(" Computed gt1: ")); |
hwrite(Lw, data_read(base_width-1 downto 0)); |
writeline(output, Lw); |
write(Lw, string'(" Read gt1: ")); |
hwrite(Lw, gt1(base_width-1 downto 0)); |
writeline(output, Lw); |
write(Lw, string'(" => calc time is ")); |
write(Lw, string'(ToString(timer))); |
writeline(output, Lw); |
write(Lw, string'(" => expected time is ")); |
write(Lw, (nr_stages+(2*(base_width-1)))*clk_period); |
writeline(output, Lw); |
if (gt1(base_width-1 downto 0) = data_read(base_width-1 downto 0)) then |
write(Lw, string'(" => gt1 is correct!")); writeline(output, Lw); |
else |
write(Lw, string'(" => Error: gt1 is incorrect!!!")); writeline(output, Lw); |
assert false report "gt1 is incorrect!!!" severity failure; |
end if; |
|
-- compute a |
------------- |
core_x_sel_single <= "10"; -- R^2 |
core_y_sel_single <= "11"; -- 1 |
core_dest_op_single <= "11"; -- op_3 = (R) mod m |
wait until rising_edge(clk); |
core_start <= '1'; |
timer := NOW; |
wait until rising_edge(clk); |
core_start <= '0'; |
wait until core_ready = '1'; |
timer := NOW-timer; |
waitclk(10); |
readOp(op_3, data_read, base_width); |
write(Lw, string'(" Computed a=(R)mod m: ")); |
hwrite(Lw, data_read(base_width-1 downto 0)); |
writeline(output, Lw); |
write(Lw, string'(" Read (R)mod m: ")); |
hwrite(Lw, R(base_width-1 downto 0)); |
writeline(output, Lw); |
write(Lw, string'(" => calc time is ")); |
write(Lw, string'(ToString(timer))); |
writeline(output, Lw); |
write(Lw, string'(" => expected time is ")); |
write(Lw, (nr_stages+(2*(base_width-1)))*clk_period); |
writeline(output, Lw); |
if (R(base_width-1 downto 0) = data_read(base_width-1 downto 0)) then |
write(Lw, string'(" => (R)mod m is correct!")); writeline(output, Lw); |
else |
write(Lw, string'(" => Error: (R)mod m is incorrect!!!")); writeline(output, Lw); |
assert false report "(R)mod m is incorrect!!!" severity failure; |
end if; |
|
-- compute gt01 |
--------------- |
core_x_sel_single <= "00"; -- gt0 |
core_y_sel_single <= "01"; -- gt1 |
core_dest_op_single <= "10"; -- op_2 = (gt0 * gt1) mod m |
wait until rising_edge(clk); |
core_start <= '1'; |
timer := NOW; |
wait until rising_edge(clk); |
core_start <= '0'; |
wait until core_ready = '1'; |
timer := NOW-timer; |
waitclk(10); |
readOp(op_2, data_read, base_width); |
write(Lw, string'(" Computed gt01: ")); |
hwrite(Lw, data_read(base_width-1 downto 0)); |
writeline(output, Lw); |
write(Lw, string'(" Read gt01: ")); |
hwrite(Lw, gt01(base_width-1 downto 0)); |
writeline(output, Lw); |
write(Lw, string'(" => calc time is ")); |
write(Lw, string'(ToString(timer))); |
writeline(output, Lw); |
write(Lw, string'(" => expected time is ")); |
write(Lw, (nr_stages+(2*(base_width-1)))*clk_period); |
writeline(output, Lw); |
if (gt01(base_width-1 downto 0) = data_read(base_width-1 downto 0)) then |
write(Lw, string'(" => gt01 is correct!")); writeline(output, Lw); |
else |
write(Lw, string'(" => Error: gt01 is incorrect!!!")); writeline(output, Lw); |
assert false report "gt01 is incorrect!!!" severity failure; |
end if; |
|
-- load exponent fifo |
---------------------- |
writeline(output, Lw); |
write(Lw, string'("----- Loading exponent fifo: ")); |
writeline(output, Lw); |
for i in (exponent_width/16)-1 downto 0 loop |
core_fifo_din <= e1((i*16)+15 downto (i*16)) & e0((i*16)+15 downto (i*16)); |
wait until rising_edge(clk); |
core_fifo_push <= '1'; |
wait until rising_edge(clk); |
assert (core_fifo_full='0' and core_fifo_nopush='0') |
report "Fifo error, full or nopush" severity failure; |
core_fifo_push <= '0'; |
wait until rising_edge(clk); |
end loop; |
waitclk(10); |
write(Lw, string'(" Done")); |
writeline(output, Lw); |
|
-- start exponentiation |
------------------------ |
writeline(output, Lw); |
write(Lw, string'("----- Starting exponentiation: ")); |
writeline(output, Lw); |
core_run_auto <= '1'; |
wait until rising_edge(clk); |
timer := NOW; |
core_start <= '1'; |
wait until rising_edge(clk); |
core_start <= '0'; |
wait until core_ready='1'; |
timer := NOW-timer; |
waitclk(10); |
write(Lw, string'(" => calc time is ")); |
write(Lw, string'(ToString(timer))); |
writeline(output, Lw); |
write(Lw, string'(" => expected time is ")); |
write(Lw, ((nr_stages+(2*(base_width-1)))*clk_period*7*exponent_width)/4); |
writeline(output, Lw); |
write(Lw, string'(" => Done")); |
core_run_auto <= '0'; |
writeline(output, Lw); |
|
-- post-computations |
--------------------- |
writeline(output, Lw); |
write(Lw, string'("----- Post-computations: ")); |
writeline(output, Lw); |
-- load in 1 to operand 2 |
loadOp(op_2, one); |
-- verify |
readOp(op_2, data_read, base_width); |
if (one(base_width-1 downto 0) = data_read(base_width-1 downto 0)) then |
write(Lw, string'(" 1 written in operand_2")); writeline(output, Lw); |
else |
write(Lw, string'(" failed to write 1 to operand_2!")); writeline(output, Lw); |
assert false report "Load 1 to op2 data verify failed!!" severity failure; |
end if; |
-- compute result |
core_x_sel_single <= "11"; -- a |
core_y_sel_single <= "10"; -- 1 |
core_dest_op_single <= "11"; -- op_3 = (a) mod m |
wait until rising_edge(clk); |
timer := NOW; |
core_start <= '1'; |
wait until rising_edge(clk); |
core_start <= '0'; |
wait until core_ready = '1'; |
timer := NOW-timer; |
waitclk(10); |
readOp(op_3, data_read, base_width); |
write(Lw, string'(" Computed result: ")); |
hwrite(Lw, data_read(base_width-1 downto 0)); |
writeline(output, Lw); |
write(Lw, string'(" => calc time is ")); |
write(Lw, string'(ToString(timer))); |
writeline(output, Lw); |
write(Lw, string'(" => expected time is ")); |
write(Lw, (nr_stages+(2*(base_width-1)))*clk_period); |
writeline(output, Lw); |
|
when 12 => -- check with result |
hread(L, result(base_width-1 downto 0), good_value); |
assert good_value report "Can not read result! (wrong lenght?)" severity failure; |
writeline(output, Lw); |
write(Lw, string'("----- verifying result: ")); |
writeline(output, Lw); |
write(Lw, string'(" Read result: ")); |
hwrite(Lw, result(base_width-1 downto 0)); |
writeline(output, Lw); |
write(Lw, string'(" Computed result: ")); |
hwrite(Lw, data_read(base_width-1 downto 0)); |
writeline(output, Lw); |
if (result(base_width-1 downto 0) = data_read(base_width-1 downto 0)) then |
write(Lw, string'(" => Result is correct!")); writeline(output, Lw); |
else |
write(Lw, string'(" Error: result is incorrect!!!")); writeline(output, Lw); |
assert false report "result is incorrect!!!" severity failure; |
end if; |
writeline(output, Lw); |
|
when others => |
assert false report "undefined state!" severity failure; |
end case; |
|
if (param_count = 12) then |
param_count := 0; |
else |
param_count := param_count+1; |
end if; |
end loop; |
|
wait for 1 us; |
assert false report "End of simulation" severity failure; |
|
end process; |
|
------------------------------------------ |
-- Multiplier core instance |
------------------------------------------ |
the_multiplier : multiplier_core |
port map( |
clk => clk, |
reset => 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, |
run_auto => core_run_auto, |
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 |
); |
|
|
end test; |
|
/tags/start_version/rtl/vhdl/interface/plb/user_logic.vhd
0,0 → 1,450
------------------------------------------------------------------------------ |
-- 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 |
|
------------------------------------------------------------------------------ |
-- 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 |
-- 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 |
component multiplier_core |
port( clk : in std_logic; |
reset : in std_logic; |
-- operand memory interface (plb shared memory) |
write_enable : in std_logic; |
data_in : in std_logic_vector (31 downto 0); |
rw_address : in std_logic_vector (8 downto 0); |
data_out : out std_logic_vector (31 downto 0); |
collision : out std_logic; |
-- op_sel fifo interface |
fifo_din : in std_logic_vector (31 downto 0); |
fifo_push : in std_logic; |
fifo_full : out std_logic; |
fifo_nopush : out std_logic; |
-- ctrl signals |
start : in std_logic; |
run_auto : in std_logic; |
ready : out std_logic; |
x_sel_single : in std_logic_vector (1 downto 0); |
y_sel_single : in std_logic_vector (1 downto 0); |
dest_op_single : in std_logic_vector (1 downto 0); |
p_sel : in std_logic_vector (1 downto 0); |
calc_time : out std_logic |
); |
end component; |
|
------------------------------------------------------------------ |
-- 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_run_auto : 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); |
|
------------------------------------------------------------------ |
-- 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_start <= slv_reg0(8); |
core_run_auto <= slv_reg0(9); |
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); |
|
------------------------------------------ |
-- Multiplier core instance |
------------------------------------------ |
the_multiplier: multiplier_core |
port map( clk => Bus2IP_Clk, -- v |
reset => Bus2IP_Reset, -- v |
-- 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, -- v |
-- op_sel fifo interface |
fifo_din => core_fifo_din, |
fifo_push => core_fifo_push, |
fifo_full => core_fifo_full, -- v |
fifo_nopush => core_fifo_nopush, -- v |
-- ctrl signals |
start => core_start, -- v |
run_auto => core_run_auto, -- v |
ready => core_ready, -- v |
x_sel_single => core_x_sel_single, -- v |
y_sel_single => core_y_sel_single, -- v |
dest_op_single => core_dest_op_single, -- v |
p_sel => core_p_sel, -- v |
calc_time => calc_time -- v |
); |
|
------------------------------------------ |
-- 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; |
/tags/start_version/rtl/vhdl/interface/plb/mont_mult1536.vhd
0,0 → 1,630
------------------------------------------------------------------------------ |
-- mont_mult1536.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: mont_mult1536.vhd |
-- Version: 2.00.a |
-- 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 mont_mult1536_v2_00_a; |
use mont_mult1536_v2_00_a.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 mont_mult1536 is |
generic |
( |
-- ADD USER GENERICS BELOW THIS LINE --------------- |
--USER generics added here |
-- 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_MEM0_BASEADDR : std_logic_vector := X"FFFFFFFF"; |
C_MEM0_HIGHADDR : std_logic_vector := X"00000000"; |
C_MEM1_BASEADDR : std_logic_vector := X"FFFFFFFF"; |
C_MEM1_HIGHADDR : std_logic_vector := X"00000000"; |
C_MEM2_BASEADDR : std_logic_vector := X"FFFFFFFF"; |
C_MEM2_HIGHADDR : std_logic_vector := X"00000000"; |
C_MEM3_BASEADDR : std_logic_vector := X"FFFFFFFF"; |
C_MEM3_HIGHADDR : std_logic_vector := X"00000000"; |
C_MEM4_BASEADDR : std_logic_vector := X"FFFFFFFF"; |
C_MEM4_HIGHADDR : std_logic_vector := X"00000000"; |
C_MEM5_BASEADDR : std_logic_vector := X"FFFFFFFF"; |
C_MEM5_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 mont_mult1536; |
|
------------------------------------------------------------------------------ |
-- Architecture section |
------------------------------------------------------------------------------ |
|
architecture IMP of mont_mult1536 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_MEM0_BASEADDR, -- user logic memory space 0 base address |
ZERO_ADDR_PAD & C_MEM0_HIGHADDR, -- user logic memory space 0 high address |
ZERO_ADDR_PAD & C_MEM1_BASEADDR, -- user logic memory space 1 base address |
ZERO_ADDR_PAD & C_MEM1_HIGHADDR, -- user logic memory space 1 high address |
ZERO_ADDR_PAD & C_MEM2_BASEADDR, -- user logic memory space 2 base address |
ZERO_ADDR_PAD & C_MEM2_HIGHADDR, -- user logic memory space 2 high address |
ZERO_ADDR_PAD & C_MEM3_BASEADDR, -- user logic memory space 3 base address |
ZERO_ADDR_PAD & C_MEM3_HIGHADDR, -- user logic memory space 3 high address |
ZERO_ADDR_PAD & C_MEM4_BASEADDR, -- user logic memory space 4 base address |
ZERO_ADDR_PAD & C_MEM4_HIGHADDR, -- user logic memory space 4 high address |
ZERO_ADDR_PAD & C_MEM5_BASEADDR, -- user logic memory space 5 base address |
ZERO_ADDR_PAD & C_MEM5_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 mont_mult1536_v2_00_a.user_logic |
generic map |
( |
-- MAP USER GENERICS BELOW THIS LINE --------------- |
--USER generics mapped here |
-- 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; |
/tags/start_version/rtl/vhdl/core/autorun_cntrl.vhd
0,0 → 1,171
------------------------------------------------------------------------------------ |
-- |
-- Geoffrey Ottoy - DraMCo research group |
-- |
-- Module Name: autorun_cntrl.vhd / entity autorun_cntrl |
-- |
-- Last Modified: 25/04/2012 |
-- |
-- Description: autorun control unit for a pipelined montgomery multiplier |
-- |
-- |
-- Dependencies: none |
-- |
-- Revision 2.00 - Major bug fix: bit_counter should count from 15 downto 0. |
-- Revision 1.00 - Architecture created |
-- Revision 0.01 - File Created |
-- Additional Comments: |
-- |
-- |
------------------------------------------------------------------------------------ |
-- |
-- NOTICE: |
-- |
-- Copyright DraMCo research group. 2011. This code may be contain portions patented |
-- by other third parties! |
-- |
---------------------------------------------------------------------------------- |
library IEEE; |
use IEEE.STD_LOGIC_1164.ALL; |
use IEEE.STD_LOGIC_ARITH.ALL; |
use IEEE.STD_LOGIC_UNSIGNED.ALL; |
|
---- Uncomment the following library declaration if instantiating |
---- any Xilinx primitives in this code. |
--library UNISIM; |
--use UNISIM.VComponents.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 next_bit_del_i : std_logic; |
|
signal start_cycle_i : std_logic := '0'; |
signal start_cycle_del_i : std_logic; |
|
signal done_i : std_logic; |
signal start_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 <= (multiplier_done and (not running_i)) or (start and buffer_empty); |
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) |
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; |
|
/tags/start_version/rtl/vhdl/core/cell_1b_adder.vhd
0,0 → 1,54
------------------------------------------------------------------------------------ |
-- |
-- Geoffrey Ottoy - DraMCo research group |
-- |
-- Module Name: cell_1b_adder.vhd / entity cell_1b_adder |
-- |
-- Last Modified: 18/11/2011 |
-- |
-- Description: full adder for use in the montgommery multiplier systolic array |
-- currently a behavioral description |
-- |
-- |
-- Dependencies: none |
-- |
-- Revision: |
-- Revision 2.00 - Major error resolved (carry & sum output were switched) |
-- Revision 1.00 - Architecture |
-- Revision 0.01 - File Created |
-- |
-- |
------------------------------------------------------------------------------------ |
-- |
-- NOTICE: |
-- |
-- Copyright DraMCo research group. 2011. This code may be contain portions patented |
-- by other third parties! |
-- |
------------------------------------------------------------------------------------ |
library IEEE; |
use IEEE.STD_LOGIC_1164.ALL; |
use IEEE.STD_LOGIC_ARITH.ALL; |
use IEEE.STD_LOGIC_UNSIGNED.ALL; |
|
---- Uncomment the following library declaration if instantiating |
---- any Xilinx primitives in this code. |
--library UNISIM; |
--use UNISIM.VComponents.all; |
|
entity cell_1b_adder is |
Port ( a : in STD_LOGIC; |
mux_result : in STD_LOGIC; |
cin : in STD_LOGIC; |
cout : out STD_LOGIC; |
r : out STD_LOGIC); |
end cell_1b_adder; |
|
architecture Behavioral of cell_1b_adder is |
signal a_xor_mux_result: std_logic; |
begin |
a_xor_mux_result <= a xor mux_result; |
r <= a_xor_mux_result xor cin; |
cout <= (a and mux_result) or (cin and a_xor_mux_result); |
end Behavioral; |
|
/tags/start_version/rtl/vhdl/core/x_shift_reg.vhd
0,0 → 1,78
------------------------------------------------------------------------------------ |
-- |
-- Geoffrey Ottoy - DraMCo research group |
-- |
-- Module Name: x_shift_reg.vhd / entity x_shift_reg |
-- |
-- Last Modified: 18/06/2012 |
-- |
-- Description: n-bit shift register with lsb output |
-- |
-- |
-- Dependencies: none |
-- |
-- Revision: |
-- Revision 1.00 - Architecture |
-- Revision 0.01 - File Created |
-- |
-- |
------------------------------------------------------------------------------------ |
-- |
-- NOTICE: |
-- |
-- Copyright DraMCo research group. 2011. This code may be contain portions patented |
-- by other third parties! |
-- |
------------------------------------------------------------------------------------ |
library IEEE; |
use IEEE.STD_LOGIC_1164.ALL; |
use IEEE.STD_LOGIC_ARITH.ALL; |
use IEEE.STD_LOGIC_UNSIGNED.ALL; |
|
---- Uncomment the following library declaration if instantiating |
---- any Xilinx primitives in this code. |
--library UNISIM; |
--use UNISIM.VComponents.all; |
|
entity x_shift_reg is |
generic( n : integer := 1536; |
t : integer := 48; |
tl : integer := 16 |
); |
port( clk : in STD_LOGIC; |
reset : in STD_LOGIC; |
x_in : in STD_LOGIC_VECTOR((n-1) downto 0); |
load_x : in STD_LOGIC; |
next_x : in STD_LOGIC; |
p_sel : in STD_LOGIC_VECTOR(1 downto 0); |
x_i : out STD_LOGIC |
); |
end x_shift_reg; |
|
architecture Behavioral of x_shift_reg is |
signal x_reg_i : std_logic_vector((n-1) downto 0); -- register |
constant s : integer := n/t; -- nr of stages |
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_i <= (others => '0'); |
elsif rising_edge(clk) then |
if load_x = '1' then -- Load_x, load the register with x_in |
x_reg_i <= x_in; |
elsif next_x = '1' then -- next_x, shift to right. LSbit gets lost and zero's are shifted in |
x_reg_i((n-2) downto 0) <= x_reg_i((n-1) downto 1); |
else -- else remember state |
x_reg_i <= x_reg_i; |
end if; |
end if; |
end process; |
|
with p_sel select -- pipeline select |
x_i <= x_reg_i(offset) when "10", -- use bit at offset for high part of pipeline |
x_reg_i(0) when others; -- use LS bit for lower part of pipeline |
|
end Behavioral; |
|
/tags/start_version/rtl/vhdl/core/register_n.vhd
0,0 → 1,71
------------------------------------------------------------------------------------ |
-- |
-- Geoffrey Ottoy - DraMCo research group |
-- |
-- Module Name: register_n.vhd / entity register_n |
-- |
-- Last Modified: 24/11/2011 |
-- |
-- Description: n bit register |
-- |
-- |
-- Dependencies: FDCE |
-- |
-- Revision: |
-- Revision 3.00 - Replaced LDCE primitive with FDCE primitive |
-- Revision 2.00 - Replaced behavioral architecture with structural using FPGA |
-- primitives. |
-- Revision 1.00 - Architecture |
-- Revision 0.01 - File Created |
-- |
-- |
------------------------------------------------------------------------------------ |
-- |
-- NOTICE: |
-- |
-- Copyright DraMCo research group. 2011. This code may be contain portions patented |
-- by other third parties! |
-- |
------------------------------------------------------------------------------------ |
library IEEE; |
use IEEE.STD_LOGIC_1164.ALL; |
use IEEE.STD_LOGIC_ARITH.ALL; |
use IEEE.STD_LOGIC_UNSIGNED.ALL; |
|
---- Uncomment the following library declaration if instantiating |
---- any Xilinx primitives in this code. |
library UNISIM; |
use UNISIM.VComponents.all; |
|
entity register_n is |
generic( n : integer := 4 |
); |
port(core_clk : in STD_LOGIC; |
ce : in STD_LOGIC; |
reset : in STD_LOGIC; |
din : in STD_LOGIC_VECTOR((n-1) downto 0); |
dout : out STD_LOGIC_VECTOR((n-1) downto 0) |
); |
end register_n; |
|
architecture Structural of register_n is |
signal dout_i : std_logic_vector((n-1) downto 0) := (others => '0'); |
begin |
|
dout <= dout_i; |
|
N_REGS: for i in 0 to n-1 generate |
FDCE_inst : FDCE |
generic map ( |
INIT => '0') -- Initial value of latch ('0' or '1') |
port map ( |
Q => dout_i(i), -- Data output |
CLR => reset, -- Asynchronous clear/reset input |
D => din(i), -- Data input |
C => core_clk, -- Gate input |
CE => ce -- Gate enable input |
); |
end generate; |
|
|
end Structural; |
/tags/start_version/rtl/vhdl/core/cell_1b.vhd
0,0 → 1,88
------------------------------------------------------------------------------------ |
-- |
-- Geoffrey Ottoy - DraMCo research group |
-- |
-- Module Name: cell_1b.vhd / entity cell_1b |
-- |
-- Last Modified: 14/11/2011 |
-- |
-- Description: cell for use in the montgommery multiplier systolic array |
-- |
-- |
-- Dependencies: cell_1b_adder |
-- cell_1b_mux |
-- |
-- Revision: |
-- Revision 1.00 - Architecture |
-- Revision 0.01 - File Created |
-- |
-- |
------------------------------------------------------------------------------------ |
-- |
-- NOTICE: |
-- |
-- Copyright DraMCo research group. 2011. This code may be contain portions patented |
-- by other third parties! |
-- |
------------------------------------------------------------------------------------ |
library IEEE; |
use IEEE.STD_LOGIC_1164.ALL; |
use IEEE.STD_LOGIC_ARITH.ALL; |
use IEEE.STD_LOGIC_UNSIGNED.ALL; |
|
---- Uncomment the following library declaration if instantiating |
---- any Xilinx primitives in this code. |
--library UNISIM; |
--use UNISIM.VComponents.all; |
|
entity cell_1b is |
Port ( my : in STD_LOGIC; |
y : in STD_LOGIC; |
m : in STD_LOGIC; |
x : in STD_LOGIC; |
q : in STD_LOGIC; |
a : in STD_LOGIC; |
cin : in STD_LOGIC; |
cout : out STD_LOGIC; |
r : out STD_LOGIC); |
end cell_1b; |
|
architecture Structural of cell_1b is |
component cell_1b_mux |
Port ( my : in STD_LOGIC; |
y : in STD_LOGIC; |
m : in STD_LOGIC; |
x : in STD_LOGIC; |
q : in STD_LOGIC; |
result : out STD_LOGIC); |
end component; |
|
component cell_1b_adder |
Port ( a : in STD_LOGIC; |
mux_result : in STD_LOGIC; |
cin : in STD_LOGIC; |
cout : out STD_LOGIC; |
r : out STD_LOGIC); |
end component; |
|
signal mux2adder : std_logic; |
begin |
|
cell_mux: cell_1b_mux |
port map( my => my, |
y => y, |
m => m, |
x => x, |
q => q, |
result => mux2adder |
); |
|
cell_adder: cell_1b_adder |
port map(a => a, |
mux_result => mux2adder, |
cin => cin, |
cout => cout, |
r => r |
); |
|
end Structural; |
/tags/start_version/rtl/vhdl/core/mont_ctrl.vhd
0,0 → 1,224
------------------------------------------------------------------------------------ |
-- |
-- Geoffrey Ottoy - DraMCo research group |
-- |
-- Module Name: mont_ctrl.vhd / entity mont_ctrl |
-- |
-- Last Modified: 25/04/2012 |
-- |
-- Description: control unit for a pipelined montgomery multiplier, with split |
-- pipeline operation and "auto-run" support |
-- |
-- |
-- Dependencies: autorun_cntrl |
-- |
-- Revision: |
-- Revision 2.00 - Added autorun_control_logic |
-- Revision 1.00 - Architecture with support for single multiplication |
-- Revision 0.01 - File Created |
-- |
-- |
------------------------------------------------------------------------------------ |
-- |
-- NOTICE: |
-- |
-- Copyright DraMCo research group. 2011. This code may be contain portions patented |
-- by other third parties! |
-- |
------------------------------------------------------------------------------------ |
library IEEE; |
use IEEE.STD_LOGIC_1164.ALL; |
use IEEE.STD_LOGIC_ARITH.ALL; |
use IEEE.STD_LOGIC_UNSIGNED.ALL; |
|
---- Uncomment the following library declaration if instantiating |
---- any Xilinx primitives in this code. |
--library UNISIM; |
--use UNISIM.VComponents.all; |
|
entity mont_ctrl is |
port ( clk : in std_logic; --v |
reset : in std_logic; --v |
-- bus side |
start : in std_logic; --v |
--p_sel : in std_logic_vector(1 downto 0); |
x_sel_single : in std_logic_vector(1 downto 0); --v |
y_sel_single : in std_logic_vector(1 downto 0); --v |
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; |
buffer_noread : in std_logic; |
done : out std_logic; |
calc_time : out std_logic; -- v |
-- multiplier side |
op_sel : out std_logic_vector(1 downto 0); --v |
load_x : out std_logic; -- v |
load_result : out std_logic; --v |
start_multiplier : out std_logic; -- v |
multiplier_ready : in std_logic |
|
); |
end mont_ctrl; |
|
architecture Behavioral of mont_ctrl is |
signal start_delayed_i : std_logic; -- delayed version of start input |
signal start_pulse_i : std_logic; |
signal auto_start_pulse_i : std_logic; |
signal start_multiplier_i : std_logic; |
signal start_up_counter_i : std_logic_vector(2 downto 0):= "100"; -- used in op_sel at multiplier start |
signal auto_start_i : std_logic := '0'; |
signal store_autorun_i : std_logic; |
signal run_auto_i : std_logic; |
signal run_auto_stored_i : std_logic := '0'; |
signal single_start_pulse_i : std_logic; |
|
signal calc_time_i : std_logic; -- high ('1') during multiplication |
|
signal x_sel_i : std_logic_vector(1 downto 0); -- the operand used as x input |
signal y_sel_i : std_logic_vector(1 downto 0); -- the operand used as y input |
signal x_sel_buffer_i : std_logic_vector(1 downto 0); -- x operand as specified by fifo buffer (autorun) |
|
signal auto_done_i : std_logic; |
signal start_auto_i : std_logic; |
signal new_buf_part_i : std_logic; |
signal new_buf_word_i : std_logic; |
signal buf_part_i : std_logic_vector(3 downto 0); |
signal pop_i : std_logic; |
signal start_autorun_cycle_i : std_logic; |
signal start_autorun_cycle_1_i : std_logic; |
signal autorun_counter_i : std_logic_vector(1 downto 0); |
signal part_counter_i : std_logic_vector(2 downto 0); |
signal auto_multiplier_done_i : std_logic; |
|
COMPONENT autorun_cntrl |
PORT( |
clk : IN std_logic; |
reset : IN std_logic; |
start : IN std_logic; |
multiplier_done : IN std_logic; |
buffer_din : IN std_logic_vector(31 downto 0); |
buffer_empty : IN std_logic; |
done : OUT std_logic; |
op_sel : OUT std_logic_vector(1 downto 0); |
start_multiplier : OUT std_logic; |
read_buffer : OUT std_logic |
); |
END COMPONENT; |
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_delayed_i <= start; |
end if; |
end process START_PULSE_PROC; |
--start_pulse_i <= store_autorun_i and (not run_auto_i); |
start_pulse_i <= start and (not start_delayed_i); |
single_start_pulse_i <= start_pulse_i and (not run_auto_i); |
--store_autorun_i <= (start and (not start_delayed_i)); |
--start_auto_i <= store_autorun_i and run_auto_i; |
start_auto_i <= start_pulse_i and run_auto_i; |
|
-- to start the multiplier we first need to select the y_operand and |
-- clock it in the y_register |
-- the we select the x_operand and start the multiplier |
START_MULT_PROC: process(clk, reset) |
begin |
if reset = '1' then |
start_up_counter_i <= "100"; |
elsif rising_edge(clk) then |
if start_pulse_i = '1' or auto_start_pulse_i = '1' then |
start_up_counter_i <= "000"; |
elsif start_up_counter_i(2) /= '1' then |
start_up_counter_i <= start_up_counter_i + '1'; |
else |
start_up_counter_i <= "100"; |
end if; |
else |
start_up_counter_i <= start_up_counter_i; |
end if; |
end process; |
|
-- select operands (autorun/single run) |
x_sel_i <= x_sel_buffer_i when (run_auto_i = '1') else x_sel_single; |
y_sel_i <= "11" when (run_auto_i = '1') else y_sel_single; -- y is operand3 in auto mode |
|
-- clock operands to operand_mem output (first y, then x) |
with start_up_counter_i(2 downto 1) select |
op_sel <= y_sel_i when "00", |
x_sel_i when others; |
load_x <= start_up_counter_i(0) and (not start_up_counter_i(1)); |
-- start multiplier |
start_multiplier_i <= start_up_counter_i(1) and start_up_counter_i(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; |
else |
calc_time_i <= calc_time_i; |
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_i when finished |
done <= ((not run_auto_i) and multiplier_ready) or auto_done_i; |
|
----------------------------------------------------------------------------------- |
-- Processes related to op_buffer cntrl and auto_run mode |
-- start_auto_i -> 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_i <- autorun logic determines which operand is used as x |
|
-- check buffer empty signal |
----------------------------------------------------------------------------------- |
|
-- at the beginning of each new multiplication we store the current autorun bit |
-- STORE_AUTORUN_PROC: process(clk) |
-- begin |
-- if rising_edge(clk) then |
-- if store_autorun_i = '1' then |
-- run_auto_stored_i <= run_auto; |
-- else |
-- run_auto_stored_i <= run_auto_stored_i; |
-- end if; |
-- end if; |
-- end process STORE_AUTORUN_PROC; |
run_auto_i <= run_auto; |
--run_auto_i <= run_auto or run_auto_stored_i; |
|
|
-- multiplier_ready is only passed to autorun control when in autorun mode |
auto_multiplier_done_i <= (multiplier_ready and run_auto_i); |
autorun_control_logic: autorun_cntrl PORT MAP( |
clk => clk, |
reset => reset, |
start => start_auto_i, |
done => auto_done_i, |
op_sel => x_sel_buffer_i, |
start_multiplier => auto_start_pulse_i, |
multiplier_done => auto_multiplier_done_i, |
read_buffer => read_buffer, |
buffer_din => op_sel_buffer, |
buffer_empty => op_buffer_empty |
); |
end Behavioral; |
|
/tags/start_version/rtl/vhdl/core/mont_mult_sys_pipeline.vhd
0,0 → 1,281
------------------------------------------------------------------------------------ |
-- |
-- Geoffrey Ottoy - DraMCo research group |
-- |
-- Module Name: mont_mult_sys_pipeline.vhd / entity mont_mult_sys_pipeline |
-- |
-- Last Modified: 18/06/2012 |
-- |
-- Description: n-bit montgomery multiplier with a pipelined systolic array |
-- |
-- |
-- Dependencies: systolic_pipeline |
-- adder_n |
-- cell_1b_adder |
-- x_shift_register |
-- |
-- Revision: |
-- Revision 3.00 - shift register for x selection in stead of decoding logic |
-- Revision 2.01 - Bug fix of the bug fix |
-- Revision 2.00 - Major bug fix in reduction logic (carry in upper part) |
-- Revision 1.00 - Architecture |
-- Revision 0.01 - File Created |
-- |
-- |
------------------------------------------------------------------------------------ |
-- |
-- NOTICE: |
-- |
-- Copyright DraMCo research group. 2011. This code may be contain portions patented |
-- by other third parties! |
-- |
------------------------------------------------------------------------------------ |
library IEEE; |
use IEEE.STD_LOGIC_1164.ALL; |
use IEEE.STD_LOGIC_ARITH.ALL; |
use IEEE.STD_LOGIC_UNSIGNED.ALL; |
|
---- Uncomment the following library declaration if instantiating |
---- any Xilinx primitives in this code. |
--library UNISIM; |
--use UNISIM.VComponents.all; |
|
entity mont_mult_sys_pipeline is |
generic ( n : integer := 1536; |
nr_stages : integer := 96; --(divides n, bits_low & (n-bits_low)) |
stages_low : integer := 32 |
); |
Port ( core_clk : in STD_LOGIC; |
xy : in STD_LOGIC_VECTOR((n-1) downto 0); |
m : in STD_LOGIC_VECTOR((n-1) downto 0); |
r : out STD_LOGIC_VECTOR((n-1) downto 0); |
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_mult_sys_pipeline; |
|
architecture Structural of mont_mult_sys_pipeline is |
component adder_n |
generic ( width : integer := 16; |
block_width : integer := 4 |
); |
Port ( core_clk : in STD_LOGIC; |
a : in STD_LOGIC_VECTOR((width-1) downto 0); |
b : in STD_LOGIC_VECTOR((width-1) downto 0); |
cin : in STD_LOGIC; |
cout : out STD_LOGIC; |
s : out STD_LOGIC_VECTOR((width-1) downto 0) |
); |
end component; |
|
component systolic_pipeline |
generic( n : integer := 1536; -- width of the operands (# bits) |
t : integer := 96; -- number of stages (divider of n) >= 2 |
tl: integer := 32 |
); |
port(core_clk : in STD_LOGIC; |
my : in STD_LOGIC_VECTOR((n) downto 0); |
y : in STD_LOGIC_VECTOR((n-1) downto 0); |
m : in STD_LOGIC_VECTOR((n-1) downto 0); |
xi : in STD_LOGIC; |
start : in STD_LOGIC; |
reset : in STD_LOGIC; |
p_sel : in STD_LOGIC_VECTOR(1 downto 0); |
ready : out STD_LOGIC; |
next_x : out STD_LOGIC; |
r : out STD_LOGIC_VECTOR((n+1) downto 0) |
); |
end component; |
|
component x_shift_reg |
generic( n : integer := 32; |
t : integer := 8; |
tl : integer := 3 |
); |
port( clk : in STD_LOGIC; |
reset : in STD_LOGIC; |
x_in : in STD_LOGIC_VECTOR((n-1) downto 0); |
load_x : in STD_LOGIC; |
next_x : in STD_LOGIC; |
p_sel : in STD_LOGIC_VECTOR(1 downto 0); |
x_i : out STD_LOGIC |
); |
end component; |
|
component cell_1b_adder |
Port ( a : in STD_LOGIC; |
mux_result : in STD_LOGIC; |
cin : in STD_LOGIC; |
cout : out STD_LOGIC; |
r : out STD_LOGIC); |
end component; |
|
component d_flip_flop |
port(core_clk : in STD_LOGIC; |
reset : in STD_LOGIC; |
din : in STD_LOGIC; |
dout : out STD_LOGIC |
); |
end component; |
|
constant stage_width : integer := n/nr_stages; |
constant bits_l : integer := stage_width * stages_low; |
constant bits_h : integer := n - bits_l; |
|
signal my : std_logic_vector(n downto 0); |
signal my_h_cin : std_logic; |
signal my_l_cout : std_logic; |
signal r_pipeline : std_logic_vector(n+1 downto 0); |
signal r_red : std_logic_vector(n-1 downto 0); |
signal r_i : std_logic_vector(n-1 downto 0); |
signal c_red_l : std_logic_vector(2 downto 0); |
signal c_red_h : std_logic_vector(2 downto 0); |
signal cin_red_h : std_logic; |
signal r_sel : std_logic; |
signal reset_multiplier : std_logic; |
signal start_multiplier : std_logic; |
signal m_inv : std_logic_vector(n-1 downto 0); |
|
signal next_x_i : std_logic; |
signal x_i : std_logic; |
begin |
-- x selection |
x_selection: x_shift_reg |
generic map( n => n, |
t => nr_stages, |
tl => stages_low |
) |
port map(clk => core_clk, |
reset => reset, |
x_in => xy, |
load_x => load_x, |
next_x => next_x_i, |
p_sel => p_sel, |
x_i => x_i |
); |
|
-- precomputation of my (m+y) |
my_adder_l: adder_n |
generic map( width => bits_l, |
block_width => stage_width |
) |
port map( core_clk => core_clk, |
a => m((bits_l-1) downto 0), |
b => xy((bits_l-1) downto 0), |
cin => '0', |
cout => my_l_cout, |
s => my((bits_l-1) downto 0) |
); |
|
my_adder_h: adder_n |
generic map( width => bits_h, |
block_width => stage_width |
) |
port map( core_clk => core_clk, |
a => m((n-1) downto bits_l), |
b => xy((n-1) downto bits_l), |
cin => my_h_cin, |
cout => my(n), |
s => my((n-1) downto bits_l) |
); |
|
my_h_cin <= '0' when (p_sel(1) and (not p_sel(0)))='1' else my_l_cout; |
|
-- multiplication |
reset_multiplier <= reset or start; |
|
delay_1_cycle: d_flip_flop |
port map(core_clk => core_clk, |
reset => reset, |
din => start, |
dout => start_multiplier |
); |
|
|
the_multiplier: systolic_pipeline |
generic map( n => n, -- width of the operands (# bits) |
t => nr_stages, -- number of stages (divider of n) >= 2 |
tl => stages_low |
) |
port map(core_clk => core_clk, |
my => my, |
y => xy, |
m => m, |
xi => x_i, |
start => start_multiplier, |
reset => reset_multiplier, |
p_sel => p_sel, |
ready => ready, -- misschien net iets te vroeg? |
next_x => next_x_i, |
r => r_pipeline |
); |
|
-- post-computation (reduction) |
m_inv <= not(m); |
|
reduction_adder_l: adder_n |
generic map( width => bits_l, |
block_width => stage_width |
) |
port map( core_clk => core_clk, |
a => m_inv((bits_l-1) downto 0), |
b => r_pipeline((bits_l-1) downto 0), |
cin => '1', |
cout => c_red_l(0), |
s => r_red((bits_l-1) downto 0) |
); |
|
reduction_adder_l_a: cell_1b_adder |
port map(a => '1', |
mux_result => r_pipeline(bits_l), |
cin => c_red_l(0), |
cout => c_red_l(1) |
--r => |
); |
|
reduction_adder_l_b: cell_1b_adder |
port map(a => '1', |
mux_result => r_pipeline(bits_l+1), |
cin => c_red_l(1), |
cout => c_red_l(2) |
-- r => |
); |
|
--cin_red_h <= p_sel(1) and (not p_sel(0)); |
cin_red_h <= c_red_l(0) when p_sel(0) = '1' else '1'; |
|
reduction_adder_h: adder_n |
generic map( width => bits_h, |
block_width => stage_width |
) |
port map( core_clk => core_clk, |
a => m_inv((n-1) downto bits_l), |
b => r_pipeline((n-1) downto bits_l), |
cin => cin_red_h, |
cout => c_red_h(0), |
s => r_red((n-1) downto bits_l) |
); |
|
reduction_adder_h_a: cell_1b_adder |
port map(a => '1', |
mux_result => r_pipeline(n), |
cin => c_red_h(0), |
cout => c_red_h(1) |
); |
|
reduction_adder_h_b: cell_1b_adder |
port map(a => '1', |
mux_result => r_pipeline(n+1), |
cin => c_red_h(1), |
cout => c_red_h(2) |
); |
|
r_sel <= (c_red_h(2) and p_sel(1)) or (c_red_l(2) and (p_sel(0) and (not p_sel(1)))); |
r_i <= r_red when r_sel = '1' else r_pipeline((n-1) downto 0); |
|
-- output |
r <= r_i; |
end Structural; |
/tags/start_version/rtl/vhdl/core/std_logic_textio.vhd
0,0 → 1,653
---------------------------------------------------------------------------- |
-- |
-- Copyright (c) 1990, 1991, 1992 by Synopsys, Inc. All rights reserved. |
-- |
-- 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 this copyright notice. |
-- |
-- Package name: STD_LOGIC_TEXTIO |
-- |
-- Purpose: This package overloads the standard TEXTIO procedures |
-- READ and WRITE. |
-- |
-- Author: CRC, TS |
-- |
---------------------------------------------------------------------------- |
|
use STD.textio.all; |
library IEEE; |
use IEEE.std_logic_1164.all; |
|
package STD_LOGIC_TEXTIO is |
--synopsys synthesis_off |
-- Read and Write procedures for STD_ULOGIC and STD_ULOGIC_VECTOR |
procedure READ(L:inout LINE; VALUE:out STD_ULOGIC); |
procedure READ(L:inout LINE; VALUE:out STD_ULOGIC; GOOD: out BOOLEAN); |
procedure READ(L:inout LINE; VALUE:out STD_ULOGIC_VECTOR); |
procedure READ(L:inout LINE; VALUE:out STD_ULOGIC_VECTOR; GOOD: out BOOLEAN); |
procedure WRITE(L:inout LINE; VALUE:in STD_ULOGIC; |
JUSTIFIED:in SIDE := RIGHT; FIELD:in WIDTH := 0); |
procedure WRITE(L:inout LINE; VALUE:in STD_ULOGIC_VECTOR; |
JUSTIFIED:in SIDE := RIGHT; FIELD:in WIDTH := 0); |
|
-- Read and Write procedures for STD_LOGIC_VECTOR |
procedure READ(L:inout LINE; VALUE:out STD_LOGIC_VECTOR); |
procedure READ(L:inout LINE; VALUE:out STD_LOGIC_VECTOR; GOOD: out BOOLEAN); |
procedure WRITE(L:inout LINE; VALUE:in STD_LOGIC_VECTOR; |
JUSTIFIED:in SIDE := RIGHT; FIELD:in WIDTH := 0); |
|
-- |
-- Read and Write procedures for Hex and Octal values. |
-- The values appear in the file as a series of characters |
-- between 0-F (Hex), or 0-7 (Octal) respectively. |
-- |
|
-- Hex |
procedure HREAD(L:inout LINE; VALUE:out STD_ULOGIC_VECTOR); |
procedure HREAD(L:inout LINE; VALUE:out STD_ULOGIC_VECTOR; GOOD: out BOOLEAN); |
procedure HWRITE(L:inout LINE; VALUE:in STD_ULOGIC_VECTOR; |
JUSTIFIED:in SIDE := RIGHT; FIELD:in WIDTH := 0); |
procedure HREAD(L:inout LINE; VALUE:out STD_LOGIC_VECTOR); |
procedure HREAD(L:inout LINE; VALUE:out STD_LOGIC_VECTOR; GOOD: out BOOLEAN); |
procedure HWRITE(L:inout LINE; VALUE:in STD_LOGIC_VECTOR; |
JUSTIFIED:in SIDE := RIGHT; FIELD:in WIDTH := 0); |
|
-- Octal |
procedure OREAD(L:inout LINE; VALUE:out STD_ULOGIC_VECTOR); |
procedure OREAD(L:inout LINE; VALUE:out STD_ULOGIC_VECTOR; GOOD: out BOOLEAN); |
procedure OWRITE(L:inout LINE; VALUE:in STD_ULOGIC_VECTOR; |
JUSTIFIED:in SIDE := RIGHT; FIELD:in WIDTH := 0); |
procedure OREAD(L:inout LINE; VALUE:out STD_LOGIC_VECTOR); |
procedure OREAD(L:inout LINE; VALUE:out STD_LOGIC_VECTOR; GOOD: out BOOLEAN); |
procedure OWRITE(L:inout LINE; VALUE:in STD_LOGIC_VECTOR; |
JUSTIFIED:in SIDE := RIGHT; FIELD:in WIDTH := 0); |
|
|
--synopsys synthesis_on |
end STD_LOGIC_TEXTIO; |
|
package body STD_LOGIC_TEXTIO is |
--synopsys synthesis_off |
|
-- Type and constant definitions used to map STD_ULOGIC values |
-- into/from character values. |
|
type MVL9plus is ('U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-', ERROR); |
type char_indexed_by_MVL9 is array (STD_ULOGIC) of character; |
type MVL9_indexed_by_char is array (character) of STD_ULOGIC; |
type MVL9plus_indexed_by_char is array (character) of MVL9plus; |
|
constant MVL9_to_char: char_indexed_by_MVL9 := "UX01ZWLH-"; |
constant char_to_MVL9: MVL9_indexed_by_char := |
('U' => 'U', 'X' => 'X', '0' => '0', '1' => '1', 'Z' => 'Z', |
'W' => 'W', 'L' => 'L', 'H' => 'H', '-' => '-', others => 'U'); |
constant char_to_MVL9plus: MVL9plus_indexed_by_char := |
('U' => 'U', 'X' => 'X', '0' => '0', '1' => '1', 'Z' => 'Z', |
'W' => 'W', 'L' => 'L', 'H' => 'H', '-' => '-', others => ERROR); |
|
|
-- Overloaded procedures. |
|
procedure READ(L:inout LINE; VALUE:out STD_ULOGIC; GOOD:out BOOLEAN) is |
variable c: character; |
variable readOk: BOOLEAN; |
begin |
loop -- skip white space |
read(l,c,readOk); -- but also exit on a bad read |
exit when ((readOk = FALSE) or ((c /= ' ') and (c /= CR) and (c /= HT))); |
end loop; |
|
if (readOk = FALSE) then |
good := FALSE; |
else |
if (char_to_MVL9plus(c) = ERROR) then |
value := 'U'; |
good := FALSE; |
else |
value := char_to_MVL9(c); |
good := TRUE; |
end if; |
end if; |
end READ; |
|
procedure READ(L:inout LINE; VALUE:out STD_ULOGIC_VECTOR; GOOD:out BOOLEAN) is |
variable m: STD_ULOGIC; |
variable c: character; |
variable s: string(1 to value'length-1); |
variable mv: STD_ULOGIC_VECTOR(0 to value'length-1); |
constant allU: STD_ULOGIC_VECTOR(0 to value'length-1) |
:= (others => 'U'); |
variable readOk: BOOLEAN; |
|
begin |
loop -- skip white space |
read(l,c,readOk); |
exit when ((readOk = FALSE) or ((c /= ' ') and (c /= CR) and (c /= HT))); |
end loop; |
|
-- Bail out if there was a bad read |
if (readOk = FALSE) then |
good := FALSE; |
return; |
end if; |
|
if (char_to_MVL9plus(c) = ERROR) then |
value := allU; |
good := FALSE; |
return; |
end if; |
|
read(l, s, readOk); |
-- Bail out if there was a bad read |
if (readOk = FALSE) then |
good := FALSE; |
return; |
end if; |
|
for i in 1 to value'length-1 loop |
if (char_to_MVL9plus(s(i)) = ERROR) then |
value := allU; |
good := FALSE; |
return; |
end if; |
end loop; |
|
mv(0) := char_to_MVL9(c); |
for i in 1 to value'length-1 loop |
mv(i) := char_to_MVL9(s(i)); |
end loop; |
value := mv; |
good := TRUE; |
end READ; |
|
procedure READ(L:inout LINE; VALUE:out STD_ULOGIC) is |
variable c: character; |
begin |
loop -- skip white space |
read(l,c); |
exit when ((c /= ' ') and (c /= CR) and (c /= HT)); |
end loop; |
|
if (char_to_MVL9plus(c) = ERROR) then |
value := 'U'; |
assert FALSE report "READ(STD_ULOGIC) Error: Character '" & |
c & "' read, expected STD_ULOGIC literal."; |
else |
value := char_to_MVL9(c); |
end if; |
end READ; |
|
procedure READ(L:inout LINE; VALUE:out STD_ULOGIC_VECTOR) is |
variable m: STD_ULOGIC; |
variable c: character; |
variable s: string(1 to value'length-1); |
variable mv: STD_ULOGIC_VECTOR(0 to value'length-1); |
constant allU: STD_ULOGIC_VECTOR(0 to value'length-1) |
:= (others => 'U'); |
begin |
loop -- skip white space |
read(l,c); |
exit when ((c /= ' ') and (c /= CR) and (c /= HT)); |
end loop; |
|
if (char_to_MVL9plus(c) = ERROR) then |
value := allU; |
assert FALSE report |
"READ(STD_ULOGIC_VECTOR) Error: Character '" & |
c & "' read, expected STD_ULOGIC literal."; |
return; |
end if; |
|
read(l, s); |
for i in 1 to value'length-1 loop |
if (char_to_MVL9plus(s(i)) = ERROR) then |
value := allU; |
assert FALSE report |
"READ(STD_ULOGIC_VECTOR) Error: Character '" & |
s(i) & "' read, expected STD_ULOGIC literal."; |
return; |
end if; |
end loop; |
|
mv(0) := char_to_MVL9(c); |
for i in 1 to value'length-1 loop |
mv(i) := char_to_MVL9(s(i)); |
end loop; |
value := mv; |
end READ; |
|
procedure WRITE(L:inout LINE; VALUE:in STD_ULOGIC; |
JUSTIFIED:in SIDE := RIGHT; FIELD:in WIDTH := 0) is |
begin |
write(l, MVL9_to_char(value), justified, field); |
end WRITE; |
|
|
procedure WRITE(L:inout LINE; VALUE:in STD_ULOGIC_VECTOR; |
JUSTIFIED:in SIDE := RIGHT; FIELD:in WIDTH := 0) is |
variable s: string(1 to value'length); |
variable m: STD_ULOGIC_VECTOR(1 to value'length) := value; |
begin |
for i in 1 to value'length loop |
s(i) := MVL9_to_char(m(i)); |
end loop; |
write(l, s, justified, field); |
end WRITE; |
|
-- Read and Write procedures for STD_LOGIC_VECTOR |
procedure READ(L:inout LINE; VALUE:out STD_LOGIC_VECTOR) is |
variable tmp: STD_ULOGIC_VECTOR(VALUE'length-1 downto 0); |
begin |
READ(L, tmp); |
VALUE := STD_LOGIC_VECTOR(tmp); |
end READ; |
|
procedure READ(L:inout LINE; VALUE:out STD_LOGIC_VECTOR; GOOD: out BOOLEAN) is |
variable tmp: STD_ULOGIC_VECTOR(VALUE'length-1 downto 0); |
begin |
READ(L, tmp, GOOD); |
VALUE := STD_LOGIC_VECTOR(tmp); |
end READ; |
|
procedure WRITE(L:inout LINE; VALUE:in STD_LOGIC_VECTOR; |
JUSTIFIED:in SIDE := RIGHT; FIELD:in WIDTH := 0) is |
begin |
WRITE(L, STD_ULOGIC_VECTOR(VALUE), JUSTIFIED, FIELD); |
end WRITE; |
|
|
-- |
-- Hex Read and Write procedures. |
-- |
|
-- |
-- Hex, and Octal Read and Write procedures for BIT_VECTOR |
-- (these procedures are not exported, they are only used |
-- by the STD_ULOGIC hex/octal reads and writes below. |
-- |
-- |
|
procedure Char2QuadBits(C: Character; |
RESULT: out Bit_Vector(3 downto 0); |
GOOD: out Boolean; |
ISSUE_ERROR: in Boolean) is |
begin |
case c is |
when '0' => result := x"0"; good := TRUE; |
when '1' => result := x"1"; good := TRUE; |
when '2' => result := x"2"; good := TRUE; |
when '3' => result := x"3"; good := TRUE; |
when '4' => result := x"4"; good := TRUE; |
when '5' => result := x"5"; good := TRUE; |
when '6' => result := x"6"; good := TRUE; |
when '7' => result := x"7"; good := TRUE; |
when '8' => result := x"8"; good := TRUE; |
when '9' => result := x"9"; good := TRUE; |
when 'A' => result := x"A"; good := TRUE; |
when 'B' => result := x"B"; good := TRUE; |
when 'C' => result := x"C"; good := TRUE; |
when 'D' => result := x"D"; good := TRUE; |
when 'E' => result := x"E"; good := TRUE; |
when 'F' => result := x"F"; good := TRUE; |
|
when 'a' => result := x"A"; good := TRUE; |
when 'b' => result := x"B"; good := TRUE; |
when 'c' => result := x"C"; good := TRUE; |
when 'd' => result := x"D"; good := TRUE; |
when 'e' => result := x"E"; good := TRUE; |
when 'f' => result := x"F"; good := TRUE; |
when others => |
if ISSUE_ERROR then |
assert FALSE report |
"HREAD Error: Read a '" & c & |
"', expected a Hex character (0-F)."; |
end if; |
good := FALSE; |
end case; |
end; |
|
procedure HREAD(L:inout LINE; VALUE:out BIT_VECTOR) is |
variable ok: boolean; |
variable c: character; |
constant ne: integer := value'length/4; |
variable bv: bit_vector(0 to value'length-1); |
variable s: string(1 to ne-1); |
begin |
if value'length mod 4 /= 0 then |
assert FALSE report |
"HREAD Error: Trying to read vector " & |
"with an odd (non multiple of 4) length"; |
return; |
end if; |
|
loop -- skip white space |
read(l,c); |
exit when ((c /= ' ') and (c /= CR) and (c /= HT)); |
end loop; |
|
Char2QuadBits(c, bv(0 to 3), ok, TRUE); |
if not ok then |
return; |
end if; |
|
read(L, s, ok); |
if not ok then |
assert FALSE |
report "HREAD Error: Failed to read the STRING"; |
return; |
end if; |
|
for i in 1 to ne-1 loop |
Char2QuadBits(s(i), bv(4*i to 4*i+3), ok, TRUE); |
if not ok then |
return; |
end if; |
end loop; |
value := bv; |
end HREAD; |
|
procedure HREAD(L:inout LINE; VALUE:out BIT_VECTOR;GOOD: out BOOLEAN) is |
variable ok: boolean; |
variable c: character; |
constant ne: integer := value'length/4; |
variable bv: bit_vector(0 to value'length-1); |
variable s: string(1 to ne-1); |
begin |
if value'length mod 4 /= 0 then |
good := FALSE; |
return; |
end if; |
|
loop -- skip white space |
read(l,c); |
exit when ((c /= ' ') and (c /= CR) and (c /= HT)); |
end loop; |
|
Char2QuadBits(c, bv(0 to 3), ok, FALSE); |
if not ok then |
good := FALSE; |
return; |
end if; |
|
read(L, s, ok); |
if not ok then |
good := FALSE; |
return; |
end if; |
|
for i in 1 to ne-1 loop |
Char2QuadBits(s(i), bv(4*i to 4*i+3), ok, FALSE); |
if not ok then |
good := FALSE; |
return; |
end if; |
end loop; |
good := TRUE; |
value := bv; |
end HREAD; |
|
|
procedure HWRITE(L:inout LINE; VALUE:in BIT_VECTOR; |
JUSTIFIED:in SIDE := RIGHT; FIELD:in WIDTH := 0) is |
variable quad: bit_vector(0 to 3); |
constant ne: integer := value'length/4; |
variable bv: bit_vector(0 to value'length-1) := value; |
variable s: string(1 to ne); |
begin |
if value'length mod 4 /= 0 then |
assert FALSE report |
"HWRITE Error: Trying to read vector " & |
"with an odd (non multiple of 4) length"; |
return; |
end if; |
|
for i in 0 to ne-1 loop |
quad := bv(4*i to 4*i+3); |
case quad is |
when x"0" => s(i+1) := '0'; |
when x"1" => s(i+1) := '1'; |
when x"2" => s(i+1) := '2'; |
when x"3" => s(i+1) := '3'; |
when x"4" => s(i+1) := '4'; |
when x"5" => s(i+1) := '5'; |
when x"6" => s(i+1) := '6'; |
when x"7" => s(i+1) := '7'; |
when x"8" => s(i+1) := '8'; |
when x"9" => s(i+1) := '9'; |
when x"A" => s(i+1) := 'A'; |
when x"B" => s(i+1) := 'B'; |
when x"C" => s(i+1) := 'C'; |
when x"D" => s(i+1) := 'D'; |
when x"E" => s(i+1) := 'E'; |
when x"F" => s(i+1) := 'F'; |
end case; |
end loop; |
write(L, s, JUSTIFIED, FIELD); |
end HWRITE; |
|
procedure Char2TriBits(C: Character; |
RESULT: out bit_vector(2 downto 0); |
GOOD: out Boolean; |
ISSUE_ERROR: in Boolean) is |
begin |
case c is |
when '0' => result := o"0"; good := TRUE; |
when '1' => result := o"1"; good := TRUE; |
when '2' => result := o"2"; good := TRUE; |
when '3' => result := o"3"; good := TRUE; |
when '4' => result := o"4"; good := TRUE; |
when '5' => result := o"5"; good := TRUE; |
when '6' => result := o"6"; good := TRUE; |
when '7' => result := o"7"; good := TRUE; |
when others => |
if ISSUE_ERROR then |
assert FALSE report |
"OREAD Error: Read a '" & c & |
"', expected an Octal character (0-7)."; |
end if; |
good := FALSE; |
end case; |
end; |
|
procedure OREAD(L:inout LINE; VALUE:out BIT_VECTOR) is |
variable c: character; |
variable ok: boolean; |
constant ne: integer := value'length/3; |
variable bv: bit_vector(0 to value'length-1); |
variable s: string(1 to ne-1); |
begin |
if value'length mod 3 /= 0 then |
assert FALSE report |
"OREAD Error: Trying to read vector " & |
"with an odd (non multiple of 3) length"; |
return; |
end if; |
|
loop -- skip white space |
read(l,c); |
exit when ((c /= ' ') and (c /= CR) and (c /= HT)); |
end loop; |
|
Char2TriBits(c, bv(0 to 2), ok, TRUE); |
if not ok then |
return; |
end if; |
|
read(L, s, ok); |
if not ok then |
assert FALSE |
report "OREAD Error: Failed to read the STRING"; |
return; |
end if; |
|
for i in 1 to ne-1 loop |
Char2TriBits(s(i), bv(3*i to 3*i+2), ok, TRUE); |
if not ok then |
return; |
end if; |
end loop; |
value := bv; |
end OREAD; |
|
procedure OREAD(L:inout LINE; VALUE:out BIT_VECTOR;GOOD: out BOOLEAN) is |
variable ok: boolean; |
variable c: character; |
constant ne: integer := value'length/3; |
variable bv: bit_vector(0 to value'length-1); |
variable s: string(1 to ne-1); |
begin |
if value'length mod 3 /= 0 then |
good := FALSE; |
return; |
end if; |
|
loop -- skip white space |
read(l,c); |
exit when ((c /= ' ') and (c /= CR) and (c /= HT)); |
end loop; |
|
Char2TriBits(c, bv(0 to 2), ok, FALSE); |
if not ok then |
good := FALSE; |
return; |
end if; |
|
read(L, s, ok); |
if not ok then |
good := FALSE; |
return; |
end if; |
|
for i in 1 to ne-1 loop |
Char2TriBits(s(i), bv(3*i to 3*i+2), ok, FALSE); |
if not ok then |
good := FALSE; |
return; |
end if; |
end loop; |
good := TRUE; |
value := bv; |
end OREAD; |
|
|
procedure OWRITE(L:inout LINE; VALUE:in BIT_VECTOR; |
JUSTIFIED:in SIDE := RIGHT; FIELD:in WIDTH := 0) is |
variable tri: bit_vector(0 to 2); |
constant ne: integer := value'length/3; |
variable bv: bit_vector(0 to value'length-1) := value; |
variable s: string(1 to ne); |
begin |
if value'length mod 3 /= 0 then |
assert FALSE report |
"OWRITE Error: Trying to read vector " & |
"with an odd (non multiple of 3) length"; |
return; |
end if; |
|
for i in 0 to ne-1 loop |
tri := bv(3*i to 3*i+2); |
case tri is |
when o"0" => s(i+1) := '0'; |
when o"1" => s(i+1) := '1'; |
when o"2" => s(i+1) := '2'; |
when o"3" => s(i+1) := '3'; |
when o"4" => s(i+1) := '4'; |
when o"5" => s(i+1) := '5'; |
when o"6" => s(i+1) := '6'; |
when o"7" => s(i+1) := '7'; |
end case; |
end loop; |
write(L, s, JUSTIFIED, FIELD); |
end OWRITE; |
|
-- Hex Read and Write procedures for STD_LOGIC_VECTOR |
procedure HREAD(L:inout LINE; VALUE:out STD_ULOGIC_VECTOR;GOOD:out BOOLEAN) is |
variable tmp: bit_vector(VALUE'length-1 downto 0); |
begin |
HREAD(L, tmp, GOOD); |
VALUE := To_X01(tmp); |
end HREAD; |
|
procedure HREAD(L:inout LINE; VALUE:out STD_ULOGIC_VECTOR) is |
variable tmp: bit_vector(VALUE'length-1 downto 0); |
begin |
HREAD(L, tmp); |
VALUE := To_X01(tmp); |
end HREAD; |
|
procedure HWRITE(L:inout LINE; VALUE:in STD_ULOGIC_VECTOR; |
JUSTIFIED:in SIDE := RIGHT; FIELD:in WIDTH := 0) is |
begin |
HWRITE(L, To_bitvector(VALUE),JUSTIFIED, FIELD); |
end HWRITE; |
|
-- Hex Read and Write procedures for STD_LOGIC_VECTOR |
|
procedure HREAD(L:inout LINE; VALUE:out STD_LOGIC_VECTOR) is |
variable tmp: STD_ULOGIC_VECTOR(VALUE'length-1 downto 0); |
begin |
HREAD(L, tmp); |
VALUE := STD_LOGIC_VECTOR(tmp); |
end HREAD; |
|
procedure HREAD(L:inout LINE; VALUE:out STD_LOGIC_VECTOR; GOOD: out BOOLEAN) is |
variable tmp: STD_ULOGIC_VECTOR(VALUE'length-1 downto 0); |
begin |
HREAD(L, tmp, GOOD); |
VALUE := STD_LOGIC_VECTOR(tmp); |
end HREAD; |
|
procedure HWRITE(L:inout LINE; VALUE:in STD_LOGIC_VECTOR; |
JUSTIFIED:in SIDE := RIGHT; FIELD:in WIDTH := 0) is |
begin |
HWRITE(L, To_bitvector(VALUE), JUSTIFIED, FIELD); |
end HWRITE; |
|
|
-- Octal Read and Write procedures for STD_ULOGIC_VECTOR |
procedure OREAD(L:inout LINE; VALUE:out STD_ULOGIC_VECTOR;GOOD:out BOOLEAN) is |
variable tmp: bit_vector(VALUE'length-1 downto 0); |
begin |
OREAD(L, tmp, GOOD); |
VALUE := To_X01(tmp); |
end OREAD; |
|
procedure OREAD(L:inout LINE; VALUE:out STD_ULOGIC_VECTOR) is |
variable tmp: bit_vector(VALUE'length-1 downto 0); |
begin |
OREAD(L, tmp); |
VALUE := To_X01(tmp); |
end OREAD; |
|
procedure OWRITE(L:inout LINE; VALUE:in STD_ULOGIC_VECTOR; |
JUSTIFIED:in SIDE := RIGHT; FIELD:in WIDTH := 0) is |
begin |
OWRITE(L, To_bitvector(VALUE),JUSTIFIED, FIELD); |
end OWRITE; |
|
-- Octal Read and Write procedures for STD_LOGIC_VECTOR |
|
procedure OREAD(L:inout LINE; VALUE:out STD_LOGIC_VECTOR) is |
variable tmp: STD_ULOGIC_VECTOR(VALUE'length-1 downto 0); |
begin |
OREAD(L, tmp); |
VALUE := STD_LOGIC_VECTOR(tmp); |
end OREAD; |
|
procedure OREAD(L:inout LINE; VALUE:out STD_LOGIC_VECTOR; GOOD: out BOOLEAN) is |
variable tmp: STD_ULOGIC_VECTOR(VALUE'length-1 downto 0); |
begin |
OREAD(L, tmp, GOOD); |
VALUE := STD_LOGIC_VECTOR(tmp); |
end OREAD; |
|
procedure OWRITE(L:inout LINE; VALUE:in STD_LOGIC_VECTOR; |
JUSTIFIED:in SIDE := RIGHT; FIELD:in WIDTH := 0) is |
begin |
OWRITE(L, STD_ULOGIC_VECTOR(VALUE), JUSTIFIED, FIELD); |
end OWRITE; |
|
|
--synopsys synthesis_on |
end STD_LOGIC_TEXTIO; |
/tags/start_version/rtl/vhdl/core/stepping_logic.vhd
0,0 → 1,156
------------------------------------------------------------------------------------ |
-- |
-- Geoffrey Ottoy - DraMCo research group |
-- |
-- Module Name: stepping_logic.vhd / entity stepping_logic |
-- |
-- Last Modified: 23/01/2012 |
-- |
-- Description: stepping logic for the pipelined montgomery multiplier |
-- |
-- |
-- Dependencies: counter_sync |
-- |
-- Revision: |
-- Revision 5.01 - defined integer range for t_sel and n_sel resulting in less LUTs |
-- Revision 5.00 - made the reset value changeable in runtime |
-- Revision 4.01 - Delayed ready pulse with 1 clk cylce. This delay is necessary |
-- for the reduction to complete. |
-- Revision 4.00 - Changed design to fit new pipeline-architecture |
-- (i.e. 1 clock cycle / stage) |
-- Revision 3.00 - Removed second delay on next_x |
-- Revision 2.00 - Changed operation to give a pulse on stepping_done when pipeline |
-- operation has finished |
-- Revision 1.00 - Architecture |
-- Revision 0.01 - File Created |
-- |
-- |
------------------------------------------------------------------------------------ |
-- |
-- NOTICE: |
-- |
-- Copyright DraMCo research group. 2011. This code may be contain portions patented |
-- by other third parties! |
-- |
------------------------------------------------------------------------------------ |
library IEEE; |
use IEEE.STD_LOGIC_1164.ALL; |
use IEEE.STD_LOGIC_ARITH.ALL; |
use IEEE.STD_LOGIC_UNSIGNED.ALL; |
|
---- Uncomment the following library declaration if instantiating |
---- any Xilinx primitives in this code. |
--library UNISIM; |
--use UNISIM.VComponents.all; |
|
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; |
start : in STD_LOGIC; |
reset : in STD_LOGIC; |
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 required for a complete multiplication |
start_first_stage : out STD_LOGIC; |
stepping_done : out STD_LOGIC |
); |
end stepping_logic; |
|
architecture Behavioral of stepping_logic is |
component d_flip_flop |
port(core_clk : in STD_LOGIC; |
reset : in STD_LOGIC; |
din : in STD_LOGIC; |
dout : out STD_LOGIC |
); |
end component; |
|
component counter_sync |
generic(max_value : integer := 16 |
); |
port(reset_value : in integer; |
core_clk : in STD_LOGIC; |
ce : in STD_LOGIC; |
reset : in STD_LOGIC; |
overflow : out STD_LOGIC |
); |
end component; |
|
signal laststeps_in_i : std_logic := '0'; |
signal laststeps_out_i : std_logic := '0'; |
signal start_stop_in_i : std_logic := '0'; |
signal start_stop_out_i : std_logic := '0'; |
signal steps_in_i : std_logic := '0'; |
signal steps_out_i : std_logic := '0'; |
signal substeps_in_i : std_logic := '0'; |
signal substeps_out_i : std_logic := '0'; |
signal done_reg_in_i : std_logic := '0'; |
signal done_reg_out_i : std_logic := '0'; |
signal start_first_stage_i : std_logic := '0'; |
signal start_i : std_logic := '0'; |
|
begin |
start_i <= start; |
|
-- map outputs |
start_first_stage <= start_first_stage_i; |
stepping_done <= laststeps_out_i; |
|
-- internal signals |
start_stop_in_i <= start_i or (start_stop_out_i and not steps_out_i); |
substeps_in_i <= start_stop_in_i; |
steps_in_i <= substeps_out_i; |
done_reg_in_i <= steps_out_i or (done_reg_out_i and not laststeps_out_i); |
laststeps_in_i <= done_reg_in_i; |
start_first_stage_i <= start_i or steps_in_i; |
--start_first_stage_i <= steps_in_i; |
|
done_reg: d_flip_flop |
port map(core_clk => core_clk, |
reset => reset, |
din => done_reg_in_i, |
dout => done_reg_out_i |
); |
|
start_stop_reg: d_flip_flop |
port map(core_clk => core_clk, |
reset => reset, |
din => start_stop_in_i, |
dout => start_stop_out_i |
); |
|
-- for counting the last steps |
laststeps_counter: counter_sync |
generic map(max_value => t |
) |
port map(reset_value => t_sel, |
core_clk => core_clk, |
ce => laststeps_in_i, |
reset => reset, |
overflow => laststeps_out_i |
); |
|
-- counter for keeping track of the steps |
steps_counter: counter_sync |
generic map(max_value => n |
) |
port map(reset_value => (n_sel), |
core_clk => core_clk, |
ce => steps_in_i, |
reset => reset, |
overflow => steps_out_i |
); |
|
-- makes sure we don't start too early with a new step |
substeps_counter: counter_sync |
generic map(max_value => 2 |
) |
port map(reset_value => 2, |
core_clk => core_clk, |
ce => substeps_in_i, |
reset => reset, |
overflow => substeps_out_i |
); |
|
end Behavioral; |
/tags/start_version/rtl/vhdl/core/register_1b.vhd
0,0 → 1,63
------------------------------------------------------------------------------------ |
-- |
-- Geoffrey Ottoy - DraMCo research group |
-- |
-- Module Name: register_1b.vhd / entity register_1b |
-- |
-- Last Modified: 24/11/2011 |
-- |
-- Description: 1 bit register |
-- |
-- |
-- Dependencies: LDCE |
-- |
-- Revision: |
-- Revision 1.00 - Architecture |
-- Revision 0.01 - File Created |
-- |
-- |
------------------------------------------------------------------------------------ |
-- |
-- NOTICE: |
-- |
-- Copyright DraMCo research group. 2011. This code may be contain portions patented |
-- by other third parties! |
-- |
------------------------------------------------------------------------------------ |
library IEEE; |
use IEEE.STD_LOGIC_1164.ALL; |
use IEEE.STD_LOGIC_ARITH.ALL; |
use IEEE.STD_LOGIC_UNSIGNED.ALL; |
|
---- Uncomment the following library declaration if instantiating |
---- any Xilinx primitives in this code. |
library UNISIM; |
use UNISIM.VComponents.all; |
|
entity register_1b is |
port(core_clk : in STD_LOGIC; |
ce : in STD_LOGIC; |
reset : in STD_LOGIC; |
din : in STD_LOGIC; |
dout : out STD_LOGIC |
); |
end register_1b; |
|
architecture Structural of register_1b is |
signal dout_i : std_logic; |
begin |
|
dout <= dout_i; |
|
FDCE_inst : FDCE |
generic map ( |
INIT => '0') -- Initial value of latch ('0' or '1') |
port map ( |
Q => dout_i, -- Data output |
CLR => reset, -- Asynchronous clear/reset input |
D => din, -- Data input |
C => core_clk, -- Gate input |
CE => ce -- Gate enable input |
); |
|
end Structural; |
/tags/start_version/rtl/vhdl/core/standard_cell_block.vhd
0,0 → 1,84
------------------------------------------------------------------------------------ |
-- |
-- Geoffrey Ottoy - DraMCo research group |
-- |
-- Module Name: standard_cell_block.vhd / entity standard_cell_block |
-- |
-- Last Modified: 14/11/2011 |
-- |
-- Description: cell_block for use in the montgommery multiplier systolic array |
-- |
-- |
-- Dependencies: none |
-- |
-- Revision: |
-- Revision 1.00 - Architecture |
-- Revision 0.01 - File Created |
-- |
-- |
------------------------------------------------------------------------------------ |
-- |
-- NOTICE: |
-- |
-- Copyright DraMCo research group. 2011. This code may be contain portions patented |
-- by other third parties! |
-- |
------------------------------------------------------------------------------------ |
library IEEE; |
use IEEE.STD_LOGIC_1164.ALL; |
use IEEE.STD_LOGIC_ARITH.ALL; |
use IEEE.STD_LOGIC_UNSIGNED.ALL; |
|
---- Uncomment the following library declaration if instantiating |
---- any Xilinx primitives in this code. |
--library UNISIM; |
--use UNISIM.VComponents.all; |
|
entity standard_cell_block is |
generic ( width : integer := 16 |
); |
Port ( 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); |
x : in STD_LOGIC; |
q : in STD_LOGIC; |
a : in STD_LOGIC_VECTOR((width-1) downto 0); |
cin : in STD_LOGIC; |
cout : out STD_LOGIC; |
r : out STD_LOGIC_VECTOR((width-1) downto 0)); |
end standard_cell_block; |
|
architecture Structural of standard_cell_block is |
component cell_1b |
Port ( my : in STD_LOGIC; |
y : in STD_LOGIC; |
m : in STD_LOGIC; |
x : in STD_LOGIC; |
q : in STD_LOGIC; |
a : in STD_LOGIC; |
cin : in STD_LOGIC; |
cout : out STD_LOGIC; |
r : out STD_LOGIC); |
end component; |
|
signal carry : std_logic_vector(width downto 0); |
begin |
|
carry(0) <= cin; |
|
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; |
|
cout <= carry(width); |
end Structural; |
/tags/start_version/rtl/vhdl/core/first_stage.vhd
0,0 → 1,271
------------------------------------------------------------------------------------ |
-- |
-- Geoffrey Ottoy - DraMCo research group |
-- |
-- Module Name: first_stage.vhd / entity first_stage |
-- |
-- Last Modified: 24/11/2011 |
-- |
-- Description: first stage for use in the montgommery multiplier systolic |
-- array pipeline |
-- |
-- |
-- Dependencies: standard_cell_block |
-- cell_mux_1b |
-- register_n, |
-- register_1b, |
-- d_flip_flop |
-- |
-- Revision: |
-- Revision 4.00 - Removed input registers and used start signal as load_out_regs |
-- Revision 3.00 - Removed "a" input and replaced with "a_msb" (which is the only one |
-- that matters. |
-- Revision 2.02 - removed "ready" output signal |
-- Revision 2.01 - replaced the behavioral description of the registers with a |
-- component instantiation |
-- Revision 2.00 - added register to store input value xin (because this |
-- can change during operation) |
-- Revision 1.03 - added done pulse |
-- Revision 1.02 - appended "_i" to name of all internal signals |
-- Revision 1.01 - ready is '1' after reset |
-- Revision 1.00 - Architecture |
-- Revision 0.01 - File Created |
-- |
-- |
------------------------------------------------------------------------------------ |
-- |
-- NOTICE: |
-- |
-- Copyright DraMCo research group. 2011. This code may be contain portions patented |
-- by other third parties! |
-- |
------------------------------------------------------------------------------------ |
library IEEE; |
use IEEE.STD_LOGIC_1164.ALL; |
use IEEE.STD_LOGIC_ARITH.ALL; |
use IEEE.STD_LOGIC_UNSIGNED.ALL; |
|
---- Uncomment the following library declaration if instantiating |
---- any Xilinx primitives in this code. |
--library UNISIM; |
--use UNISIM.VComponents.all; |
|
entity first_stage is |
generic(width : integer := 16 -- must be the same as width of the standard stage |
); |
port(core_clk : in STD_LOGIC; |
my : in STD_LOGIC_VECTOR((width) downto 0); |
y : in STD_LOGIC_VECTOR((width) downto 0); |
m : in STD_LOGIC_VECTOR((width) downto 0); |
xin : in STD_LOGIC; |
xout : out STD_LOGIC; |
qout : out STD_LOGIC; |
a_msb : in STD_LOGIC; |
cout : out STD_LOGIC; |
start : in STD_LOGIC; |
reset : in STD_LOGIC; |
-- ready : out STD_LOGIC; |
done : out STD_LOGIC; |
r : out STD_LOGIC_VECTOR((width-1) downto 0) |
); |
end first_stage; |
|
architecture Structural of first_stage is |
|
component d_flip_flop |
port(core_clk : in STD_LOGIC; |
reset : in STD_LOGIC; |
din : in STD_LOGIC; |
dout : out STD_LOGIC |
); |
end component; |
|
component register_1b |
port(core_clk : in STD_LOGIC; |
ce : in STD_LOGIC; |
reset : in STD_LOGIC; |
din : in STD_LOGIC; |
dout : out STD_LOGIC |
); |
end component; |
|
component register_n |
generic( n : integer := 4 |
); |
port(core_clk : in STD_LOGIC; |
ce : in STD_LOGIC; |
reset : in STD_LOGIC; |
din : in STD_LOGIC_VECTOR((n-1) downto 0); |
dout : out STD_LOGIC_VECTOR((n-1) downto 0) |
); |
end component; |
|
component standard_cell_block |
generic ( width : integer := 32 |
); |
Port ( 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); |
x : in STD_LOGIC; |
q : in STD_LOGIC; |
a : in STD_LOGIC_VECTOR((width-1) downto 0); |
cin : in STD_LOGIC; |
cout : out STD_LOGIC; |
r : out STD_LOGIC_VECTOR((width-1) downto 0)); |
end component; |
|
component cell_1b_mux |
port ( my : in STD_LOGIC; |
y : in STD_LOGIC; |
m : in STD_LOGIC; |
x : in STD_LOGIC; |
q : in STD_LOGIC; |
result : out STD_LOGIC); |
end component; |
|
-- input |
signal xin_i : std_logic; |
signal a_msb_i : std_logic; |
-- signal xin_reg_i : std_logic; |
-- signal a_msb_reg_i : std_logic; |
|
-- output |
signal cout_i : std_logic; |
signal r_i : std_logic_vector((width-1) downto 0); |
signal cout_reg_i : std_logic; |
signal xout_reg_i : std_logic; |
signal qout_reg_i : std_logic; |
signal r_reg_i : std_logic_vector((width-1) downto 0); |
|
-- interconnection |
signal q_i : std_logic; |
signal c_i : std_logic; |
signal first_res_i : std_logic; |
signal a_i : std_logic_vector((width) downto 0); |
|
-- control signals |
signal done_i : std_logic := '1'; |
--signal ready_del_i : std_logic := '1'; |
-- signal load_out_regs_i : std_logic; |
begin |
|
-- map inputs to internal signals |
xin_i <= xin; |
a_msb_i <= a_msb; |
|
-- map internal signals to outputs |
done <= done_i; |
r <= r_reg_i; |
cout <= cout_reg_i; |
qout <= qout_reg_i; |
xout <= xout_reg_i; |
-- two posibilities: |
--done <= ready_i and (not ready_del_i); -- slow |
--done <= not ready_i; -- faster but not sure if it will work (DONE_PROC can be omitted) |
|
-- a_i <= a_msb_reg_i & r_reg_i; |
a_i <= a_msb_i & r_reg_i; |
|
-- -- input registers |
-- A_REG: register_1b |
-- port map(core_clk => core_clk, |
-- ce => start, |
-- reset => reset, |
-- din => a_msb_i, |
-- dout => a_msb_reg_i |
-- ); |
-- |
-- XIN_REG: register_1b |
-- port map(core_clk => core_clk, |
-- ce => start, |
-- reset => reset, |
-- din => xin_i, |
-- dout => xin_reg_i |
-- ); |
|
-- compute first q_i and carry |
-- q_i <= a_i(0) xor (y(0) and xin_reg_i); |
q_i <= a_i(0) xor (y(0) and xin_i); |
c_i <= a_i(0) and first_res_i; |
|
first_cell: cell_1b_mux |
port map( my => my(0), |
y => y(0), |
m => m(0), |
-- x => xin_reg_i, |
x => xin_i, |
q => q_i, |
result => first_res_i |
); |
|
cell_block: standard_cell_block |
generic map( width => width |
) |
port map( my => my(width downto 1), |
y => y(width downto 1), |
m => m(width downto 1), |
-- x => xin_reg_i, |
x => xin_i, |
q => q_i, |
a => a_i(width downto 1), |
cin => c_i, |
cout => cout_i, |
r => r_i((width-1) downto 0) |
); |
|
-- delay_1_cycle: d_flip_flop |
-- port map(core_clk => core_clk, |
-- reset => reset, |
-- din => start, |
-- dout => load_out_regs_i |
-- ); |
|
done_signal: d_flip_flop |
port map(core_clk => core_clk, |
reset => reset, |
-- din => load_out_regs_i, |
din => start, |
dout => done_i |
); |
|
-- output registers |
RESULT_REG: register_n |
generic map( n => width |
) |
port map(core_clk => core_clk, |
-- ce => load_out_regs_i, |
ce => start, |
reset => reset, |
din => r_i, |
dout => r_reg_i |
); |
|
XOUT_REG: register_1b |
port map(core_clk => core_clk, |
-- ce => load_out_regs_i, |
ce => start, |
reset => reset, |
-- din => xin_reg_i, |
din => xin_i, |
dout => xout_reg_i |
); |
|
QOUT_REG: register_1b |
port map(core_clk => core_clk, |
-- ce => load_out_regs_i, |
ce => start, |
reset => reset, |
din => q_i, |
dout => qout_reg_i |
); |
|
COUT_REG: register_1b |
port map(core_clk => core_clk, |
-- ce => load_out_regs_i, |
ce => start, |
reset => reset, |
din => cout_i, |
dout => cout_reg_i |
); |
|
end Structural; |
/tags/start_version/rtl/vhdl/core/fifo_primitive.vhd
0,0 → 1,124
------------------------------------------------------------------------------------ |
-- |
-- Geoffrey Ottoy - DraMCo research group |
-- |
-- Module Name: adder_n.vhd / entity adder_n |
-- |
-- Last Modified: 04/04/2012 |
-- |
-- Description: 512x32-bit fifo |
-- |
-- |
-- Dependencies: FIFO18E1 primitive |
-- |
-- Revision: |
-- Revision 1.00 - Architecture |
-- Revision 0.01 - File Created |
-- |
-- |
------------------------------------------------------------------------------------ |
-- |
-- NOTICE: |
-- |
-- Copyright DraMCo research group. 2011. This code may be contain portions patented |
-- by other third parties! |
-- |
------------------------------------------------------------------------------------ |
library IEEE; |
use IEEE.STD_LOGIC_1164.ALL; |
use IEEE.STD_LOGIC_ARITH.ALL; |
use IEEE.STD_LOGIC_UNSIGNED.ALL; |
|
---- Uncomment the following library declaration if instantiating |
---- any Xilinx primitives 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; |
|
/tags/start_version/rtl/vhdl/core/counter_sync.vhd
0,0 → 1,79
------------------------------------------------------------------------------------ |
-- |
-- Geoffrey Ottoy - DraMCo research group |
-- |
-- Module Name: counter_sync.vhd / entity counter_sync |
-- |
-- Last Modified: 23/01/2012 |
-- |
-- Description: counter with synchronous count enable. It generates an |
-- overflow when max_value is reached |
-- |
-- |
-- Dependencies: none |
-- |
-- Revision: |
-- Revision 2.00 - moved max_value from generic to port so it is changeable in runtime |
-- Revision 1.00 - Architecture |
-- Revision 0.01 - File Created |
-- |
-- |
------------------------------------------------------------------------------------ |
-- |
-- NOTICE: |
-- |
-- Copyright DraMCo research group. 2011. This code may be contain portions patented |
-- by other third parties! |
-- |
------------------------------------------------------------------------------------ |
library IEEE; |
use IEEE.STD_LOGIC_1164.ALL; |
use IEEE.STD_LOGIC_ARITH.ALL; |
use IEEE.STD_LOGIC_UNSIGNED.ALL; |
|
---- Uncomment the following library declaration if instantiating |
---- any Xilinx primitives in this code. |
--library UNISIM; |
--use UNISIM.VComponents.all; |
|
entity counter_sync is |
generic(max_value : integer := 1024 |
); |
port(reset_value : in integer; |
core_clk : in STD_LOGIC; |
ce : in STD_LOGIC; |
reset : in STD_LOGIC; |
overflow : out STD_LOGIC |
); |
end counter_sync; |
|
architecture Behavioral of counter_sync is |
|
signal overflow_i : std_logic := '0'; |
begin |
|
overflow <= overflow_i; |
|
COUNT_PROC: process(core_clk, ce, reset) |
variable steps_counter : integer range 0 to max_value-1 := 0; |
begin |
if reset = '1' then -- reset counter |
steps_counter := 0; |
overflow_i <= '0'; |
elsif rising_edge(core_clk) then |
if ce = '1' then -- count |
if steps_counter = (reset_value-1) then -- generate overflow and reset counter |
steps_counter := 0; |
overflow_i <= '1'; |
else -- just count |
steps_counter := steps_counter + 1; |
overflow_i <= '0'; |
end if; |
else |
overflow_i <= '0'; |
steps_counter := steps_counter; |
end if; |
end if; |
end process; |
|
end Behavioral; |
/tags/start_version/rtl/vhdl/core/operand_dp.vhd
0,0 → 1,144
-------------------------------------------------------------------------------- |
-- 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; |
|
/tags/start_version/rtl/vhdl/core/operands_sp.vhd
0,0 → 1,129
-------------------------------------------------------------------------------- |
-- 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 operands_sp.vhd when simulating |
-- the core, operands_sp. 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; |
|
/tags/start_version/rtl/vhdl/core/d_flip_flop.vhd
0,0 → 1,62
------------------------------------------------------------------------------------ |
-- |
-- Geoffrey Ottoy - DraMCo research group |
-- |
-- Module Name: d_flip_flop.vhd / entity d_flip_flop |
-- |
-- Last Modified: 24/11/2011 |
-- |
-- Description: 1 bit D flip-flop |
-- |
-- |
-- Dependencies: LDCE |
-- |
-- Revision: |
-- Revision 1.00 - Architecture |
-- Revision 0.01 - File Created |
-- |
-- |
------------------------------------------------------------------------------------ |
-- |
-- NOTICE: |
-- |
-- Copyright DraMCo research group. 2011. This code may be contain portions patented |
-- by other third parties! |
-- |
------------------------------------------------------------------------------------ |
library IEEE; |
use IEEE.STD_LOGIC_1164.ALL; |
use IEEE.STD_LOGIC_ARITH.ALL; |
use IEEE.STD_LOGIC_UNSIGNED.ALL; |
|
---- Uncomment the following library declaration if instantiating |
---- any Xilinx primitives in this code. |
library UNISIM; |
use UNISIM.VComponents.all; |
|
entity d_flip_flop is |
port(core_clk : in STD_LOGIC; |
reset : in STD_LOGIC; |
din : in STD_LOGIC; |
dout : out STD_LOGIC |
); |
end d_flip_flop; |
|
architecture Structural of d_flip_flop is |
signal dout_i : std_logic; |
begin |
|
dout <= dout_i; |
|
FDCE_inst : FDCE |
generic map ( |
INIT => '0') -- Initial value of latch ('0' or '1') |
port map ( |
Q => dout_i, -- Data output |
CLR => reset, -- Asynchronous clear/reset input |
D => din, -- Data input |
C => core_clk, -- Gate input |
CE => '1' -- Gate enable input |
); |
|
end Structural; |
/tags/start_version/rtl/vhdl/core/standard_stage.vhd
0,0 → 1,268
------------------------------------------------------------------------------------ |
-- |
-- Geoffrey Ottoy - DraMCo research group |
-- |
-- Module Name: standard_stage.vhd / entity standard_stage |
-- |
-- Last Modified: 24/11/2011 |
-- |
-- Description: standard stage for use in the montgommery multiplier systolic |
-- array pipeline |
-- |
-- |
-- Dependencies: standard_cell_block, |
-- register_n, |
-- register_1b, |
-- d_flip_flop |
-- |
-- Revision: |
-- Revision 4.00 - Removed input registers and used start signal as load_out_regs |
-- Revision 3.00 - Removed "a" input and replaced with "a_msb" (which is the only one |
-- that matters. |
-- Revision 2.02 - removed "ready" output signal |
-- Revision 2.01 - replaced the behavioral description of the registers with a |
-- component instantiation |
-- Revision 2.00 - added registers to store input values xin, cin, qin (because they |
-- can change during operation) |
-- Revision 1.03 - added done pulse |
-- Revision 1.02 - appended "_i" to name of all internal signals |
-- Revision 1.01 - ready is '1' after reset |
-- Revision 1.00 - Architecture |
-- Revision 0.01 - File Created |
-- |
-- |
------------------------------------------------------------------------------------ |
-- |
-- NOTICE: |
-- |
-- Copyright DraMCo research group. 2011. This code may be contain portions patented |
-- by other third parties! |
-- |
------------------------------------------------------------------------------------ |
library IEEE; |
use IEEE.STD_LOGIC_1164.ALL; |
use IEEE.STD_LOGIC_ARITH.ALL; |
use IEEE.STD_LOGIC_UNSIGNED.ALL; |
|
---- Uncomment the following library declaration if instantiating |
---- any Xilinx primitives in this code. |
--library UNISIM; |
--use UNISIM.VComponents.all; |
|
entity standard_stage is |
generic(width : integer := 32 |
); |
port(core_clk : in STD_LOGIC; |
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); |
xin : in STD_LOGIC; |
qin : in STD_LOGIC; |
xout : out STD_LOGIC; |
qout : out STD_LOGIC; |
a_msb : in STD_LOGIC; |
cin : in STD_LOGIC; |
cout : out STD_LOGIC; |
start : in STD_LOGIC; |
reset : in STD_LOGIC; |
-- ready : out STD_LOGIC; |
done : out STD_LOGIC; |
r : out STD_LOGIC_VECTOR((width-1) downto 0) |
); |
end standard_stage; |
|
architecture Structural of standard_stage is |
component d_flip_flop |
port(core_clk : in STD_LOGIC; |
reset : in STD_LOGIC; |
din : in STD_LOGIC; |
dout : out STD_LOGIC |
); |
end component; |
|
component register_1b |
port(core_clk : in STD_LOGIC; |
ce : in STD_LOGIC; |
reset : in STD_LOGIC; |
din : in STD_LOGIC; |
dout : out STD_LOGIC |
); |
end component; |
|
component register_n |
generic( n : integer := 4 |
); |
port(core_clk : in STD_LOGIC; |
ce : in STD_LOGIC; |
reset : in STD_LOGIC; |
din : in STD_LOGIC_VECTOR((n-1) downto 0); |
dout : out STD_LOGIC_VECTOR((n-1) downto 0) |
); |
end component; |
|
component standard_cell_block |
generic ( width : integer := 32 |
); |
Port ( 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); |
x : in STD_LOGIC; |
q : in STD_LOGIC; |
a : in STD_LOGIC_VECTOR((width-1) downto 0); |
cin : in STD_LOGIC; |
cout : out STD_LOGIC; |
r : out STD_LOGIC_VECTOR((width-1) downto 0)); |
end component; |
|
-- input |
signal cin_i : std_logic; |
signal xin_i : std_logic; |
signal qin_i : std_logic; |
signal a_msb_i : std_logic; |
-- signal cin_reg_i : std_logic; |
-- signal xin_reg_i : std_logic; |
-- signal qin_reg_i : std_logic; |
-- signal a_msb_reg_i : std_logic; |
|
-- output |
signal cout_i : std_logic; |
signal r_i : std_logic_vector((width-1) downto 0); |
signal cout_reg_i : std_logic; |
signal xout_reg_i : std_logic; |
signal qout_reg_i : std_logic; |
signal r_reg_i : std_logic_vector((width-1) downto 0); |
|
-- interconnect |
signal a_i : std_logic_vector((width-1) downto 0); |
|
-- control |
-- signal load_out_regs_i : std_logic; |
signal done_i : std_logic := '1'; |
--signal ready_del_i : std_logic := '1'; |
begin |
-- map internal signals to outputs |
done <= done_i; |
r <= r_reg_i; |
cout <= cout_reg_i; |
qout <= qout_reg_i; |
xout <= xout_reg_i; |
-- two posibilities: |
--done <= ready_i and (not ready_del_i); -- slow |
--done <= not ready_i; -- faster but not sure if it will work (DONE_PROC can be omitted) |
|
-- map inputs to internal signals |
xin_i <= xin; |
qin_i <= qin; |
cin_i <= cin; |
a_msb_i <= a_msb; |
|
-- a_i <= a_msb_reg_i & r_reg_i((width-1) downto 1); |
a_i <= a_msb_i & r_reg_i((width-1) downto 1); |
|
-- input registers |
-- A_REG: register_1b |
-- port map(core_clk => core_clk, |
-- ce => start, |
-- reset => reset, |
-- din => a_msb_i, |
-- dout => a_msb_reg_i |
-- ); |
|
-- XIN_REG: register_1b |
-- port map(core_clk => core_clk, |
-- ce => start, |
-- reset => reset, |
-- din => xin_i, |
-- dout => xin_reg_i |
-- ); |
|
-- QIN_REG: register_1b |
-- port map(core_clk => core_clk, |
-- ce => start, |
-- reset => reset, |
-- din => qin_i, |
-- dout => qin_reg_i |
-- ); |
|
-- CIN_REG: register_1b |
-- port map(core_clk => core_clk, |
-- ce => start, |
-- reset => reset, |
-- din => cin_i, |
-- dout => cin_reg_i |
-- ); |
|
cell_block: standard_cell_block |
generic map( width => width |
) |
Port map( my => my, |
y => y, |
m => m, |
-- x => xin_reg_i, |
-- q => qin_reg_i, |
x => xin_i, |
q => qin_i, |
a => a_i, |
-- cin => cin_reg_i, |
cin => cin_i, |
cout => cout_i, |
r => r_i |
); |
|
-- delay_1_cycle: d_flip_flop |
-- port map(core_clk => core_clk, |
-- reset => reset, |
-- din => start, |
-- dout => load_out_regs_i |
-- ); |
|
done_signal: d_flip_flop |
port map(core_clk => core_clk, |
reset => reset, |
-- din => load_out_regs_i, |
din => start, |
dout => done_i |
); |
|
-- output registers |
RESULT_REG: register_n |
generic map( n => width |
) |
port map(core_clk => core_clk, |
-- ce => load_out_regs_i, |
ce => start, |
reset => reset, |
din => r_i, |
dout => r_reg_i |
); |
|
XOUT_REG: register_1b |
port map(core_clk => core_clk, |
-- ce => load_out_regs_i, |
ce => start, |
reset => reset, |
-- din => xin_reg_i, |
din => xin_i, |
dout => xout_reg_i |
); |
|
QOUT_REG: register_1b |
port map(core_clk => core_clk, |
-- ce => load_out_regs_i, |
ce => start, |
reset => reset, |
-- din => qin_reg_i, |
din => qin_i, |
dout => qout_reg_i |
); |
|
COUT_REG: register_1b |
port map(core_clk => core_clk, |
-- ce => load_out_regs_i, |
ce => start, |
reset => reset, |
din => cout_i, |
dout => cout_reg_i |
); |
|
end Structural; |
/tags/start_version/rtl/vhdl/core/operand_mem.vhd
0,0 → 1,151
------------------------------------------------------------------------------------ |
-- |
-- Geoffrey Ottoy - DraMCo research group |
-- |
-- Module Name: operand_mem.vhd / entity operand_mem |
-- |
-- Last Modified: 18/06/2012 |
-- |
-- Description: BRAM memory and logic to the store 4 (1536-bit) operands and the |
-- modulus for the montgomery multiplier |
-- |
-- |
-- Dependencies: modulus_ram, operand_ram |
-- |
-- Revision: |
-- Revision 2.00 - Removed y_register -> seperate module |
-- Revision 1.01 - Added "result_dest_op" input |
-- Revision 1.00 - Architecture |
-- Revision 0.01 - File Created |
-- |
-- |
------------------------------------------------------------------------------------ |
-- |
-- NOTICE: |
-- |
-- Copyright DraMCo research group. 2011. This code may be contain portions patented |
-- by other third parties! |
-- |
------------------------------------------------------------------------------------ |
library IEEE; |
use IEEE.STD_LOGIC_1164.ALL; |
use IEEE.STD_LOGIC_ARITH.ALL; |
use IEEE.STD_LOGIC_UNSIGNED.ALL; |
|
---- Uncomment the following library declaration if instantiating |
---- any Xilinx primitives in this code. |
--library UNISIM; |
--use UNISIM.VComponents.all; |
|
entity operand_mem is |
generic(n : integer := 1536 |
); |
port(-- 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); |
-- address structure: |
-- bit: 8 -> '1': modulus |
-- '0': operands |
-- bits: 7-6 -> operand_in_sel in case of bit 8 = '0' |
-- don't care in case of modulus |
-- bits: 5-0 -> modulus_addr / operand_addr resp. |
|
-- operand interface (multiplier side) |
op_sel : in std_logic_vector(1 downto 0); |
xy_out : out std_logic_vector(1535 downto 0); |
m : out std_logic_vector(1535 downto 0); |
result_in : in std_logic_vector(1535 downto 0); |
-- control signals |
load_op : in std_logic; |
load_m : in std_logic; |
load_result : in std_logic; |
result_dest_op : in std_logic_vector(1 downto 0); |
collision : out std_logic; |
-- system clock |
clk : in std_logic |
); |
end operand_mem; |
|
architecture Behavioral of operand_mem is |
-- single port (32-bit -> 1536-bit) block ram |
component modulus_ram |
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; |
|
-- dual port block ram |
component operand_ram |
port( |
clk : in std_logic; |
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); |
write_operand : in std_logic; |
operand_out_sel : in std_logic_vector(1 downto 0); |
result_dest_op : in std_logic_vector(1 downto 0); |
write_result : in std_logic; |
result_in : in std_logic_vector(1535 downto 0); |
collision : out std_logic; |
result_out : out std_logic_vector(31 downto 0); |
operand_out : out std_logic_vector(1535 downto 0) |
); |
end component; |
|
signal xy_data_i : std_logic_vector(31 downto 0); |
signal xy_addr_i : std_logic_vector(5 downto 0); |
signal operand_in_sel_i : std_logic_vector(1 downto 0); |
signal collision_i : std_logic; |
|
signal xy_op_i : std_logic_vector(1535 downto 0); |
|
signal m_addr_i : std_logic_vector(5 downto 0); |
signal write_m_i : std_logic; |
signal m_data_i : std_logic_vector(31 downto 0); |
begin |
|
-- map outputs |
xy_out <= xy_op_i; |
collision <= collision_i; |
|
-- map inputs |
xy_addr_i <= rw_address(5 downto 0); |
m_addr_i <= rw_address(5 downto 0); |
operand_in_sel_i <= rw_address(7 downto 6); |
xy_data_i <= data_in; |
m_data_i <= data_in; |
write_m_i <= load_m; |
|
-- xy operand storage |
xy_ram: operand_ram port map( |
clk => clk, |
collision => collision_i, |
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_op_i, |
operand_out_sel => op_sel, |
result_dest_op => result_dest_op, |
write_result => load_result, |
result_in => result_in |
); |
|
-- modulus storage |
m_ram : modulus_ram |
port map( |
clk => clk, |
modulus_addr => m_addr_i, |
write_modulus => write_m_i, |
modulus_in => m_data_i, |
modulus_out => m |
); |
|
end Behavioral; |
|
/tags/start_version/rtl/vhdl/core/last_stage.vhd
0,0 → 1,251
------------------------------------------------------------------------------------ |
-- |
-- Geoffrey Ottoy - DraMCo research group |
-- |
-- Module Name: last_stage.vhd / entity last_stage |
-- |
-- Last Modified: 24/11/2011 |
-- |
-- Description: last stage for use in the montgommery multiplier systolic |
-- array pipeline |
-- |
-- |
-- Dependencies: standard_cell_block |
-- cell_1b |
-- |
-- Revision: |
-- Revision 5.00 - Removed input registers and used start signal as load_out_regs |
-- Revision 4.01 - Remove "done" input |
-- Revision 4.00 - Removed "a" input with internal feedback |
-- Revision 3.03 - fixed switched last two bits |
-- Revision 3.02 - removed "ready" output signal |
-- Revision 3.01 - replaced the behavioral description of the registers with a |
-- component instantiation |
-- Revision 3.00 - added registers to store input values xin, cin, qin (because they |
-- can change during operation) |
-- Revision 2.00 - changed indices in signals my, y and m |
-- Revision 1.03 - added done pulse |
-- Revision 1.02 - appended "_i" to name of all internal signals |
-- Revision 1.01 - ready is '1' after reset |
-- Revision 1.00 - Architecture |
-- Revision 0.01 - File Created |
-- |
-- |
------------------------------------------------------------------------------------ |
-- |
-- NOTICE: |
-- |
-- Copyright DraMCo research group. 2011. This code may be contain portions patented |
-- by other third parties! |
-- |
------------------------------------------------------------------------------------ |
library IEEE; |
use IEEE.STD_LOGIC_1164.ALL; |
use IEEE.STD_LOGIC_ARITH.ALL; |
use IEEE.STD_LOGIC_UNSIGNED.ALL; |
|
---- Uncomment the following library declaration if instantiating |
---- any Xilinx primitives in this code. |
--library UNISIM; |
--use UNISIM.VComponents.all; |
|
entity last_stage is |
generic(width : integer := 16 -- must be the same as width of the standard stage |
); |
port(core_clk : in STD_LOGIC; |
my : in STD_LOGIC_VECTOR((width-1) downto 0); |
y : in STD_LOGIC_VECTOR((width-2) downto 0); |
m : in STD_LOGIC_VECTOR((width-2) downto 0); |
xin : in STD_LOGIC; |
qin : in STD_LOGIC; |
cin : in STD_LOGIC; |
start : in STD_LOGIC; |
reset : in STD_LOGIC; |
-- ready : out STD_LOGIC; |
-- done : out STD_LOGIC; |
r : out STD_LOGIC_VECTOR((width+1) downto 0) |
); |
end last_stage; |
|
architecture Structural of last_stage is |
|
component d_flip_flop |
port(core_clk : in STD_LOGIC; |
reset : in STD_LOGIC; |
din : in STD_LOGIC; |
dout : out STD_LOGIC |
); |
end component; |
|
component register_1b |
port(core_clk : in STD_LOGIC; |
ce : in STD_LOGIC; |
reset : in STD_LOGIC; |
din : in STD_LOGIC; |
dout : out STD_LOGIC |
); |
end component; |
|
component register_n |
generic( n : integer := 4 |
); |
port(core_clk : in STD_LOGIC; |
ce : in STD_LOGIC; |
reset : in STD_LOGIC; |
din : in STD_LOGIC_VECTOR((n-1) downto 0); |
dout : out STD_LOGIC_VECTOR((n-1) downto 0) |
); |
end component; |
|
component standard_cell_block |
generic ( width : integer := 32 |
); |
Port ( 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); |
x : in STD_LOGIC; |
q : in STD_LOGIC; |
a : in STD_LOGIC_VECTOR((width-1) downto 0); |
cin : in STD_LOGIC; |
cout : out STD_LOGIC; |
r : out STD_LOGIC_VECTOR((width-1) downto 0)); |
end component; |
|
component cell_1b |
port ( my : in STD_LOGIC; |
y : in STD_LOGIC; |
m : in STD_LOGIC; |
x : in STD_LOGIC; |
q : in STD_LOGIC; |
a : in STD_LOGIC; |
cin : in STD_LOGIC; |
cout : out STD_LOGIC; |
r : out STD_LOGIC); |
end component; |
|
-- input |
signal my_i : std_logic_vector(width downto 0); |
signal m_i : std_logic_vector(width downto 0); |
signal y_i : std_logic_vector(width downto 0); |
signal cin_i : std_logic; |
signal xin_i : std_logic; |
signal qin_i : std_logic; |
signal a_i : std_logic_vector((width) downto 0); |
-- signal cin_reg_i : std_logic; |
-- signal xin_reg_i : std_logic; |
-- signal qin_reg_i : std_logic; |
-- signal a_reg_i : std_logic_vector((width) downto 0); |
|
-- output |
signal r_i : std_logic_vector((width+1) downto 0); |
signal r_reg_i : std_logic_vector((width+1) downto 0); |
|
-- interconnection |
signal cout_i : std_logic; |
|
-- control signals |
-- signal load_out_regs_i : std_logic; |
-- signal done_i : std_logic := '1'; |
--signal ready_del_i : std_logic := '1'; |
|
begin |
-- map internal signals to outputs |
-- done <= done_i; |
r <= r_reg_i; |
-- two posibilities: |
--done <= ready_i and (not ready_del_i); -- slow |
--done <= not ready_i; -- faster but not sure if it will work (DONE_PROC can be omitted) |
|
-- map inputs to internal signals |
my_i <= '0' & my; |
m_i <= "00" & m; |
y_i <= "00" & y; |
xin_i <= xin; |
qin_i <= qin; |
cin_i <= cin; |
|
a_i <= r_reg_i((width+1) downto 1); |
|
cell_block: standard_cell_block |
generic map( width => width |
) |
Port map( my => my_i(width-1 downto 0), |
y => y_i(width-1 downto 0), |
m => m_i(width-1 downto 0), |
-- x => xin_reg_i, |
-- q => qin_reg_i, |
x => xin_i, |
q => qin_i, |
a => a_i((width-1) downto 0), |
-- cin => cin_reg_i, |
cin => cin_i, |
cout => cout_i, |
r => r_i((width-1) downto 0) |
); |
|
last_cell: cell_1b |
port map( my => my_i(width), |
y => y_i(width), |
m => m_i(width), |
-- x => xin_reg_i, |
-- q => qin_reg_i, |
x => xin_i, |
q => qin_i, |
a => a_i(width), |
cin => cout_i, |
cout => r_i(width+1), |
r => r_i(width) |
); |
|
-- XIN_REG: register_1b |
-- port map(core_clk => core_clk, |
-- ce => start, |
-- reset => reset, |
-- din => xin_i, |
-- dout => xin_reg_i |
-- ); |
|
-- QIN_REG: register_1b |
-- port map(core_clk => core_clk, |
-- ce => start, |
-- reset => reset, |
-- din => qin_i, |
-- dout => qin_reg_i |
-- ); |
|
-- CIN_REG: register_1b |
-- port map(core_clk => core_clk, |
-- ce => start, |
-- reset => reset, |
-- din => cin_i, |
-- dout => cin_reg_i |
-- ); |
|
-- control |
-- delay_1_cycle: d_flip_flop |
-- port map(core_clk => core_clk, |
-- reset => reset, |
-- din => start, |
-- dout => load_out_regs_i |
-- ); |
|
-- done_signal: d_flip_flop |
-- port map(core_clk => core_clk, |
-- reset => reset, |
-- din => load_out_regs_i, |
-- dout => done_i |
-- ); |
|
-- output registers |
RESULT_REG: register_n |
generic map( n => (width+2) |
) |
port map(core_clk => core_clk, |
-- ce => load_out_regs_i, |
ce => start, |
reset => reset, |
din => r_i, |
dout => r_reg_i |
); |
|
end Structural; |
/tags/start_version/rtl/vhdl/core/operand_ram.vhd
0,0 → 1,197
------------------------------------------------------------------------------------ |
-- |
-- Geoffrey Ottoy - DraMCo research group |
-- |
-- Module Name: operand_mem.vhd / entity operand_mem |
-- |
-- Last Modified: 25/04/2012 |
-- |
-- Description: BRAM memory and logic to the store 4 (1536-bit) operands and the |
-- modulus for the montgomery multiplier |
-- |
-- |
-- Dependencies: operand_dp (coregen) |
-- |
-- Revision: |
-- Revision 1.01 - added "result_dest_op" input |
-- Revision 1.00 - Architecture |
-- Revision 0.01 - File Created |
-- Additional Comments: |
-- |
-- |
------------------------------------------------------------------------------------ |
-- |
-- NOTICE: |
-- |
-- Copyright DraMCo research group. 2011. This code may be contain portions patented |
-- by other third parties! |
-- |
------------------------------------------------------------------------------------ |
library IEEE; |
use IEEE.STD_LOGIC_1164.ALL; |
use IEEE.STD_LOGIC_ARITH.ALL; |
use IEEE.STD_LOGIC_UNSIGNED.ALL; |
|
---- Uncomment the following library declaration if instantiating |
---- any Xilinx primitives in this code. |
--library UNISIM; |
--use UNISIM.VComponents.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 (+1024 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 |
-- dual port blockram to store and update operands |
component 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; |
|
-- 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); |
signal doutb3 : 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); |
|
-- register_output_proc: process(clk) |
-- begin |
-- if rising_edge(clk) then |
-- case operand_addr(5 downto 4) is |
-- when "00" => |
-- result_out <= doutb0; |
-- when "01" => |
-- result_out <= doutb1; |
-- when "10" => |
-- result_out <= doutb2; |
-- when others => |
-- result_out <= doutb3; |
-- end case; |
-- end if; |
-- end process; |
with operand_addr(5 downto 4) select |
result_out <= doutb0 when "00", |
doutb1 when "01", |
doutb2 when "10", |
doutb3 when others; |
|
-- 4 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 |
); |
|
-- op_3 : operand_dp |
-- port map ( |
-- clka => clk, |
-- wea => wea(3 downto 3), |
-- addra => addra, |
-- dina => operand_in, |
-- douta => operand_out(2047 downto 1536), |
-- clkb => clk, |
-- web => web, |
-- addrb => addrb, |
-- dinb => result_in(2047 downto 1536), |
-- doutb => doutb3 |
-- ); |
|
end Behavioral; |
|
/tags/start_version/rtl/vhdl/core/modulus_ram.vhd
0,0 → 1,109
---------------------------------------------------------------------------------- |
-- Company: |
-- Engineer: |
-- |
-- Create Date: 13:57:21 03/08/2012 |
-- Design Name: |
-- Module Name: modulus_ram - Behavioral |
-- Project Name: |
-- Target Devices: |
-- Tool versions: |
-- Description: |
-- |
-- Dependencies: |
-- |
-- Revision: |
-- Revision 0.01 - File Created |
-- Additional Comments: |
-- |
---------------------------------------------------------------------------------- |
library IEEE; |
use IEEE.STD_LOGIC_1164.ALL; |
use IEEE.STD_LOGIC_ARITH.ALL; |
use IEEE.STD_LOGIC_UNSIGNED.ALL; |
|
---- Uncomment the following library declaration if instantiating |
---- any Xilinx primitives in this code. |
--library UNISIM; |
--use UNISIM.VComponents.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 |
-- single port blockram to store modulus |
component 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; |
|
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) |
); |
|
-- modulus_3 : operands_sp |
-- port map ( |
-- clka => clk, |
-- wea => wea(3 downto 3), |
-- addra => addra, |
-- dina => modulus_in, |
-- douta => modulus_out(2047 downto 1536) |
-- ); |
|
end Behavioral; |
|
/tags/start_version/rtl/vhdl/core/adder_block.vhd
0,0 → 1,90
------------------------------------------------------------------------------------ |
-- |
-- Geoffrey Ottoy - DraMCo research group |
-- |
-- Module Name: adder_block.vhd / entity adder_block |
-- |
-- Last Modified: 25/11/2011 |
-- |
-- Description: adder block for use in the montgommery multiplier pre- and post- |
-- computation adders |
-- |
-- |
-- Dependencies: cell_1b_adder, |
-- d_flip_flop |
-- |
-- Revision: |
-- Revision 1.00 - Architecture |
-- Revision 0.01 - File Created |
-- |
-- |
------------------------------------------------------------------------------------ |
-- |
-- NOTICE: |
-- |
-- Copyright DraMCo research group. 2011. This code may be contain portions patented |
-- by other third parties! |
-- |
------------------------------------------------------------------------------------ |
library IEEE; |
use IEEE.STD_LOGIC_1164.ALL; |
use IEEE.STD_LOGIC_ARITH.ALL; |
use IEEE.STD_LOGIC_UNSIGNED.ALL; |
|
---- Uncomment the following library declaration if instantiating |
---- any Xilinx primitives in this code. |
--library UNISIM; |
--use UNISIM.VComponents.all; |
|
entity adder_block is |
generic ( width : integer := 32 |
); |
Port ( core_clk : in STD_LOGIC; |
a : in STD_LOGIC_VECTOR((width-1) downto 0); |
b : in STD_LOGIC_VECTOR((width-1) downto 0); |
cin : in STD_LOGIC; |
cout : out STD_LOGIC; |
s : out STD_LOGIC_VECTOR((width-1) downto 0) |
); |
end adder_block; |
|
architecture Structural of adder_block is |
component cell_1b_adder |
Port ( a : in STD_LOGIC; |
mux_result : in STD_LOGIC; |
cin : in STD_LOGIC; |
cout : out STD_LOGIC; |
r : out STD_LOGIC); |
end component; |
|
component d_flip_flop |
port(core_clk : in STD_LOGIC; |
reset : in STD_LOGIC; |
din : in STD_LOGIC; |
dout : out STD_LOGIC |
); |
end component; |
|
signal carry : std_logic_vector(width downto 0); |
begin |
|
carry(0) <= cin; |
|
adder_chain: for i in 0 to (width-1) generate |
adders: cell_1b_adder |
port map(a => a(i), |
mux_result => b(i), |
cin => carry(i), |
cout => carry(i+1), |
r => s(i) |
); |
end generate; |
|
delay_1_cycle: d_flip_flop |
port map(core_clk => core_clk, |
reset => '0', |
din => carry(width), |
dout => cout |
); |
|
end Structural; |
/tags/start_version/rtl/vhdl/core/cell_1b_mux.vhd
0,0 → 1,60
------------------------------------------------------------------------------------ |
-- |
-- Geoffrey Ottoy - DraMCo research group |
-- |
-- Module Name: cell_1b_mux.vhd / entity cell_1b_mux |
-- |
-- Last Modified: 14/11/2011 |
-- |
-- Description: mux for use in the montgommery multiplier systolic array |
-- currently a behavioral description |
-- |
-- |
-- Dependencies: none |
-- |
-- Revision: |
-- Revision 1.00 - Architecture |
-- Revision 0.01 - File Created |
-- |
-- |
------------------------------------------------------------------------------------ |
-- |
-- NOTICE: |
-- |
-- Copyright DraMCo research group. 2011. This code may be contain portions patented |
-- by other third parties! |
-- |
------------------------------------------------------------------------------------ |
library IEEE; |
use IEEE.STD_LOGIC_1164.ALL; |
use IEEE.STD_LOGIC_ARITH.ALL; |
use IEEE.STD_LOGIC_UNSIGNED.ALL; |
|
---- Uncomment the following library declaration if instantiating |
---- any Xilinx primitives in this code. |
--library UNISIM; |
--use UNISIM.VComponents.all; |
|
entity cell_1b_mux is |
Port ( my : in STD_LOGIC; |
y : in STD_LOGIC; |
m : in STD_LOGIC; |
x : in STD_LOGIC; |
q : in STD_LOGIC; |
result : out STD_LOGIC); |
end cell_1b_mux; |
|
architecture Behavioral of cell_1b_mux is |
signal sel : std_logic_vector(1 downto 0); |
begin |
|
sel <= x & q; |
|
with sel select |
result <= my when "11", |
y when "10", |
m when "01", |
'0' when others; |
|
end Behavioral; |
|
/tags/start_version/rtl/vhdl/core/adder_n.vhd
0,0 → 1,106
---------------------------------------------------------------------- |
---- ---- |
---- adder_n.vhd ---- |
---- ---- |
---- 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 n-bit adder ---- |
---- using the adder blocks. ---- |
---- used as the montgommery multiplier pre- and post- ---- |
---- computation adder ---- |
---- ---- |
---- Dependencies: ---- |
---- - adder_block ---- |
---- ---- |
---- Author(s): ---- |
---- - 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; |
|
---- Uncomment the following library declaration if instantiating |
---- any Xilinx primitives in this code. |
--library UNISIM; |
--use UNISIM.VComponents.all; |
|
entity adder_n is |
generic ( width : integer := 1536; |
block_width : integer := 8 |
); |
Port ( core_clk : in STD_LOGIC; |
a : in STD_LOGIC_VECTOR((width-1) downto 0); |
b : in STD_LOGIC_VECTOR((width-1) downto 0); |
cin : in STD_LOGIC; |
cout : out STD_LOGIC; |
s : out STD_LOGIC_VECTOR((width-1) downto 0) |
); |
end adder_n; |
|
architecture Structural of adder_n is |
component adder_block |
generic ( width : integer := 32 |
); |
Port ( core_clk : in STD_LOGIC; |
a : in STD_LOGIC_VECTOR((width-1) downto 0); |
b : in STD_LOGIC_VECTOR((width-1) downto 0); |
cin : in STD_LOGIC; |
cout : out STD_LOGIC; |
s : out STD_LOGIC_VECTOR((width-1) downto 0) |
); |
end component; |
|
constant nr_of_blocks : integer := width/block_width; |
signal carry : std_logic_vector(nr_of_blocks downto 0); |
begin |
|
carry(0) <= cin; |
|
adder_block_chain: for i in 0 to (nr_of_blocks-1) generate |
adder_blocks: adder_block |
generic map( width => block_width |
) |
port map( core_clk => core_clk, |
a => a((((i+1)*block_width)-1) downto (i*block_width)), |
b => b((((i+1)*block_width)-1) downto (i*block_width)), |
cin => carry(i), |
cout => carry(i+1), |
s => s((((i+1)*block_width)-1) downto (i*block_width)) |
); |
end generate; |
|
cout <= carry(nr_of_blocks); |
|
end Structural; |
/tags/start_version/rtl/vhdl/core/systolic_pipeline.vhd
0,0 → 1,398
------------------------------------------------------------------------------------ |
-- |
-- Geoffrey Ottoy - DraMCo research group |
-- |
-- Module Name: systolic_pipeline.vhd / entity systolic_pipeline |
-- |
-- Last Modified: 05/01/2012 |
-- |
-- Description: pipelined systolic array implementation of a montgomery multiplier |
-- |
-- |
-- Dependencies: first_stage, |
-- standard_stage, |
-- last_stage, |
-- stepping_control |
-- |
-- Revision: |
-- Revision 3.00 - Made x_selection external |
-- Revision 2.02 - Changed design to cope with new stepping_control (next_x) |
-- Revision 2.01 - Created an extra contant s (step size = n/t) to fix a problem |
-- that occured when t not = sqrt(n). |
-- Revision 2.00 - Moved stepping logic and x_selection to seperate submodules |
-- Revision 1.00 - Architecture |
-- Revision 0.01 - File Created |
-- |
-- |
------------------------------------------------------------------------------------ |
-- |
-- NOTICE: |
-- |
-- Copyright DraMCo research group. 2011. This code may be contain portions patented |
-- by other third parties! |
-- |
------------------------------------------------------------------------------------ |
library IEEE; |
use IEEE.STD_LOGIC_1164.ALL; |
use IEEE.STD_LOGIC_ARITH.ALL; |
use IEEE.STD_LOGIC_UNSIGNED.ALL; |
|
---- Uncomment the following library declaration if instantiating |
---- any Xilinx primitives in this code. |
--library UNISIM; |
--use UNISIM.VComponents.all; |
|
-- p_sel: |
-- 01 = lower part |
-- 10 = upper part |
-- 11 = full range |
|
entity systolic_pipeline is |
generic( n : integer := 1536; -- width of the operands (# bits) |
t : integer := 192; -- number of stages (divider of n) >= 2 |
tl: integer := 64 |
-- best take t = sqrt(n) |
); |
port(core_clk : in STD_LOGIC; |
my : in STD_LOGIC_VECTOR((n) downto 0); |
y : in STD_LOGIC_VECTOR((n-1) downto 0); |
m : in STD_LOGIC_VECTOR((n-1) downto 0); |
xi : in STD_LOGIC; |
start : in STD_LOGIC; |
reset : in STD_LOGIC; |
p_sel : in STD_LOGIC_VECTOR(1 downto 0); -- select which piece of the multiplier will be used |
ready : out STD_LOGIC; |
next_x : out STD_LOGIC; |
r : out STD_LOGIC_VECTOR((n+1) downto 0) |
); |
end systolic_pipeline; |
|
architecture Structural of systolic_pipeline is |
|
constant s : integer := n/t; -- defines the size of the stages (# bits) |
constant size_l : integer := s*tl; |
constant size_h : integer := n - size_l; |
|
component first_stage |
generic(width : integer := 4 -- must be the same as width of the standard stage |
); |
port(core_clk : in STD_LOGIC; |
my : in STD_LOGIC_VECTOR((width) downto 0); |
y : in STD_LOGIC_VECTOR((width) downto 0); |
m : in STD_LOGIC_VECTOR((width) downto 0); |
xin : in STD_LOGIC; |
xout : out STD_LOGIC; |
qout : out STD_LOGIC; |
a_msb : in STD_LOGIC; |
cout : out STD_LOGIC; |
start : in STD_LOGIC; |
reset : in STD_LOGIC; |
--ready : out STD_LOGIC; |
done : out STD_LOGIC; |
r : out STD_LOGIC_VECTOR((width-1) downto 0) |
); |
end component; |
|
component standard_stage |
generic(width : integer := 4 |
); |
port(core_clk : in STD_LOGIC; |
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); |
xin : in STD_LOGIC; |
qin : in STD_LOGIC; |
xout : out STD_LOGIC; |
qout : out STD_LOGIC; |
a_msb : in STD_LOGIC; |
cin : in STD_LOGIC; |
cout : out STD_LOGIC; |
start : in STD_LOGIC; |
reset : in STD_LOGIC; |
-- ready : out STD_LOGIC; |
done : out STD_LOGIC; |
r : out STD_LOGIC_VECTOR((width-1) downto 0) |
); |
end component; |
|
component last_stage |
generic(width : integer := 4 -- must be the same as width of the standard stage |
); |
port(core_clk : in STD_LOGIC; |
my : in STD_LOGIC_VECTOR((width-1) downto 0); |
y : in STD_LOGIC_VECTOR((width-2) downto 0); |
m : in STD_LOGIC_VECTOR((width-2) downto 0); |
xin : in STD_LOGIC; |
qin : in STD_LOGIC; |
cin : in STD_LOGIC; |
start : in STD_LOGIC; |
reset : in STD_LOGIC; |
-- ready : out STD_LOGIC; |
-- done : out STD_LOGIC; |
r : out STD_LOGIC_VECTOR((width+1) downto 0) |
); |
end component; |
|
component stepping_logic |
generic( n : integer := 16; -- max nr of steps required to complete a multiplication |
t : integer := 4 -- total nr of steps in the pipeline |
); |
port(core_clk : in STD_LOGIC; |
start : in STD_LOGIC; |
reset : in STD_LOGIC; |
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 required for a complete multiplication |
start_first_stage : out STD_LOGIC; |
stepping_done : out STD_LOGIC |
); |
end component; |
|
signal start_stage_i : std_logic_vector((t-1) downto 0); |
--signal stage_ready_i : std_logic_vector((t-1) downto 0); |
signal stage_done_i : std_logic_vector((t-2) downto 0); |
|
signal x_i : std_logic_vector((t-1) downto 0) := (others=>'0'); |
signal q_i : std_logic_vector((t-2) downto 0) := (others=>'0'); |
signal c_i : std_logic_vector((t-2) downto 0) := (others=>'0'); |
signal a_i : std_logic_vector((n+1) downto 0) := (others=>'0'); |
signal r_tot : std_logic_vector((n+1) downto 0) := (others=>'0'); |
signal r_h : std_logic_vector(s-1 downto 0) := (others=>'0'); |
signal r_l : std_logic_vector((s+1) downto 0) := (others=>'0'); |
signal a_h : std_logic_vector((s*2)-1 downto 0) := (others=>'0'); |
signal a_l : std_logic_vector((s*2)-1 downto 0) := (others=>'0'); |
|
--signal ready_i : std_logic; |
signal stepping_done_i : std_logic; |
signal t_sel : integer range 0 to t := t; |
signal n_sel : integer range 0 to n := n; |
signal split : std_logic := '0'; |
signal lower_e_i : std_logic := '0'; |
signal higher_e_i : std_logic := '0'; |
signal start_pulses_i : std_logic := '0'; |
signal start_higher_i : std_logic := '0'; |
signal higher_0_done_i : std_logic := '0'; |
signal h_x_0, h_x_1 : std_logic := '0'; |
signal h_q_0, h_q_1 : std_logic := '0'; |
signal h_c_0, h_c_1 : std_logic := '0'; |
signal x_offset_i : integer range 0 to tl*s := 0; |
signal next_x_i : std_logic := '0'; |
begin |
|
-- output mapping |
r <= a_i; -- mogelijks moet er nog een shift operatie gebeuren |
ready <= stepping_done_i; |
|
-- result feedback |
a_i((n+1) downto ((tl+1)*s)) <= r_tot((n+1) downto ((tl+1)*s)); |
a_i(((tl-1)*s-1) downto 0) <= r_tot(((tl-1)*s-1) downto 0); |
|
a_l((s+1) downto 0) <= r_l; |
a_h((s*2)-1 downto s) <= r_h; |
with p_sel select |
a_i(((tl+1)*s-1) downto ((tl-1)*s)) <= a_l when "01", |
a_h when "10", |
r_tot(((tl+1)*s-1) downto ((tl-1)*s)) when others; |
|
|
-- signals from x_selection |
next_x_i <= start_stage_i(1) or (start_stage_i(tl+1) and higher_e_i); |
-- |
next_x <= next_x_i; |
x_i(0) <= xi; |
|
-- this module controls the pipeline operation |
with p_sel select |
t_sel <= tl when "01", |
t-tl when "10", |
t when others; |
|
with p_sel select |
n_sel <= size_l-1 when "01", |
size_h-1 when "10", |
n-1 when others; |
|
with p_sel select |
lower_e_i <= '0' when "10", |
'1' when others; |
|
with p_sel select |
higher_e_i <= '1' when "10", |
'0' when others; |
|
split <= p_sel(0) and p_sel(1); |
|
|
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, |
reset => reset, |
t_sel => t_sel, |
n_sel => n_sel, |
start_first_stage => start_pulses_i, |
stepping_done => stepping_done_i |
); |
|
-- start signals for first stage of lower and higher part |
start_stage_i(0) <= start_pulses_i and lower_e_i; |
start_higher_i <= start_pulses_i and (higher_e_i and not split); |
|
-- start signals for stage tl and tl+1 (full pipeline operation) |
start_stage_i(tl) <= stage_done_i(tl-1) and split; |
start_stage_i(tl+1) <= stage_done_i(tl) or higher_0_done_i; |
|
-- nothing special here, previous stages starts the next |
start_signals_l: for i in 1 to tl-1 generate |
start_stage_i(i) <= stage_done_i(i-1); |
end generate; |
start_signals_h: for i in tl+2 to t-1 generate |
start_stage_i(i) <= stage_done_i(i-1); |
end generate; |
|
stage_0: first_stage |
generic map(width => s |
) |
port map(core_clk => core_clk, |
my => my(s downto 0), |
y => y(s downto 0), |
m => m(s downto 0), |
xin => x_i(0), |
xout => x_i(1), |
qout => q_i(0), |
a_msb => a_i(s), |
cout => c_i(0), |
start => start_stage_i(0), |
reset => reset, |
--ready => stage_ready_i(0), |
done => stage_done_i(0), |
r => r_tot((s-1) downto 0) |
); |
|
stages_l: for i in 1 to (tl) generate |
standard_stages: standard_stage |
generic map(width => s |
) |
port map(core_clk => core_clk, |
my => my(((i+1)*s) downto ((s*i)+1)), |
y => y(((i+1)*s) downto ((s*i)+1)), |
m => m(((i+1)*s) downto ((s*i)+1)), |
xin => x_i(i), |
qin => q_i(i-1), |
xout => x_i(i+1), |
qout => q_i(i), |
a_msb => a_i((i+1)*s), |
cin => c_i(i-1), |
cout => c_i(i), |
start => start_stage_i(i), |
reset => reset, |
--ready => stage_ready_i(i), |
done => stage_done_i(i), |
r => r_tot((((i+1)*s)-1) downto (s*i)) |
); |
end generate; |
|
h_c_1 <= h_c_0 or c_i(tl); |
h_q_1 <= h_q_0 or q_i(tl); |
h_x_1 <= h_x_0 or x_i(tl+1); |
|
stage_tl_1: standard_stage |
generic map(width => s |
) |
port map(core_clk => core_clk, |
my => my(((tl+2)*s) downto ((s*(tl+1))+1)), |
y => y(((tl+2)*s) downto ((s*(tl+1))+1)), |
m => m(((tl+2)*s) downto ((s*(tl+1))+1)), |
--xin => x_i(tl+1), |
xin => h_x_1, |
--qin => q_i(tl), |
qin => h_q_1, |
xout => x_i(tl+2), |
qout => q_i(tl+1), |
a_msb => a_i((tl+2)*s), |
--cin => c_i(tl), |
cin => h_c_1, |
cout => c_i(tl+1), |
start => start_stage_i(tl+1), |
reset => reset, |
--ready => stage_ready_i(i), |
done => stage_done_i(tl+1), |
r => r_tot((((tl+2)*s)-1) downto (s*(tl+1))) |
); |
|
stages_h: for i in (tl+2) to (t-2) generate |
standard_stages: standard_stage |
generic map(width => s |
) |
port map(core_clk => core_clk, |
my => my(((i+1)*s) downto ((s*i)+1)), |
y => y(((i+1)*s) downto ((s*i)+1)), |
m => m(((i+1)*s) downto ((s*i)+1)), |
xin => x_i(i), |
qin => q_i(i-1), |
xout => x_i(i+1), |
qout => q_i(i), |
a_msb => a_i((i+1)*s), |
cin => c_i(i-1), |
cout => c_i(i), |
start => start_stage_i(i), |
reset => reset, |
--ready => stage_ready_i(i), |
done => stage_done_i(i), |
r => r_tot((((i+1)*s)-1) downto (s*i)) |
); |
end generate; |
|
stage_t: last_stage |
generic map(width => s -- must be the same as width of the standard stage |
) |
port map(core_clk => core_clk, |
my => my(n downto ((n-s)+1)), --width-1 |
y => y((n-1) downto ((n-s)+1)), --width-2 |
m => m((n-1) downto ((n-s)+1)), --width-2 |
xin => x_i(t-1), |
qin => q_i(t-2), |
cin => c_i(t-2), |
start => start_stage_i(t-1), |
reset => reset, |
--ready => stage_ready_i(t-1), |
r => r_tot((n+1) downto (n-s)) --width+1 |
); |
|
mid_start: first_stage |
generic map(width => s |
) |
port map(core_clk => core_clk, |
my => my((tl*s+s) downto tl*s), |
y => y((tl*s+s) downto tl*s), |
m => m((tl*s+s) downto tl*s), |
xin => x_i(0), |
xout => h_x_0, |
qout => h_q_0, |
a_msb => a_i((tl+1)*s), |
cout => h_c_0, |
start => start_higher_i, |
reset => reset, |
--ready => stage_ready_i(0), |
done => higher_0_done_i, |
r => r_h |
); |
|
mid_end: last_stage |
generic map(width => s -- must be the same as width of the standard stage |
) |
port map(core_clk => core_clk, |
my => my((tl*s) downto ((tl-1)*s)+1), --width-1 |
y => y(((tl*s)-1) downto ((tl-1)*s)+1), --width-2 |
m => m(((tl*s)-1) downto ((tl-1)*s)+1), --width-2 |
xin => x_i(tl-1), |
qin => q_i(tl-2), |
cin => c_i(tl-2), |
start => start_stage_i(tl-1), |
reset => reset, |
--ready => stage_ready_i(t-1), |
r => r_l --width+1 |
); |
|
end Structural; |
/tags/start_version/rtl/vhdl/core/multiplier_core.vhd
0,0 → 1,244
------------------------------------------------------------------------------------ |
-- |
-- Geoffrey Ottoy - DraMCo research group |
-- |
-- Module Name: multiplier_core.vhd / entity multiplier_core |
-- |
-- Last Modified: 18/06/2012 |
-- |
-- Description: a pipelined montgomery multiplier, with split |
-- pipeline operation and "auto-run" support |
-- |
-- |
-- Dependencies: mont_mult_sys_pipeline, operand_mem, fifo_primitive, mont_cntrl |
-- |
-- Revision: |
-- Revision 6.00 - created seperate module for x-operand (x_shift_reg) |
-- Revision 5.00 - moved fifo interface to shared memory |
-- Revision 4.00 - added dest_op_single input |
-- Revision 3.00 - added auto-run control |
-- Revision 2.01 - Split ctrl_reg input to separate inputs with more descriptive |
-- names |
-- Revision 2.00 - Control logic moved to separate design module and added fifo |
-- Revision 1.00 - Architecture based on multiplier IP core "mont_mult1536_v1_00_a" |
-- Revision 0.01 - File Created |
-- |
-- |
------------------------------------------------------------------------------------ |
-- |
-- NOTICE: |
-- |
-- Copyright DraMCo research group. 2011. This code may be contain portions patented |
-- by other third parties! |
-- |
------------------------------------------------------------------------------------ |
library IEEE; |
use IEEE.STD_LOGIC_1164.ALL; |
use IEEE.STD_LOGIC_ARITH.ALL; |
use IEEE.STD_LOGIC_UNSIGNED.ALL; |
|
---- Uncomment the following library declaration if instantiating |
---- any Xilinx primitives in this code. |
--library UNISIM; |
--use UNISIM.VComponents.all; |
|
entity multiplier_core is |
port( clk : in std_logic; |
reset : in std_logic; |
-- operand memory interface (plb shared memory) |
write_enable : in std_logic; |
data_in : in std_logic_vector (31 downto 0); |
rw_address : in std_logic_vector (8 downto 0); |
data_out : out std_logic_vector (31 downto 0); |
collision : out std_logic; |
-- op_sel fifo interface |
fifo_din : in std_logic_vector (31 downto 0); |
fifo_push : in std_logic; |
fifo_full : out std_logic; |
fifo_nopush : out std_logic; |
-- ctrl signals |
start : in std_logic; |
run_auto : in std_logic; |
ready : out std_logic; |
x_sel_single : in std_logic_vector (1 downto 0); |
y_sel_single : in std_logic_vector (1 downto 0); |
dest_op_single : in std_logic_vector (1 downto 0); |
p_sel : in std_logic_vector (1 downto 0); |
calc_time : out std_logic |
); |
end multiplier_core; |
|
architecture Behavioral of multiplier_core is |
component mont_mult_sys_pipeline |
generic ( n : integer := 32; |
nr_stages : integer := 8; --(divides n, bits_low & (n-bits_low)) |
stages_low : integer := 3 |
); |
Port ( core_clk : in STD_LOGIC; |
xy : in STD_LOGIC_VECTOR((n-1) downto 0); |
m : in STD_LOGIC_VECTOR((n-1) downto 0); |
r : out STD_LOGIC_VECTOR((n-1) downto 0); |
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; |
|
component operand_mem |
port( |
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); |
op_sel : in std_logic_vector(1 downto 0); |
xy_out : out std_logic_vector(1535 downto 0); |
m : out std_logic_vector(1535 downto 0); |
result_in : in std_logic_vector(1535 downto 0); |
load_op : in std_logic; |
load_m : in std_logic; |
load_result : in std_logic; |
result_dest_op : in std_logic_vector(1 downto 0); |
collision : out std_logic; |
clk : in std_logic |
); |
end component; |
|
component fifo_primitive |
port( |
clk : in std_logic; |
din : in std_logic_vector(31 downto 0); |
push : in std_logic; |
pop : in std_logic; |
reset : in std_logic; |
dout : out std_logic_vector(31 downto 0); |
empty : out std_logic; |
full : out std_logic; |
nopop : out std_logic; |
nopush : out std_logic |
); |
end component; |
|
component mont_ctrl |
port( |
clk : in std_logic; |
reset : in std_logic; |
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_sel_buffer : in std_logic_vector(31 downto 0); |
read_buffer : out std_logic; |
multiplier_ready : in std_logic; |
op_buffer_empty : in std_logic; |
buffer_noread : in std_logic; |
done : out std_logic; |
calc_time : out std_logic; |
op_sel : out std_logic_vector(1 downto 0); |
load_x : out std_logic; |
load_result : out std_logic; |
start_multiplier : out std_logic |
); |
end component; |
|
signal xy_i : std_logic_vector(1535 downto 0); |
signal x_i : std_logic; |
signal m : std_logic_vector(1535 downto 0); |
signal r : std_logic_vector(1535 downto 0); |
|
signal op_sel : std_logic_vector(1 downto 0); |
signal result_dest_op_i : std_logic_vector(1 downto 0); |
signal mult_ready : std_logic; |
signal start_mult : std_logic; |
signal load_op : std_logic; |
signal load_x_i : std_logic; |
signal load_m : std_logic; |
signal load_result : std_logic; |
|
signal fifo_empty : std_logic; |
signal fifo_pop : std_logic; |
signal fifo_nopop : std_logic; |
signal fifo_dout : std_logic_vector(31 downto 0); |
--signal fifo_push : std_logic; |
|
constant n : integer := 1536; |
constant t : integer := 96; |
constant tl : integer := 32; |
begin |
|
-- The actual multiplier |
the_multiplier: mont_mult_sys_pipeline generic map( |
n => n, |
nr_stages => t, --(divides n, bits_low & (n-bits_low)) |
stages_low => tl |
) |
port map( |
core_clk => clk, |
xy => xy_i, |
m => m, |
r => r, |
start => start_mult, |
reset => reset, |
p_sel => p_sel, |
load_x => load_x_i, |
ready => mult_ready |
); |
|
-- Block ram memory for storing the operands and the modulus |
the_memory: operand_mem port map( |
data_in => data_in, |
data_out => data_out, |
rw_address => rw_address, |
op_sel => op_sel, |
xy_out => xy_i, |
m => m, |
result_in => r, |
load_op => load_op, |
load_m => load_m, |
load_result => load_result, |
result_dest_op => result_dest_op_i, |
collision => collision, |
clk => clk |
); |
load_op <= write_enable when (rw_address(8) = '0') else '0'; |
load_m <= write_enable when (rw_address(8) = '1') else '0'; |
result_dest_op_i <= dest_op_single when run_auto = '0' else "11"; -- in autorun mode we always store the result in operand3 |
|
-- A fifo for auto-run operand selection |
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 |
); |
|
-- 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 => run_auto, |
op_buffer_empty => fifo_empty, |
op_sel_buffer => fifo_dout, |
read_buffer => fifo_pop, |
buffer_noread => fifo_nopop, |
done => ready, |
calc_time => calc_time, |
op_sel => op_sel, |
load_x => load_x_i, |
load_result => load_result, |
start_multiplier => start_mult, |
multiplier_ready => mult_ready |
); |
|
|
end Behavioral; |
|