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/trunk
- from Rev 89 to Rev 90
- ↔ Reverse comparison
Rev 89 → Rev 90
/bench/vhdl/msec_axi_tb.vhd
0,0 → 1,865
---------------------------------------------------------------------- |
---- msec_axi_tb ---- |
---- ---- |
---- This file is part of the ---- |
---- Modular Simultaneous Exponentiation Core project ---- |
---- http://www.opencores.org/cores/mod_sim_exp/ ---- |
---- ---- |
---- Description ---- |
---- testbench for the AXI-Lite interface of the modular ---- |
---- simultaneous exponentiation core. Performs some ---- |
---- exponentiations to verify the design ---- |
---- Takes input parameters from in/sim_input.txt en writes ---- |
---- result and output to out/axi_sim_output.txt. The AXI bus ---- |
---- transfers ar written to out/axi_bus_output ---- |
---- ---- |
---- Dependencies: ---- |
---- - msec_ipcore_axilite ---- |
---- ---- |
---- Authors: ---- |
---- - Geoffrey Ottoy, DraMCo research group ---- |
---- - Jonas De Craene, JonasDC@opencores.org ---- |
---- ---- |
---------------------------------------------------------------------- |
---- ---- |
---- Copyright (C) 2011 DraMCo research group and OPENCORES.ORG ---- |
---- ---- |
---- This source file may be used and distributed without ---- |
---- restriction provided that this copyright statement is not ---- |
---- removed from the file and that any derivative work contains ---- |
---- the original copyright notice and the associated disclaimer. ---- |
---- ---- |
---- This source file is free software; you can redistribute it ---- |
---- and/or modify it under the terms of the GNU Lesser General ---- |
---- Public License as published by the Free Software Foundation; ---- |
---- either version 2.1 of the License, or (at your option) any ---- |
---- later version. ---- |
---- ---- |
---- This source is distributed in the hope that it will be ---- |
---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- |
---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- |
---- PURPOSE. See the GNU Lesser General Public License for more ---- |
---- details. ---- |
---- ---- |
---- You should have received a copy of the GNU Lesser General ---- |
---- Public License along with this source; if not, download it ---- |
---- from http://www.opencores.org/lgpl.shtml ---- |
---- ---- |
---------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_unsigned.all; |
use ieee.std_logic_arith.all; |
|
library std; |
use std.textio.all; |
|
library ieee; |
use ieee.std_logic_textio.all; |
|
entity msec_axi_tb is |
end msec_axi_tb; |
|
architecture arch of msec_axi_tb is |
-- constants |
constant CLK_PERIOD : time := 10 ns; |
constant CORE_CLK_PERIOD : time := 4 ns; |
constant C_S_AXI_DATA_WIDTH : integer := 32; |
constant C_S_AXI_ADDR_WIDTH : integer := 32; |
|
file output : text open write_mode is "out/axi_sim_output.txt"; |
file axi_dbg : text open write_mode is "out/axi_bus_output.txt"; |
file input : text open read_mode is "src/sim_input.txt"; |
|
------------------------------------------------------------------ |
-- Core parameters |
------------------------------------------------------------------ |
constant C_NR_BITS_TOTAL : integer := 1536; |
constant C_NR_STAGES_TOTAL : integer := 96; |
constant C_NR_STAGES_LOW : integer := 32; |
constant C_SPLIT_PIPELINE : boolean := true; |
constant C_FIFO_DEPTH : integer := 32; -- set to (maximum exponent width)/16 |
constant C_MEM_STYLE : string := "generic"; -- xil_prim, generic, asym are valid options |
constant C_FPGA_MAN : string := "xilinx"; -- xilinx, altera are valid options |
constant C_BASEADDR : std_logic_vector(0 to 31) := x"A0000000"; |
constant C_HIGHADDR : std_logic_vector(0 to 31) := x"A0007FFF"; |
|
-- extra calculated constants |
constant NR_BITS_LOW : integer := (C_NR_BITS_TOTAL/C_NR_STAGES_TOTAL)*C_NR_STAGES_LOW; |
constant NR_BITS_HIGH : integer := C_NR_BITS_TOTAL-NR_BITS_LOW; |
|
signal core_clk : std_logic := '0'; |
------------------------- |
-- AXI4lite interface |
------------------------- |
--- Global signals |
signal S_AXI_ACLK : std_logic; |
signal S_AXI_ARESETN : std_logic; |
--- Write address channel |
signal S_AXI_AWADDR : std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0); |
signal S_AXI_AWVALID : std_logic; |
signal S_AXI_AWREADY : std_logic; |
--- Write data channel |
signal S_AXI_WDATA : std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0); |
signal S_AXI_WVALID : std_logic; |
signal S_AXI_WREADY : std_logic; |
signal S_AXI_WSTRB : std_logic_vector((C_S_AXI_DATA_WIDTH/8)-1 downto 0); |
--- Write response channel |
signal S_AXI_BVALID : std_logic; |
signal S_AXI_BREADY : std_logic; |
signal S_AXI_BRESP : std_logic_vector(1 downto 0); |
--- Read address channel |
signal S_AXI_ARADDR : std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0); |
signal S_AXI_ARVALID : std_logic; |
signal S_AXI_ARREADY : std_logic; |
--- Read data channel |
signal S_AXI_RDATA : std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0); |
signal S_AXI_RVALID : std_logic; |
signal S_AXI_RREADY : std_logic; |
signal S_AXI_RRESP : std_logic_vector(1 downto 0); |
|
-- CORE control reg bits |
signal core_control_reg : std_logic_vector(31 downto 0) := (others=>'0'); |
signal core_start : std_logic; |
signal core_exp_m : std_logic; |
signal core_p_sel : std_logic_vector(1 downto 0); |
signal core_dest_op_single : std_logic_vector(1 downto 0); |
signal core_x_sel_single : std_logic_vector(1 downto 0); |
signal core_y_sel_single : std_logic_vector(1 downto 0); |
signal core_modulus_sel : std_logic; |
signal calc_time : std_logic; |
signal IntrEvent : std_logic; |
|
begin |
|
-- map the core control bits to the core control register |
core_control_reg(31 downto 30) <= core_p_sel; |
core_control_reg(29 downto 28) <= core_dest_op_single; |
core_control_reg(27 downto 26) <= core_x_sel_single; |
core_control_reg(25 downto 24) <= core_y_sel_single; |
core_control_reg(23) <= core_start; |
core_control_reg(22) <= core_exp_m; |
core_control_reg(21) <= core_modulus_sel; |
|
------------------------------------------ |
-- Generate S_AXI_ACLK |
------------------------------------------ |
clk_process : process |
begin |
while (true) loop |
S_AXI_ACLK <= '0'; |
wait for CLK_PERIOD/2; |
S_AXI_ACLK <= '1'; |
wait for CLK_PERIOD/2; |
end loop; |
end process; |
|
core_clk_process : process |
begin |
while (true) loop |
core_clk <= '0'; |
wait for CORE_CLK_PERIOD/2; |
core_clk <= '1'; |
wait for CORE_CLK_PERIOD/2; |
end loop; |
end process; |
|
|
stim_proc : process |
-- variables to read file |
variable L : line; |
variable Lw : line; |
variable La : line; |
|
-- constants for memory space selection |
constant op_modulus : std_logic_vector(2 downto 0) := "000"; |
constant op_0 : std_logic_vector(2 downto 0) := "001"; |
constant op_1 : std_logic_vector(2 downto 0) := "010"; |
constant op_2 : std_logic_vector(2 downto 0) := "011"; |
constant op_3 : std_logic_vector(2 downto 0) := "100"; |
constant fifo : std_logic_vector(2 downto 0) := "101"; |
constant control_reg : std_logic_vector(2 downto 0) := "110"; |
|
procedure waitclk(n : natural := 1) is |
begin |
for i in 1 to n loop |
wait until rising_edge(S_AXI_ACLK); |
end loop; |
end waitclk; |
|
procedure axi_write( variable address : std_logic_vector(31 downto 0); |
variable data : std_logic_vector(31 downto 0) ) is |
variable counter : integer := 0; |
begin |
-- place address on the bus |
wait until rising_edge(S_AXI_ACLK); |
S_AXI_AWADDR <= address; |
S_AXI_AWVALID <= '1'; |
S_AXI_WDATA <= data; |
S_AXI_WVALID <= '1'; |
S_AXI_WSTRB <= "1111"; |
while (counter /= 2) loop -- wait for slave response |
wait until rising_edge(S_AXI_ACLK); |
if (S_AXI_AWREADY='1') then |
S_AXI_AWVALID <= '0'; |
counter := counter+1; |
end if; |
if (S_AXI_WREADY='1') then |
S_AXI_WVALID <= '0'; |
counter := counter+1; |
end if; |
end loop; |
S_AXI_BREADY <= '1'; |
if S_AXI_BVALID/='1' then |
wait until S_AXI_BVALID='1'; |
end if; |
|
write(La, string'("Wrote ")); |
hwrite(La, data); |
write(La, string'(" to ")); |
hwrite(La, address); |
|
if (S_AXI_BRESP /= "00") then |
write(La, string'(" --> Error! Status: ")); |
write(La, S_AXI_BRESP); |
end if; |
writeline(axi_dbg, La); |
|
wait until rising_edge(S_AXI_ACLK); |
S_AXI_BREADY <= '0'; |
end axi_write; |
|
procedure axi_read( variable address : std_logic_vector(31 downto 0); |
variable data : out std_logic_vector(31 downto 0) ) is |
begin |
-- place address on the bus |
wait until rising_edge(S_AXI_ACLK); |
S_AXI_ARADDR <= address; |
S_AXI_ARVALID <= '1'; |
wait until S_AXI_ARREADY='1'; |
wait until rising_edge(S_AXI_ACLK); |
S_AXI_ARVALID <= '0'; |
-- wait for read data |
S_AXI_RREADY <= '1'; |
wait until S_AXI_RVALID='1'; |
wait until rising_edge(S_AXI_ACLK); |
|
data := S_AXI_RDATA; |
write(La, string'("Read ")); |
hwrite(La, S_AXI_RDATA); |
write(La, string'(" from ")); |
hwrite(La, address); |
|
if (S_AXI_RRESP /= "00") then |
write(La, string'(" --> Error! Status: ")); |
write(La, S_AXI_RRESP); |
end if; |
writeline(axi_dbg, La); |
S_AXI_RREADY <= '0'; |
|
--assert false report "Wrote " & " to " & " Status=" & to_string(S_AXI_BRESP) severity note; |
end axi_read; |
|
procedure axi_write_control_reg is |
variable address : std_logic_vector(31 downto 0); |
variable data : std_logic_vector(31 downto 0); |
begin |
wait until rising_edge(S_AXI_ACLK); |
address := C_BASEADDR+x"00006000"; |
data := core_control_reg; |
axi_write(address, data); |
end axi_write_control_reg; |
|
procedure loadOp(constant op_sel : std_logic_vector(2 downto 0); |
variable op_data : std_logic_vector(2047 downto 0)) is |
variable address : std_logic_vector(31 downto 0); |
variable zero : std_logic_vector(31 downto 0) := (others=>'0'); |
begin |
-- set the start address |
address := C_BASEADDR(0 to 15) & '0' & op_sel & "0000" & "000000" & "00"; |
-- write operand per 32 bits |
for i in 0 to (C_NR_BITS_TOTAL/32)-1 loop |
case (core_p_sel) is |
when "11" => |
axi_write(address, op_data(((i+1)*32)-1 downto (i*32))); |
when "01" => |
if (i < 16) then axi_write(address, op_data(((i+1)*32)-1 downto (i*32))); |
else axi_write(address, zero); end if; |
when "10" => |
if (i >= 16) then axi_write(address, op_data(((i-15)*32)-1 downto ((i-16)*32))); |
else axi_write(address, zero); end if; |
when others => |
axi_write(address, zero); |
end case; |
-- next address is 32 further |
address := address + "100"; |
end loop; |
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 |
variable address : std_logic_vector(31 downto 0); |
variable data : std_logic_vector(31 downto 0); |
begin |
-- set destination operand, cause only can readfrom destination operand |
case op_sel is |
when "001" => core_dest_op_single <= "00"; |
when "010" => core_dest_op_single <= "01"; |
when "011" => core_dest_op_single <= "10"; |
when "100" => core_dest_op_single <= "11"; |
when others => core_dest_op_single <= "00"; |
end case; |
axi_write_control_reg; |
|
-- set the start address |
if (core_p_sel = "10") then |
address := C_BASEADDR(0 to 15) & '0' & op_sel & "0000" & "010000" & "00"; |
else |
address := C_BASEADDR(0 to 15) & '0' & op_sel & "0000" & "000000" & "00"; |
end if; |
-- read the data |
for i in 0 to (op_width/32)-1 loop |
axi_read(address, data); |
op_data(((i+1)*32)-1 downto (i*32)) := data; |
-- next address is 32 further |
address := address + "100"; |
end loop; |
end readOp; |
|
procedure loadFifo(variable data : std_logic_vector(31 downto 0)) is |
variable address : std_logic_vector(31 downto 0); |
begin |
-- set the start address |
address := C_BASEADDR(0 to 15) & '0' & fifo & "0000" & "000000" & "00"; |
axi_write(address, data); |
end loadFifo; |
|
function ToString(constant Timeval : time) return string is |
variable StrPtr : line; |
begin |
write(StrPtr,Timeval); |
return StrPtr.all; |
end ToString; |
|
|
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; |
variable temp_data : std_logic_vector(31 downto 0); |
|
variable timer : time; |
begin |
|
write(Lw, string'("----------------------------------------------")); |
writeline(output, Lw); |
write(Lw, string'("-- AXI BUS SIMULATION --")); |
writeline(output, Lw); |
write(Lw, string'("----------------------------------------------")); |
writeline(output, Lw); |
-- axi bus initialisation |
S_AXI_AWADDR <= (others=>'0'); |
S_AXI_AWVALID <= '0'; |
S_AXI_WDATA <= (others=>'0'); |
S_AXI_WVALID <= '0'; |
S_AXI_WSTRB <= (others=>'0'); |
S_AXI_BREADY <= '0'; |
S_AXI_ARADDR <= (others=>'0'); |
S_AXI_ARVALID <= '0'; |
S_AXI_RREADY <= '0'; |
-- control signals initialisation |
core_start <= '0'; |
core_exp_m <= '0'; |
core_x_sel_single <= "00"; |
core_y_sel_single <= "01"; |
core_dest_op_single <= "01"; |
core_p_sel <= "11"; |
core_modulus_sel <= '0'; |
-- reset |
S_AXI_ARESETN <= '0'; |
waitclk(10); |
S_AXI_ARESETN <= '1'; |
waitclk(20); |
|
|
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 C_NR_BITS_TOTAL => when NR_BITS_HIGH => when NR_BITS_LOW => |
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 C_NR_BITS_TOTAL => core_p_sel <= "11"; write(Lw, string'(" Full pipeline selected")); |
when NR_BITS_HIGH => core_p_sel <= "10"; write(Lw, string'(" Upper pipeline selected")); |
when NR_BITS_LOW => 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; |
axi_write_control_reg; |
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 |
axi_write_control_reg; |
timer := NOW; |
core_start <= '1'; |
axi_write_control_reg; |
core_start <= '0'; |
axi_write_control_reg; |
wait until IntrEvent = '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, (C_NR_STAGES_TOTAL+(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 |
timer := NOW; |
core_start <= '1'; |
axi_write_control_reg; |
core_start <= '0'; |
axi_write_control_reg; |
wait until IntrEvent = '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, (C_NR_STAGES_TOTAL+(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 |
core_start <= '1'; |
axi_write_control_reg; |
timer := NOW; |
core_start <= '0'; |
axi_write_control_reg; |
wait until IntrEvent = '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, (C_NR_STAGES_TOTAL+(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 |
core_start <= '1'; |
axi_write_control_reg; |
timer := NOW; |
core_start <= '0'; |
axi_write_control_reg; |
wait until IntrEvent = '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, (C_NR_STAGES_TOTAL+(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 |
temp_data := e1((i*16)+15 downto (i*16)) & e0((i*16)+15 downto (i*16)); |
LoadFifo(temp_data); |
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_exp_m <= '1'; |
timer := NOW; |
core_start <= '1'; |
axi_write_control_reg; |
core_start <= '0'; |
axi_write_control_reg; |
wait until IntrEvent='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, ((C_NR_STAGES_TOTAL+(2*(base_width-1)))*CLK_PERIOD*7*exponent_width)/4); |
writeline(output, Lw); |
write(Lw, string'(" => Done")); |
core_exp_m <= '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 |
timer := NOW; |
core_start <= '1'; |
axi_write_control_reg; |
core_start <= '0'; |
axi_write_control_reg; |
wait until IntrEvent = '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, (C_NR_STAGES_TOTAL+(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; |
|
|
------------------------- |
-- Unit Under Test |
------------------------- |
uut : entity work.msec_ipcore_axilite |
generic map( |
C_NR_BITS_TOTAL => C_NR_BITS_TOTAL, |
C_NR_STAGES_TOTAL => C_NR_STAGES_TOTAL, |
C_NR_STAGES_LOW => C_NR_STAGES_LOW, |
C_SPLIT_PIPELINE => C_SPLIT_PIPELINE, |
C_FIFO_DEPTH => C_FIFO_DEPTH, |
C_MEM_STYLE => C_MEM_STYLE, -- xil_prim, generic, asym are valid options |
C_FPGA_MAN => C_FPGA_MAN, -- xilinx, altera are valid options |
C_BASEADDR => C_BASEADDR, |
C_HIGHADDR => C_HIGHADDR |
) |
port map( |
--USER ports |
calc_time => calc_time, |
IntrEvent => IntrEvent, |
------------------------- |
-- AXI4lite interface |
------------------------- |
--- Global signals |
S_AXI_ACLK => S_AXI_ACLK, |
S_AXI_ARESETN => S_AXI_ARESETN, |
--- Write address channel |
S_AXI_AWADDR => S_AXI_AWADDR, |
S_AXI_AWVALID => S_AXI_AWVALID, |
S_AXI_AWREADY => S_AXI_AWREADY, |
--- Write data channel |
S_AXI_WDATA => S_AXI_WDATA, |
S_AXI_WVALID => S_AXI_WVALID, |
S_AXI_WREADY => S_AXI_WREADY, |
S_AXI_WSTRB => S_AXI_WSTRB, |
--- Write response channel |
S_AXI_BVALID => S_AXI_BVALID, |
S_AXI_BREADY => S_AXI_BREADY, |
S_AXI_BRESP => S_AXI_BRESP, |
--- Read address channel |
S_AXI_ARADDR => S_AXI_ARADDR, |
S_AXI_ARVALID => S_AXI_ARVALID, |
S_AXI_ARREADY => S_AXI_ARREADY, |
--- Read data channel |
S_AXI_RDATA => S_AXI_RDATA, |
S_AXI_RVALID => S_AXI_RVALID, |
S_AXI_RREADY => S_AXI_RREADY, |
S_AXI_RRESP => S_AXI_RRESP |
); |
|
end arch; |
|
/rtl/vhdl/ram/dpram_generic.vhd
56,15 → 56,14
depth : integer := 2 |
); |
port ( |
-- write port A |
clkA : in std_logic; |
waddrA : in std_logic_vector(log2(depth)-1 downto 0); |
weA : in std_logic; |
dinA : in std_logic_vector(31 downto 0); |
-- read port B |
clkB : in std_logic; |
raddrB : in std_logic_vector(log2(depth)-1 downto 0); |
doutB : out std_logic_vector(31 downto 0) |
clk : in std_logic; |
-- write port |
waddr : in std_logic_vector(log2(depth)-1 downto 0); |
we : in std_logic; |
din : in std_logic_vector(31 downto 0); |
-- read port |
raddr : in std_logic_vector(log2(depth)-1 downto 0); |
dout : out std_logic_vector(31 downto 0) |
); |
end dpram_generic; |
|
71,11 → 70,11
architecture behavorial of dpram_generic is |
-- the memory |
type ram_type is array (depth-1 downto 0) of std_logic_vector (31 downto 0); |
shared variable RAM : ram_type := (others => (others => '0')); |
signal RAM : ram_type := (others => (others => '0')); |
|
-- xilinx constraint to use blockram resources |
attribute ram_style : string; |
attribute ram_style of ram:variable is "block"; |
attribute ram_style of ram:signal is "block"; |
-- altera constraints: |
-- for smal depths: |
-- if the synthesis option "allow any size of RAM to be inferred" is on, these lines |
82,23 → 81,16
-- may be left commented. |
-- uncomment this attribute if that option is off and you know wich primitives should be used. |
--attribute ramstyle : string; |
--attribute ramstyle of RAM : variable is "M9K, no_rw_check"; |
--attribute ramstyle of RAM : signal is "M9K, no_rw_check"; |
begin |
process (clkA) |
process (clk) |
begin |
if rising_edge(clkA) then |
if (weA = '1') then |
RAM(conv_integer(waddrA)) := dinA; |
if (clk'event and clk = '1') then |
if (we = '1') then |
RAM(conv_integer(waddr)) <= din; |
end if; |
dout <= RAM(conv_integer(raddr)); |
end if; |
end process; |
|
process (clkB) |
begin |
if rising_edge(clkB) then |
doutB <= RAM(conv_integer(raddrB)); |
end if; |
end process; |
|
end behavorial; |
|
/rtl/vhdl/ram/tdpram_asym.vhd
62,14 → 62,13
device : string := "xilinx" |
); |
port ( |
clk : in std_logic; |
-- port A (widthA)-bit |
clkA : in std_logic; |
addrA : in std_logic_vector(log2((depthB*32)/widthA)-1 downto 0); |
weA : in std_logic; |
dinA : in std_logic_vector(widthA-1 downto 0); |
doutA : out std_logic_vector(widthA-1 downto 0); |
-- port B 32-bit |
clkB : in std_logic; |
addrB : in std_logic_vector(log2(depthB)-1 downto 0); |
weB : in std_logic; |
dinB : in std_logic_vector(31 downto 0); |
92,9 → 91,12
-- - the RAM has two write ports, |
-- - the RAM has only one write port whose data width is maxWIDTH |
-- In all other cases, ram can be a signal. |
shared variable ram : ramType := (others => (others => '0')); |
shared variable ram : ramType := (others => (others => '0')); |
signal clkA : std_logic; |
signal clkB : std_logic; |
|
begin |
clkA <= clk; |
process (clkA) |
begin |
if rising_edge(clkA) then |
105,6 → 107,7
end if; |
end process; |
|
clkB <= clk; |
process (clkB) |
begin |
if rising_edge(clkB) then |
146,9 → 149,9
end generate unpack; |
|
--port B |
process(clkB) |
process(clk) |
begin |
if(rising_edge(clkB)) then |
if(rising_edge(clk)) then |
if(weB = '1') then |
ram(conv_integer(addrB)) <= wB_local; |
end if; |
157,9 → 160,9
end process; |
|
-- port A |
process(clkA) |
process(clk) |
begin |
if(rising_edge(clkA)) then |
if(rising_edge(clk)) then |
doutA <= ram(conv_integer(addrA) / R )(conv_integer(addrA) mod R); |
if(weA ='1') then |
ram(conv_integer(addrA) / R)(conv_integer(addrA) mod R) <= dinA; |
/rtl/vhdl/ram/dpramblock_asym.vhd
62,15 → 62,14
device : string := "xilinx" |
); |
port ( |
-- write port A |
clkA : in std_logic; |
waddrA : in std_logic_vector(log2((width*depth)/32)-1 downto 0); |
weA : in std_logic; |
dinA : in std_logic_vector(31 downto 0); |
-- read port B |
clkB : in std_logic; |
raddrB : in std_logic_vector(log2(depth)-1 downto 0); |
doutB : out std_logic_vector(width-1 downto 0) |
clk : in std_logic; |
-- write port |
waddr : in std_logic_vector(log2((width*depth)/32)-1 downto 0); |
we : in std_logic; |
din : in std_logic_vector(31 downto 0); |
-- read port |
raddr : in std_logic_vector(log2(depth)-1 downto 0); |
dout : out std_logic_vector(width-1 downto 0) |
); |
end dpramblock_asym; |
|
93,20 → 92,18
device => device |
) |
port map( |
|
clk => clk, |
-- write port |
clkA => clkA, |
waddrA => waddrA, |
weA => weA, |
dinA => dinA((i+1)*RAMwrwidth-1 downto RAMwrwidth*i), |
waddr => waddr, |
we => we, |
din => din((i+1)*RAMwrwidth-1 downto RAMwrwidth*i), |
-- read port |
clkB => clkB, |
raddrB => raddrB, |
doutB => dout_RAM(i) |
raddr => raddr, |
dout => dout_RAM(i) |
); |
|
map_output : for j in 0 to nrRAMs-1 generate |
doutB(j*32+(i+1)*RAMwrwidth-1 downto j*32+i*RAMwrwidth) |
dout(j*32+(i+1)*RAMwrwidth-1 downto j*32+i*RAMwrwidth) |
<= dout_RAM(i)((j+1)*RAMwrwidth-1 downto j*RAMwrwidth); |
end generate; |
end generate; |
/rtl/vhdl/ram/tdpramblock_asym.vhd
61,15 → 61,14
width : integer := 512; -- width of portB |
device : string := "xilinx" |
); |
port ( |
port ( |
clk : in std_logic; |
-- port A 32-bit |
clkA : in std_logic; |
addrA : in std_logic_vector(log2((width*depth)/32)-1 downto 0); |
weA : in std_logic; |
dinA : in std_logic_vector(31 downto 0); |
doutA : out std_logic_vector(31 downto 0); |
-- port B (width)-bit |
clkB : in std_logic; |
addrB : in std_logic_vector(log2(depth)-1 downto 0); |
weB : in std_logic; |
dinB : in std_logic_vector(width-1 downto 0); |
96,14 → 95,13
device => device |
) |
port map( |
clk => clk, |
-- port A (widthA)-bit |
clkA => clkA, |
addrA => addrA, |
weA => weA, |
dinA => dinA((i+1)*RAMwidthA-1 downto RAMwidthA*i), |
doutA => doutA((i+1)*RAMwidthA-1 downto RAMwidthA*i), |
-- port B 32-bit |
clkB => clkB, |
addrB => addrB, |
weB => weB, |
dinB => dinB_RAM(i), |
/rtl/vhdl/ram/dpram_asym.vhd
61,16 → 61,15
wrwidth : integer := 2; -- write width, must be smaller than or equal to 32 |
device : string := "xilinx" -- device template to use |
); |
port ( |
port ( |
clk : in std_logic; |
-- write port |
clkA : in std_logic; |
waddrA : in std_logic_vector(log2((rddepth*32)/wrwidth)-1 downto 0); |
weA : in std_logic; |
dinA : in std_logic_vector(wrwidth-1 downto 0); |
waddr : in std_logic_vector(log2((rddepth*32)/wrwidth)-1 downto 0); |
we : in std_logic; |
din : in std_logic_vector(wrwidth-1 downto 0); |
-- read port |
clkB : in std_logic; |
raddrB : in std_logic_vector(log2(rddepth)-1 downto 0); |
doutB : out std_logic_vector(31 downto 0) |
raddr : in std_logic_vector(log2(rddepth)-1 downto 0); |
dout : out std_logic_vector(31 downto 0) |
); |
end dpram_asym; |
|
83,29 → 82,21
xilinx_device : if device="xilinx" generate |
-- the memory |
type ram_type is array (wrdepth-1 downto 0) of std_logic_vector (wrwidth-1 downto 0); |
shared variable RAM : ram_type := (others => (others => '0')); |
signal RAM : ram_type := (others => (others => '0')); |
|
-- xilinx constraint to use blockram resources |
attribute ram_style : string; |
attribute ram_style of RAM:variable is "block"; |
attribute ram_style of ram:signal is "block"; |
begin |
-- Write port A |
process (clkA) |
process (clk) |
begin |
if rising_edge(clkA) then |
if (weA = '1') then |
RAM(conv_integer(waddrA)) := dinA; |
if (clk'event and clk = '1') then |
if (we = '1') then |
RAM(conv_integer(waddr)) <= din; |
end if; |
end if; |
end process; |
|
-- Read port B |
process (clkB) |
begin |
if rising_edge(clkB) then |
for i in 0 to R-1 loop |
doutB((i+1)*wrwidth-1 downto i*wrwidth) |
<= RAM(conv_integer(raddrB & conv_std_logic_vector(i,log2(R)))); |
dout((i+1)*wrwidth-1 downto i*wrwidth) |
<= RAM(conv_integer(raddr & conv_std_logic_vector(i,log2(R)))); |
end loop; |
end if; |
end process; |
116,7 → 107,7
type word_t is array(R-1 downto 0) of std_logic_vector(wrwidth-1 downto 0); |
type ram_t is array (0 to rddepth-1) of word_t; |
|
shared variable ram : ram_t; |
signal ram : ram_t; |
signal q_local : word_t; |
-- altera constraints: |
-- for smal depths: |
127,24 → 118,18
--attribute ramstyle of RAM : signal is "M9K, no_rw_check"; |
begin |
unpack: for i in 0 to R - 1 generate |
doutB(wrwidth*(i+1) - 1 downto wrwidth*i) <= q_local(i); |
dout(wrwidth*(i+1) - 1 downto wrwidth*i) <= q_local(i); |
end generate unpack; |
|
process(clkA) |
process(clk, we) |
begin |
if(rising_edge(clkA)) then |
if(weA = '1') then |
ram(conv_integer(waddrA)/R)(conv_integer(waddrA) mod R) := dinA; |
if(rising_edge(clk)) then |
if(we = '1') then |
ram(conv_integer(waddr)/R)(conv_integer(waddr) mod R) <= din; |
end if; |
q_local <= ram(conv_integer(raddr)); |
end if; |
end process; |
|
process(clkB) |
begin |
if(rising_edge(clkB)) then |
q_local <= ram(conv_integer(raddrB)); |
end if; |
end process; |
end generate; |
|
end behavorial; |
/rtl/vhdl/interface/axi/msec_ipcore_axilite.vhd
112,7 → 112,6
--USER ports |
calc_time : out std_logic; |
IntrEvent : out std_logic; |
core_clk : in std_logic; |
------------------------- |
-- AXI4lite interface |
------------------------- |
388,8 → 387,7
C_FPGA_MAN => C_FPGA_MAN |
) |
port map( |
bus_clk => S_AXI_ACLK, |
core_clk => core_clk, |
clk => S_AXI_ACLK, |
reset => reset, |
-- operand memory interface (plb shared memory) |
write_enable => core_write_enable, |
/rtl/vhdl/core/fifo_primitive.vhd
54,17 → 54,16
|
entity fifo_primitive is |
port ( |
push_clk : in std_logic; |
pop_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 |
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; |
|
87,13 → 86,13
push_i <= push and (not reset_i); |
|
-- makes the reset at least three clk_cycles long |
RESET_PROC: process (reset, push_clk) |
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(push_clk) then |
elsif rising_edge(clk) then |
if clk_counter = 0 then |
clk_counter := 0; |
reset_i <= '0'; |
136,8 → 135,8
RST => reset_i, -- 1-bit reset input |
RSTREG => reset_i, -- 1-bit output register set/reset |
-- WRCLK, RDCLK: 1-bit (each) Clocks |
RDCLK => pop_clk, -- 1-bit read clock input |
WRCLK => push_clk, -- 1-bit write clock input |
RDCLK => clk, -- 1-bit read clock input |
WRCLK => clk, -- 1-bit write clock input |
WREN => push_i -- 1-bit write enable input |
); |
|
/rtl/vhdl/core/fifo_generic.vhd
138,15 → 138,14
depth => depth+1 |
) |
port map( |
clk => clk, |
-- write port |
clkA => clk, |
waddrA => wr_addr, |
weA => push_i_d, |
dinA => din, |
waddr => wr_addr, |
we => push_i_d, |
din => din, |
-- read port |
clkB => clk, |
raddrB => rd_addr, |
doutB => dout |
raddr => rd_addr, |
dout => dout |
); |
|
end arch; |
/rtl/vhdl/core/operand_ram_gen.vhd
61,9 → 61,9
); |
port( |
-- global ports |
clk : in std_logic; |
collision : out std_logic; -- 1 if simultaneous write on RAM |
-- bus side connections (32-bit serial) |
bus_clk : in std_logic; |
write_operand : in std_logic; -- write_enable |
operand_in_sel : in std_logic_vector(log2(depth)-1 downto 0); -- operand to write to |
operand_addr : in std_logic_vector(log2(width/32)-1 downto 0); -- address of operand word to write |
71,7 → 71,6
result_out : out std_logic_vector(31 downto 0); -- operand out, reading is always result operand |
operand_out_sel : in std_logic_vector(log2(depth)-1 downto 0); -- operand to give to multiplier |
-- multiplier side connections (width-bit parallel) |
core_clk : in std_logic; |
result_dest_op : in std_logic_vector(log2(depth)-1 downto 0); -- operand select for result |
operand_out : out std_logic_vector(width-1 downto 0); -- operand out to multiplier |
write_result : in std_logic; -- write enable for multiplier side |
89,22 → 88,22
-- total RAM structure signals |
signal weA_RAM : std_logic_vector(nrRAMs-1 downto 0); |
type wordsplit is array (nrRAMs-1 downto 0) of std_logic_vector(31 downto 0); |
signal doutA_RAM : wordsplit; |
signal doutB_RAM : wordsplit; |
--- PORT A : 32-bit write | (width)-bit read |
signal dinA : std_logic_vector(31 downto 0); |
signal doutA : std_logic_vector(31 downto 0); |
signal doutA : std_logic_vector(width-1 downto 0); |
signal weA : std_logic; |
signal addrA : std_logic_vector(RAMselect_aw-1 downto 0); |
signal op_selA : std_logic_vector(RAMdepth_aw-1 downto 0); |
--- PORT B : 32-bit read | (width)-bit write |
signal dinB : std_logic_vector(width-1 downto 0); |
signal doutB : std_logic_vector(width-1 downto 0); |
signal doutB : std_logic_vector(31 downto 0); |
signal weB : std_logic; |
signal addrB : std_logic_vector(RAMselect_aw-1 downto 0); |
signal op_selB : std_logic_vector(RAMdepth_aw-1 downto 0); |
|
signal write_operand_i : std_logic; |
signal op_selB_i : std_logic_vector(RAMdepth_aw-1 downto 0); |
signal op_selA_i : std_logic_vector(RAMdepth_aw-1 downto 0); |
begin |
|
-- WARNING: Very Important! |
116,29 → 115,29
-- 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_result select |
op_selB_i <= result_dest_op when '1', |
with write_operand_i select |
op_selA_i <= operand_in_sel when '1', |
operand_out_sel when others; |
|
-- map signals to RAM |
-- PORTA |
weA <= write_operand_i; |
op_selA <= operand_in_sel; |
op_selA <= op_selA_i; |
addrA <= operand_addr; |
dinA <= operand_in; |
result_out <= doutA; |
operand_out <= doutA; |
-- PORT B |
weB <= write_result; |
op_selB <= op_selB_i; -- portB locked to result operand |
op_selB <= result_dest_op; -- portB locked to result operand |
addrB <= operand_addr; |
dinB <= result_in; |
operand_out <= doutB; |
result_out <= doutB; |
|
-- generate (width/32) blocks of 32-bit ram with a given depth |
-- these rams are tyed together to form the following structure |
-- True dual port ram: |
-- - PORT A : 32-bit write | 32-bit read |
-- - PORT B : (width)-bit read | (width)-bit write |
-- - PORT A : 32-bit write | (width)-bit read |
-- - PORT B : 32-bit read | (width)-bit write |
-- ^ ^ |
-- addres addr op_sel |
-- |
149,17 → 148,17
) |
port map( |
-- port A : 32-bit |
clkA => bus_clk, |
clkA => clk, |
addrA => op_selA, |
weA => weA_RAM(i), |
dinA => dinA, |
doutA => doutA_RAM(i), |
doutA => doutA(((i+1)*32)-1 downto i*32), |
-- port B : 32-bit |
clkB => core_clk, |
clkB => clk, |
addrB => op_selB, |
weB => weB, |
dinB => dinB(((i+1)*32)-1 downto i*32), |
doutB => doutB(((i+1)*32)-1 downto i*32) |
doutB => doutB_RAM(i) |
); |
-- demultiplexer for write enable A signal |
process (addrA, weA) |
172,7 → 171,7
end process; |
end generate; |
-- PORTB 32-bit read |
doutA <= doutA_RAM(conv_integer(addrA)) when (conv_integer(addrA)<nrRAMs) |
doutB <= doutB_RAM(conv_integer(addrB)) when (conv_integer(addrB)<nrRAMs) |
else (others=>'0'); |
|
end Behavioral; |
/rtl/vhdl/core/operand_ram_asym.vhd
68,9 → 68,9
); |
port( |
-- global ports |
clk : in std_logic; |
collision : out std_logic; -- 1 if simultaneous write on RAM |
-- bus side connections (32-bit serial) |
bus_clk : in std_logic; |
write_operand : in std_logic; -- write_enable |
operand_in_sel : in std_logic_vector(log2(depth)-1 downto 0); -- operand to write to |
operand_addr : in std_logic_vector(log2(width/32)-1 downto 0); -- address of operand word to write |
78,7 → 78,6
result_out : out std_logic_vector(31 downto 0); -- operand out, reading is always result operand |
operand_out_sel : in std_logic_vector(log2(depth)-1 downto 0); -- operand to give to multiplier |
-- multiplier side connections (width-bit parallel) |
core_clk : in std_logic; |
result_dest_op : in std_logic_vector(log2(depth)-1 downto 0); -- operand select for result |
operand_out : out std_logic_vector(width-1 downto 0); -- operand out to multiplier |
write_result : in std_logic; -- write enable for multiplier side |
127,14 → 126,13
device => device |
) |
port map( |
clk => clk, |
-- port A 32-bit |
clkA => bus_clk, |
addrA => addrA_single, |
weA => write_operand_i, |
dinA => operand_in, |
doutA => result_out, |
-- port B (width)-bit |
clkB => core_clk, |
addrB => mult_op_sel, |
weB => write_result, |
dinB => result_in, |
161,14 → 159,13
device => device |
) |
port map( |
clk => clk, |
-- port A 32-bit |
clkA => bus_clk, |
addrA => addrA, |
weA => weA_RAM(i), |
dinA => operand_in, |
doutA => doutA_RAM(i), |
-- port B (width)-bit |
clkB => core_clk, |
addrB => mult_op_sel, |
weB => write_result, |
dinB => result_in((i+1)*RAMblock_maxwidth-1 downto i*RAMblock_maxwidth), |
211,14 → 208,13
device => device |
) |
port map( |
clk => clk, |
-- port A 32-bit |
clkA => bus_clk, |
addrA => addrA_part, |
weA => weA_part, |
dinA => operand_in, |
doutA => doutA_RAM(i), |
-- port B (width)-bit |
clkB => core_clk, |
addrB => mult_op_sel, |
weB => write_result, |
dinB => result_in(width-1 downto i*RAMblock_maxwidth), |
/rtl/vhdl/core/modulus_ram_asym.vhd
64,11 → 64,11
generic( |
width : integer := 1536; -- must be a multiple of 32 |
depth : integer := 2; -- nr of moduluses |
device : string := "altera" |
device : string := "xilinx" |
); |
port( |
clk : in std_logic; |
-- bus side |
bus_clk : in std_logic; |
write_modulus : in std_logic; -- write enable |
modulus_in_sel : in std_logic_vector(log2(depth)-1 downto 0); -- modulus operand to write to |
modulus_addr : in std_logic_vector(log2((width)/32)-1 downto 0); -- modulus word(32-bit) address |
75,7 → 75,6
modulus_in : in std_logic_vector(31 downto 0); -- modulus word data in |
modulus_sel : in std_logic_vector(log2(depth)-1 downto 0); -- selects the modulus to use for multiplications |
-- multiplier side |
core_clk : in std_logic; |
modulus_out : out std_logic_vector(width-1 downto 0) |
); |
end modulus_ram_asym; |
108,15 → 107,14
device => device |
) |
port map( |
clk => clk, |
-- write port |
clkA => bus_clk, |
waddrA => waddr, |
weA => write_modulus, |
dinA => modulus_in, |
waddr => waddr, |
we => write_modulus, |
din => modulus_in, |
-- read port |
clkB => core_clk, |
raddrB => modulus_sel, |
doutB => modulus_out |
raddr => modulus_sel, |
dout => modulus_out |
); |
end generate; |
|
137,15 → 135,14
device => device |
) |
port map( |
clk => clk, |
-- write port |
clkA => bus_clk, |
waddrA => waddr, |
weA => we_RAM(i), |
dinA => modulus_in, |
waddr => waddr, |
we => we_RAM(i), |
din => modulus_in, |
-- read port |
clkB => core_clk, |
raddrB => modulus_sel, |
doutB => modulus_out((i+1)*RAMblock_maxwidth-1 downto i*RAMblock_maxwidth) |
raddr => modulus_sel, |
dout => modulus_out((i+1)*RAMblock_maxwidth-1 downto i*RAMblock_maxwidth) |
); |
-- we |
process (write_modulus, modulus_addr) |
172,15 → 169,14
device => device |
) |
port map( |
clk => clk, |
-- write port |
clkA => bus_clk, |
waddrA => waddr_part, |
weA => we_part, |
dinA => modulus_in, |
waddr => waddr_part, |
we => we_part, |
din => modulus_in, |
-- read port |
clkB => core_clk, |
raddrB => modulus_sel, |
doutB => modulus_out(width-1 downto i*RAMblock_maxwidth) |
raddr => modulus_sel, |
dout => modulus_out(width-1 downto i*RAMblock_maxwidth) |
); |
|
-- we_part |
/rtl/vhdl/core/modulus_ram_gen.vhd
61,8 → 61,8
depth : integer := 2 -- nr of moduluses |
); |
port( |
clk : in std_logic; |
-- bus side |
bus_clk : in std_logic; |
write_modulus : in std_logic; -- write enable |
modulus_in_sel : in std_logic_vector(log2(depth)-1 downto 0); -- modulus operand to write to |
modulus_addr : in std_logic_vector(log2((width)/32)-1 downto 0); -- modulus word(32-bit) address |
69,7 → 69,6
modulus_in : in std_logic_vector(31 downto 0); -- modulus word data in |
modulus_sel : in std_logic_vector(log2(depth)-1 downto 0); -- selects the modulus to use for multiplications |
-- multiplier side |
core_clk : in std_logic; |
modulus_out : out std_logic_vector(width-1 downto 0) |
); |
end modulus_ram_gen; |
97,15 → 96,14
depth => depth |
) |
port map( |
clk => clk, |
-- write port |
clkA => bus_clk, |
waddrA => modulus_wraddr(total_aw-1 downto RAMselect_aw), |
weA => we(i), |
dinA => modulus_in, |
waddr => modulus_wraddr(total_aw-1 downto RAMselect_aw), |
we => we(i), |
din => modulus_in, |
-- read port |
clkB => core_clk, |
raddrB => modulus_rdaddr, |
doutB => modulus_out(((i+1)*32)-1 downto i*32) |
raddr => modulus_rdaddr, |
dout => modulus_out(((i+1)*32)-1 downto i*32) |
); |
-- connect the w |
process (write_modulus, modulus_wraddr) |
/rtl/vhdl/core/mod_sim_exp_pkg.vhd
479,12 → 479,12
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(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(1 downto 0); |
addrb : in std_logic_vector(5 downto 0); |
dinb : in std_logic_vector(511 downto 0); |
doutb : out std_logic_vector(511 downto 0) |
doutb : out std_logic_vector(31 downto 0) |
); |
end component operand_dp; |
|
510,17 → 510,16
-- |
component fifo_primitive is |
port ( |
pop_clk : in std_logic; |
push_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 |
clk : in std_logic; |
din : in std_logic_vector (31 downto 0); |
dout : out std_logic_vector (31 downto 0); |
empty : out std_logic; |
full : out std_logic; |
push : in std_logic; |
pop : in std_logic; |
reset : in std_logic; |
nopop : out std_logic; |
nopush : out std_logic |
); |
end component fifo_primitive; |
|
533,9 → 532,9
component operand_ram is |
port( |
-- global ports |
clk : in std_logic; |
collision : out std_logic; |
-- bus side connections (32-bit serial) |
bus_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); |
542,7 → 541,6
result_out : out std_logic_vector(31 downto 0); |
write_operand : in std_logic; |
-- multiplier side connections (1536 bit parallel) |
core_clk : in std_logic; |
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 |
580,15 → 578,14
depth : integer := 2 |
); |
port ( |
-- write port A |
clkA : in std_logic; |
waddrA : in std_logic_vector(log2(depth)-1 downto 0); |
weA : in std_logic; |
dinA : in std_logic_vector(31 downto 0); |
-- read port B |
clkB : in std_logic; |
raddrB : in std_logic_vector(log2(depth)-1 downto 0); |
doutB : out std_logic_vector(31 downto 0) |
clk : in std_logic; |
-- write port |
waddr : in std_logic_vector(log2(depth)-1 downto 0); |
we : in std_logic; |
din : in std_logic_vector(31 downto 0); |
-- read port |
raddr : in std_logic_vector(log2(depth)-1 downto 0); |
dout : out std_logic_vector(31 downto 0) |
); |
end component dpram_generic; |
|
654,8 → 651,8
depth : integer := 2 -- nr of moduluses |
); |
port( |
clk : in std_logic; |
-- bus side |
bus_clk : in std_logic; |
write_modulus : in std_logic; -- write enable |
modulus_in_sel : in std_logic_vector(log2(depth)-1 downto 0); -- modulus operand to write to |
modulus_addr : in std_logic_vector(log2((width)/32)-1 downto 0); -- modulus word(32-bit) address |
662,7 → 659,6
modulus_in : in std_logic_vector(31 downto 0); -- modulus word data in |
modulus_sel : in std_logic_vector(log2(depth)-1 downto 0); -- selects the modulus to use for multiplications |
-- multiplier side |
core_clk : in std_logic; |
modulus_out : out std_logic_vector(width-1 downto 0) |
); |
end component modulus_ram_gen; |
680,9 → 676,9
); |
port( |
-- global ports |
clk : in std_logic; |
collision : out std_logic; -- 1 if simultaneous write on RAM |
-- bus side connections (32-bit serial) |
bus_clk : in std_logic; |
write_operand : in std_logic; -- write_enable |
operand_in_sel : in std_logic_vector(log2(depth)-1 downto 0); -- operand to write to |
operand_addr : in std_logic_vector(log2(width/32)-1 downto 0); -- address of operand word to write |
690,7 → 686,6
result_out : out std_logic_vector(31 downto 0); -- operand out, reading is always result operand |
operand_out_sel : in std_logic_vector(log2(depth)-1 downto 0); -- operand to give to multiplier |
-- multiplier side connections (width-bit parallel) |
core_clk : in std_logic; |
result_dest_op : in std_logic_vector(log2(depth)-1 downto 0); -- operand select for result |
operand_out : out std_logic_vector(width-1 downto 0); -- operand out to multiplier |
write_result : in std_logic; -- write enable for multiplier side |
711,21 → 706,20
-- asymmetric ram. |
-- |
component dpram_asym is |
generic ( |
generic( |
rddepth : integer := 4; -- nr of 32-bit words |
wrwidth : integer := 2; -- write width, must be smaller than or equal to 32 |
device : string := "xilinx" -- device template to use |
); |
port ( |
port( |
clk : in std_logic; |
-- write port |
clkA : in std_logic; |
waddrA : in std_logic_vector(log2((rddepth*32)/wrwidth)-1 downto 0); |
weA : in std_logic; |
dinA : in std_logic_vector(wrwidth-1 downto 0); |
waddr : in std_logic_vector(log2((rddepth*32)/wrwidth)-1 downto 0); |
we : in std_logic; |
din : in std_logic_vector(wrwidth-1 downto 0); |
-- read port |
clkB : in std_logic; |
raddrB : in std_logic_vector(log2(rddepth)-1 downto 0); |
doutB : out std_logic_vector(31 downto 0) |
raddr : in std_logic_vector(log2(rddepth)-1 downto 0); |
dout : out std_logic_vector(31 downto 0) |
); |
end component dpram_asym; |
|
737,21 → 731,20
-- port. |
-- |
component dpramblock_asym is |
generic ( |
generic( |
width : integer := 256; -- read width |
depth : integer := 2; -- nr of (width)-bit words |
device : string := "xilinx" |
); |
port ( |
-- write port A |
clkA : in std_logic; |
waddrA : in std_logic_vector(log2((width*depth)/32)-1 downto 0); |
weA : in std_logic; |
dinA : in std_logic_vector(31 downto 0); |
-- read port B |
clkB : in std_logic; |
raddrB : in std_logic_vector(log2(depth)-1 downto 0); |
doutB : out std_logic_vector(width-1 downto 0) |
port( |
clk : in std_logic; |
-- write port |
waddr : in std_logic_vector(log2((width*depth)/32)-1 downto 0); |
we : in std_logic; |
din : in std_logic_vector(31 downto 0); |
-- read port |
raddr : in std_logic_vector(log2(depth)-1 downto 0); |
dout : out std_logic_vector(width-1 downto 0) |
); |
end component dpramblock_asym; |
|
764,20 → 757,19
-- altera for asymmetric ram. |
-- |
component tdpram_asym is |
generic ( |
generic( |
depthB : integer := 4; -- nr of 32-bit words |
widthA : integer := 2; -- port A width, must be smaller than or equal to 32 |
device : string := "xilinx" |
); |
port ( |
port( |
clk : in std_logic; |
-- port A (widthA)-bit |
clkA : in std_logic; |
addrA : in std_logic_vector(log2((depthB*32)/widthA)-1 downto 0); |
weA : in std_logic; |
dinA : in std_logic_vector(widthA-1 downto 0); |
doutA : out std_logic_vector(widthA-1 downto 0); |
-- port B 32-bit |
clkB : in std_logic; |
addrB : in std_logic_vector(log2(depthB)-1 downto 0); |
weB : in std_logic; |
dinB : in std_logic_vector(31 downto 0); |
798,15 → 790,14
width : integer := 512; -- width of portB |
device : string := "xilinx" |
); |
port ( |
port ( |
clk : in std_logic; |
-- port A 32-bit |
clkA : in std_logic; |
addrA : in std_logic_vector(log2((width*depth)/32)-1 downto 0); |
weA : in std_logic; |
dinA : in std_logic_vector(31 downto 0); |
doutA : out std_logic_vector(31 downto 0); |
-- port B (width)-bit |
clkB : in std_logic; |
addrB : in std_logic_vector(log2(depth)-1 downto 0); |
weB : in std_logic; |
dinB : in std_logic_vector(width-1 downto 0); |
831,8 → 822,8
device : string := "xilinx" |
); |
port( |
clk : in std_logic; |
-- bus side |
bus_clk : in std_logic; |
write_modulus : in std_logic; -- write enable |
modulus_in_sel : in std_logic_vector(log2(depth)-1 downto 0); -- modulus operand to write to |
modulus_addr : in std_logic_vector(log2((width)/32)-1 downto 0); -- modulus word(32-bit) address |
839,7 → 830,6
modulus_in : in std_logic_vector(31 downto 0); -- modulus word data in |
modulus_sel : in std_logic_vector(log2(depth)-1 downto 0); -- selects the modulus to use for multiplications |
-- multiplier side |
core_clk : in std_logic; |
modulus_out : out std_logic_vector(width-1 downto 0) |
); |
end component modulus_ram_asym; |
862,9 → 852,9
); |
port( |
-- global ports |
clk : in std_logic; |
collision : out std_logic; -- 1 if simultaneous write on RAM |
-- bus side connections (32-bit serial) |
bus_clk : in std_logic; |
write_operand : in std_logic; -- write_enable |
operand_in_sel : in std_logic_vector(log2(depth)-1 downto 0); -- operand to write to |
operand_addr : in std_logic_vector(log2(width/32)-1 downto 0); -- address of operand word to write |
872,7 → 862,6
result_out : out std_logic_vector(31 downto 0); -- operand out, reading is always result operand |
operand_out_sel : in std_logic_vector(log2(depth)-1 downto 0); -- operand to give to multiplier |
-- multiplier side connections (width-bit parallel) |
core_clk : in std_logic; |
result_dest_op : in std_logic_vector(log2(depth)-1 downto 0); -- operand select for result |
operand_out : out std_logic_vector(width-1 downto 0); -- operand out to multiplier |
write_result : in std_logic; -- write enable for multiplier side |
904,14 → 893,14
device : string := "altera" -- xilinx, altera are valid options |
); |
port( |
-- system clock |
clk : in std_logic; |
-- data interface (plb side) |
bus_clk : in std_logic; |
data_in : in std_logic_vector(31 downto 0); |
data_out : out std_logic_vector(31 downto 0); |
rw_address : in std_logic_vector(8 downto 0); |
write_enable : in std_logic; |
-- operand interface (multiplier side) |
core_clk : in std_logic; |
op_sel : in std_logic_vector(log2(nr_op)-1 downto 0); |
xy_out : out std_logic_vector((width-1) downto 0); |
m : out std_logic_vector((width-1) downto 0); |
924,25 → 913,7
); |
end component operand_mem; |
|
---------------------- CLOCK DOMAIN CROSSING ---------------------- |
|
component pulse_cdc is |
port ( |
reset : in std_logic; |
clkA : in std_logic; |
pulseA : in std_logic; |
clkB : in std_logic; |
pulseB : out std_logic |
); |
end component pulse_cdc; |
|
component clk_sync is |
port ( |
sigA : in std_logic; |
clkB : in std_logic; |
sigB : out std_logic |
); |
end component clk_sync; |
|
---------------------------- TOP LEVEL ----------------------------- |
|
960,14 → 931,13
C_NR_STAGES_LOW : integer := 32; |
C_SPLIT_PIPELINE : boolean := true; |
C_FIFO_DEPTH : integer := 32; |
C_MEM_STYLE : string := "asym"; -- xil_prim, generic, asym are valid options |
C_MEM_STYLE : string := "generic"; -- xil_prim, generic, asym are valid options |
C_FPGA_MAN : string := "xilinx" -- xilinx, altera are valid options |
); |
port( |
core_clk : in std_logic; |
reset : in std_logic; |
clk : in std_logic; |
reset : in std_logic; |
-- operand memory interface (plb shared memory) |
bus_clk : in std_logic; |
write_enable : in std_logic; -- write data to operand ram |
data_in : in std_logic_vector (31 downto 0); -- operand ram data in |
rw_address : in std_logic_vector (8 downto 0); -- operand ram address bus |
987,7 → 957,7
dest_op_single : in std_logic_vector (1 downto 0); -- result destination operand selection |
p_sel : in std_logic_vector (1 downto 0); -- pipeline part selection |
calc_time : out std_logic; |
modulus_sel : in std_logic -- selects which modulus to use for multiplications |
modulus_sel : in std_logic -- selects which modulus to use for multiplications |
); |
end component mod_sim_exp_core; |
|
/rtl/vhdl/core/mod_sim_exp_core.vhd
70,10 → 70,9
C_FPGA_MAN : string := "xilinx" -- xilinx, altera are valid options |
); |
port( |
core_clk : in std_logic; |
reset : in std_logic; |
clk : in std_logic; |
reset : in std_logic; |
-- operand memory interface (plb shared memory) |
bus_clk : in std_logic; |
write_enable : in std_logic; -- write data to operand ram |
data_in : in std_logic_vector (31 downto 0); -- operand ram data in |
rw_address : in std_logic_vector (8 downto 0); -- operand ram address bus |
116,10 → 115,6
signal load_x : std_logic; |
signal load_result : std_logic; |
signal modulus_sel_i : std_logic_vector(0 downto 0); |
signal core_ready : std_logic; |
signal core_calc_time : std_logic; |
signal core_collision : std_logic; |
signal core_start : std_logic; |
|
-- fifo signals |
signal fifo_empty : std_logic; |
132,6 → 127,26
report "C_MEM_STYLE incorrect!, it must be one of these: xil_prim, generic or asym" severity failure; |
assert (C_FPGA_MAN="xilinx" or C_FPGA_MAN="altera") |
report "C_FPGA_MAN incorrect!, it must be one of these: xilinx or altera" severity failure; |
|
-- The actual multiplier |
the_multiplier : mont_multiplier |
generic map( |
n => C_NR_BITS_TOTAL, |
t => C_NR_STAGES_TOTAL, |
tl => C_NR_STAGES_LOW, |
split => C_SPLIT_PIPELINE |
) |
port map( |
core_clk => clk, |
xy => xy, |
m => m, |
r => r, |
start => start_mult, |
reset => reset, |
p_sel => p_sel, |
load_x => load_x, |
ready => mult_ready |
); |
|
-- Block ram memory for storing the operands and the modulus |
the_memory : operand_mem |
143,7 → 158,6
device => C_FPGA_MAN |
) |
port map( |
bus_clk => bus_clk, |
data_in => data_in, |
data_out => data_out, |
rw_address => rw_address, |
151,11 → 165,11
op_sel => op_sel, |
xy_out => xy, |
m => m, |
core_clk => core_clk, |
result_in => r, |
load_result => load_result, |
result_dest_op => result_dest_op, |
collision => core_collision, |
collision => collision, |
clk => clk, |
modulus_sel => modulus_sel_i |
); |
|
163,11 → 177,10
result_dest_op <= dest_op_single when exp_m = '0' else "11"; -- in autorun mode we always store the result in operand3 |
|
-- A fifo for exponentiation mode |
-- xil_prim_fifo : if C_MEM_STYLE="xil_prim" generate |
xil_prim_fifo : if C_MEM_STYLE="xil_prim" generate |
the_exponent_fifo : fifo_primitive |
port map( |
push_clk => bus_clk, |
pop_clk => core_clk, |
clk => clk, |
din => fifo_din, |
dout => fifo_dout, |
empty => fifo_empty, |
178,52 → 191,32
nopop => fifo_nopop, |
nopush => fifo_nopush |
); |
-- end generate; |
-- gen_fifo : if (C_MEM_STYLE="generic") or (C_MEM_STYLE="asym") generate |
-- the_exponent_fifo : fifo_generic |
-- generic map( |
-- depth => C_FIFO_DEPTH |
-- ) |
-- port map( |
-- clk => bus_clk, |
-- din => fifo_din, |
-- dout => fifo_dout, |
-- empty => fifo_empty, |
-- full => fifo_full, |
-- push => fifo_push, |
-- pop => fifo_pop, |
-- reset => reset, |
-- nopop => fifo_nopop, |
-- nopush => fifo_nopush |
-- ); |
-- end generate; |
end generate; |
gen_fifo : if (C_MEM_STYLE="generic") or (C_MEM_STYLE="asym") generate |
the_exponent_fifo : fifo_generic |
generic map( |
depth => C_FIFO_DEPTH |
) |
port map( |
clk => clk, |
din => fifo_din, |
dout => fifo_dout, |
empty => fifo_empty, |
full => fifo_full, |
push => fifo_push, |
pop => fifo_pop, |
reset => reset, |
nopop => fifo_nopop, |
nopush => fifo_nopush |
); |
end generate; |
|
-- The actual multiplier |
the_multiplier : mont_multiplier |
generic map( |
n => C_NR_BITS_TOTAL, |
t => C_NR_STAGES_TOTAL, |
tl => C_NR_STAGES_LOW, |
split => C_SPLIT_PIPELINE |
) |
port map( |
core_clk => core_clk, |
xy => xy, |
m => m, |
r => r, |
start => start_mult, |
reset => reset, -- asynchronious reset |
p_sel => p_sel, |
load_x => load_x, |
ready => mult_ready |
); |
|
-- The control logic for the core |
the_control_unit : mont_ctrl |
port map( |
clk => core_clk, |
reset => reset, -- asynchronious reset |
start => core_start, |
clk => clk, |
reset => reset, |
start => start, |
x_sel_single => x_sel_single, |
y_sel_single => y_sel_single, |
run_auto => exp_m, |
230,8 → 223,8
op_buffer_empty => fifo_empty, |
op_sel_buffer => fifo_dout, |
read_buffer => fifo_pop, |
done => core_ready, |
calc_time => core_calc_time, |
done => ready, |
calc_time => calc_time, |
op_sel => op_sel, |
load_x => load_x, |
load_result => load_result, |
238,41 → 231,5
start_multiplier => start_mult, |
multiplier_ready => mult_ready |
); |
|
-- go from bus clock domain to core clock domain |
start_pulse : pulse_cdc |
port map( |
reset => reset, |
clkA => bus_clk, |
pulseA => start, |
clkB => core_clk, |
pulseB => core_start |
); |
|
-- go from core clock domain to bus clock domain |
ready_pulse : pulse_cdc |
port map( |
reset => reset, |
clkA => core_clk, |
pulseA => core_ready, |
clkB => bus_clk, |
pulseB => ready |
); |
|
sync_to_bus_clk : clk_sync |
port map( |
sigA => core_calc_time, |
clkB => bus_clk, |
sigB => calc_time |
); |
|
collision_pulse : pulse_cdc |
port map( |
reset => reset, |
clkA => core_clk, |
pulseA => core_collision, |
clkB => bus_clk, |
pulseB => collision |
); |
|
end Structural; |
/rtl/vhdl/core/operand_dp.vhd
1,50 → 1,75
-------------------------------------------------------------------------------- |
-- (c) Copyright 1995 - 2010 Xilinx, Inc. All rights reserved. -- |
-- -- |
-- This file contains confidential and proprietary information -- |
-- of Xilinx, Inc. and is protected under U.S. and -- |
-- international copyright and other intellectual property -- |
-- laws. -- |
-- -- |
-- DISCLAIMER -- |
-- This disclaimer is not a license and does not grant any -- |
-- rights to the materials distributed herewith. Except as -- |
-- otherwise provided in a valid license issued to you by -- |
-- Xilinx, and to the maximum extent permitted by applicable -- |
-- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND -- |
-- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES -- |
-- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING -- |
-- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON- -- |
-- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and -- |
-- (2) Xilinx shall not be liable (whether in contract or tort, -- |
-- including negligence, or under any other theory of -- |
-- liability) for any loss or damage of any kind or nature -- |
-- related to, arising under or in connection with these -- |
-- materials, including for any direct, or any indirect, -- |
-- special, incidental, or consequential loss or damage -- |
-- (including loss of data, profits, goodwill, or any type of -- |
-- loss or damage suffered as a result of any action brought -- |
-- by a third party) even if such damage or loss was -- |
-- reasonably foreseeable or Xilinx had been advised of the -- |
-- possibility of the same. -- |
-- -- |
-- CRITICAL APPLICATIONS -- |
-- Xilinx products are not designed or intended to be fail- -- |
-- safe, or for use in any application requiring fail-safe -- |
-- performance, such as life-support or safety devices or -- |
-- systems, Class III medical devices, nuclear facilities, -- |
-- applications related to the deployment of airbags, or any -- |
-- other applications that could lead to death, personal -- |
-- injury, or severe property or environmental damage -- |
-- (individually and collectively, "Critical -- |
-- Applications"). Customer assumes the sole risk and -- |
-- liability of any use of Xilinx products in Critical -- |
-- Applications, subject only to applicable laws and -- |
-- regulations governing limitations on product liability. -- |
-- -- |
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS -- |
-- PART OF THIS FILE AT ALL TIMES. -- |
-------------------------------------------------------------------------------- |
---------------------------------------------------------------------- |
---- operand_dp ---- |
---- ---- |
---- This file is part of the ---- |
---- Modular Simultaneous Exponentiation Core project ---- |
---- http://www.opencores.org/cores/mod_sim_exp/ ---- |
---- ---- |
---- Description ---- |
---- 4 x 512 bit dual port ram for the operands ---- |
---- 32 bit read and write for bus side and 512 bit read and ---- |
---- write for multiplier side ---- |
---- ---- |
---- Dependencies: none ---- |
---- ---- |
---- Authors: ---- |
---- - Geoffrey Ottoy, DraMCo research group ---- |
---- - Jonas De Craene, JonasDC@opencores.org ---- |
---- ---- |
---------------------------------------------------------------------- |
---- ---- |
---- Copyright (C) 2011 DraMCo research group and OPENCORES.ORG ---- |
---- ---- |
---- This source file may be used and distributed without ---- |
---- restriction provided that this copyright statement is not ---- |
---- removed from the file and that any derivative work contains ---- |
---- the original copyright notice and the associated disclaimer. ---- |
---- ---- |
---- This source file is free software; you can redistribute it ---- |
---- and/or modify it under the terms of the GNU Lesser General ---- |
---- Public License as published by the Free Software Foundation; ---- |
---- either version 2.1 of the License, or (at your option) any ---- |
---- later version. ---- |
---- ---- |
---- This source is distributed in the hope that it will be ---- |
---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- |
---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- |
---- PURPOSE. See the GNU Lesser General Public License for more ---- |
---- details. ---- |
---- ---- |
---- You should have received a copy of the GNU Lesser General ---- |
---- Public License along with this source; if not, download it ---- |
---- from http://www.opencores.org/lgpl.shtml ---- |
---- ---- |
---------------------------------------------------------------------- |
---------------------------------------------------------------------- |
-- This file is owned and controlled by Xilinx and must be used -- |
-- solely for design, simulation, implementation and creation of -- |
-- design files limited to Xilinx devices or technologies. Use -- |
-- with non-Xilinx devices or technologies is expressly prohibited -- |
-- and immediately terminates your license. -- |
-- -- |
-- XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" -- |
-- SOLELY FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR -- |
-- XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION -- |
-- AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION -- |
-- OR STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS -- |
-- IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT, -- |
-- AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE -- |
-- FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY -- |
-- WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE -- |
-- IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR -- |
-- REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF -- |
-- INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -- |
-- FOR A PARTICULAR PURPOSE. -- |
-- -- |
-- Xilinx products are not intended for use in life support -- |
-- appliances, devices, or systems. Use in such applications are -- |
-- expressly prohibited. -- |
-- -- |
-- (c) Copyright 1995-2009 Xilinx, Inc. -- |
-- All rights reserved. -- |
---------------------------------------------------------------------- |
-- You must compile the wrapper file operand_dp.vhd when simulating |
-- the core, operand_dp. When compiling the wrapper file, be sure to |
-- reference the XilinxCoreLib VHDL simulation library. For detailed |
54,40 → 79,46
-- 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; |
|
library ieee; |
use ieee.std_logic_1164.ALL; |
-- synthesis translate_off |
Library XilinxCoreLib; |
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(31 downto 0); |
clkb: in std_logic; |
web: in std_logic_vector(0 downto 0); |
addrb: in std_logic_vector(1 downto 0); |
dinb: in std_logic_vector(511 downto 0); |
doutb: out std_logic_vector(511 downto 0)); |
END operand_dp; |
|
ARCHITECTURE operand_dp_a OF operand_dp IS |
|
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(31 downto 0); |
clkb: in std_logic; |
web: in std_logic_vector(0 downto 0); |
addrb: in std_logic_vector(1 downto 0); |
dinb: in std_logic_vector(511 downto 0); |
doutb: out std_logic_vector(511 downto 0)); |
end component; |
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) |
100,10 → 131,10
c_has_injecterr => 0, |
c_rst_type => "SYNC", |
c_prim_type => 1, |
c_read_width_b => 512, |
c_read_width_b => 32, |
c_initb_val => "0", |
c_family => "virtex6", |
c_read_width_a => 32, |
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", |
121,7 → 152,7
c_inita_val => "0", |
c_has_mux_output_regs_a => 0, |
c_addra_width => 6, |
c_addrb_width => 2, |
c_addrb_width => 6, |
c_default_data => "0", |
c_use_ecc => 0, |
c_algorithm => 1, |
128,8 → 159,8
c_disable_warn_bhv_range => 0, |
c_write_width_b => 512, |
c_write_width_a => 32, |
c_read_depth_b => 4, |
c_read_depth_a => 64, |
c_read_depth_b => 64, |
c_read_depth_a => 4, |
c_byte_size => 9, |
c_sim_collision_check => "ALL", |
c_common_clk => 0, |
141,23 → 172,24
c_use_byte_wea => 0, |
c_rst_priority_b => "CE", |
c_rst_priority_a => "CE", |
c_use_default_data => 0); |
c_use_default_data => 0 |
); |
-- synthesis translate_on |
BEGIN |
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); |
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; |
|
end operand_dp_a; |
/rtl/vhdl/core/operand_mem.vhd
72,17 → 72,17
nr_op : integer := 4; -- nr of operand storages, has to be greater than nr_m |
nr_m : integer := 2; -- nr of modulus storages |
mem_style : string := "asym"; -- xil_prim, generic, asym are valid options |
device : string := "xilinx" -- xilinx, altera are valid options |
device : string := "altera" -- xilinx, altera are valid options |
); |
port( |
-- system clock |
clk : in std_logic; |
-- data interface (plb side) |
bus_clk : in std_logic; |
data_in : in std_logic_vector(31 downto 0); |
data_out : out std_logic_vector(31 downto 0); |
rw_address : in std_logic_vector(8 downto 0); |
write_enable : in std_logic; |
-- operand interface (multiplier side) |
core_clk : in std_logic; |
op_sel : in std_logic_vector(log2(nr_op)-1 downto 0); |
xy_out : out std_logic_vector((width-1) downto 0); |
m : out std_logic_vector((width-1) downto 0); |
132,8 → 132,7
-- xy operand storage |
xy_ram_xil : operand_ram |
port map( |
bus_clk => bus_clk, |
core_clk => core_clk, |
clk => clk, |
collision => collision, |
operand_addr => xy_addr_i, |
operand_in => xy_data_i, |
150,7 → 149,7
-- modulus storage |
m_ram_xil : modulus_ram |
port map( |
clk => bus_clk, |
clk => clk, |
modulus_addr => m_addr_i, |
write_modulus => load_m, |
modulus_in => m_data_i, |
166,8 → 165,8
depth => nr_op |
) |
port map( |
clk => clk, |
collision => collision, |
bus_clk => bus_clk, |
operand_addr => xy_addr_i, |
operand_in => xy_data_i, |
operand_in_sel => operand_in_sel_i, |
176,7 → 175,6
operand_out => xy_out, |
operand_out_sel => op_sel, |
result_dest_op => result_dest_op, |
core_clk => core_clk, |
write_result => load_result, |
result_in => result_in |
); |
188,12 → 186,11
depth => nr_m |
) |
port map( |
bus_clk => bus_clk, |
clk => clk, |
modulus_in_sel => modulus_in_sel_i, |
modulus_addr => m_addr_i, |
write_modulus => load_m, |
modulus_in => m_data_i, |
core_clk => core_clk, |
modulus_out => m, |
modulus_sel => modulus_sel |
); |
208,8 → 205,8
device => device |
) |
port map( |
clk => clk, |
collision => collision, |
bus_clk => bus_clk, |
operand_addr => xy_addr_i, |
operand_in => xy_data_i, |
operand_in_sel => operand_in_sel_i, |
218,7 → 215,6
operand_out => xy_out, |
operand_out_sel => op_sel, |
result_dest_op => result_dest_op, |
core_clk => core_clk, |
write_result => load_result, |
result_in => result_in |
); |
231,12 → 227,11
device => device |
) |
port map( |
bus_clk => bus_clk, |
clk => clk, |
modulus_in_sel => modulus_in_sel_i, |
modulus_addr => m_addr_i, |
write_modulus => load_m, |
modulus_in => m_data_i, |
core_clk => core_clk, |
modulus_out => m, |
modulus_sel => modulus_sel |
); |
/rtl/vhdl/core/operand_ram.vhd
55,9 → 55,9
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) |
bus_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); |
64,7 → 64,6
result_out : out std_logic_vector(31 downto 0); |
write_operand : in std_logic; |
-- multiplier side connections (1536 bit parallel) |
core_clk : in std_logic; |
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 |
82,11 → 81,11
signal write_operand_i : std_logic; |
|
-- port b signals |
signal addrb : std_logic_vector(1 downto 0); |
signal addrb : std_logic_vector(5 downto 0); |
signal web : std_logic_vector(0 downto 0); |
signal douta0 : std_logic_vector(31 downto 0); |
signal douta1 : std_logic_vector(31 downto 0); |
signal douta2 : std_logic_vector(31 downto 0); |
signal doutb0 : std_logic_vector(31 downto 0); |
signal doutb1 : std_logic_vector(31 downto 0); |
signal doutb2 : std_logic_vector(31 downto 0); |
|
begin |
|
100,70 → 99,70
-- 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_result select |
addrb <= result_dest_op when '1', |
operand_out_sel when others; |
with write_operand_i select |
addra <= operand_in_sel & operand_addr(3 downto 0) when '1', |
operand_out_sel & "0000" when others; |
|
|
|
with operand_addr(5 downto 4) select |
part_enable <= "0001" when "00", |
"0010" when "01", |
"0100" when "10", |
"1000" when others; |
|
with write_operand_i select |
wea <= part_enable when '1', |
"0000" when others; |
|
-- we can only read back from the result (stored in result_dest_op) |
addrb <= result_dest_op & operand_addr(3 downto 0); |
|
|
with write_operand select |
wea <= part_enable when '1', |
"0000" when others; |
|
addra <= operand_in_sel & operand_addr(3 downto 0); |
|
with operand_addr(5 downto 4) select |
result_out <= douta0 when "00", |
douta1 when "01", |
douta2 when others; |
result_out <= doutb0 when "00", |
doutb1 when "01", |
doutb2 when others; |
|
-- 3 instances of a dual port ram to store the parts of the operand |
op_0 : operand_dp |
port map ( |
clka => bus_clk, |
clka => clk, |
wea => wea(0 downto 0), |
addra => addra, |
dina => operand_in, |
douta => douta0, |
clkb => core_clk, |
douta => operand_out(511 downto 0), |
clkb => clk, |
web => web, |
addrb => addrb, |
dinb => result_in(511 downto 0), |
doutb => operand_out(511 downto 0) |
doutb => doutb0 |
); |
|
op_1 : operand_dp |
port map ( |
clka => bus_clk, |
clka => clk, |
wea => wea(1 downto 1), |
addra => addra, |
dina => operand_in, |
douta => douta1, |
clkb => core_clk, |
douta => operand_out(1023 downto 512), |
clkb => clk, |
web => web, |
addrb => addrb, |
dinb => result_in(1023 downto 512), |
doutb => operand_out(1023 downto 512) |
doutb => doutb1 |
); |
|
op_2 : operand_dp |
port map ( |
clka => bus_clk, |
clka => clk, |
wea => wea(2 downto 2), |
addra => addra, |
dina => operand_in, |
douta => douta2, |
clkb => core_clk, |
douta => operand_out(1535 downto 1024), |
clkb => clk, |
web => web, |
addrb => addrb, |
dinb => result_in(1535 downto 1024), |
doutb => operand_out(1535 downto 1024) |
doutb => doutb2 |
); |
|
end Behavioral; |
/sim/Makefile
4,7 → 4,7
HDL_DIR = ../rtl/vhdl/ |
|
## |
# avs_aes hdl files |
# hdl files |
## |
CORE_SRC =$(HDL_DIR)core/std_functions.vhd \ |
$(HDL_DIR)core/mod_sim_exp_pkg.vhd \ |