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/rtl
- from Rev 91 to Rev 94
- ↔ Reverse comparison
Rev 91 → Rev 94
/verilog/generic_fifo_dc.v
0,0 → 1,304
///////////////////////////////////////////////////////////////////// |
//// //// |
//// Universal FIFO Dual Clock //// |
//// //// |
//// //// |
//// Author: Rudolf Usselmann //// |
//// rudi@asics.ws //// |
//// //// |
//// //// |
//// D/L from: http://www.opencores.org/cores/generic_fifos/ //// |
//// //// |
///////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000-2002 Rudolf Usselmann //// |
//// www.asics.ws //// |
//// rudi@asics.ws //// |
//// //// |
//// 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 SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// |
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// |
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// |
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// |
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// |
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// |
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// |
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// |
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// |
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// |
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// |
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// |
//// POSSIBILITY OF SUCH DAMAGE. //// |
//// //// |
///////////////////////////////////////////////////////////////////// |
|
//// Some minor modifactions are done by Jonas De Craene, JonasDC@opencores.org |
//// in this version. The FIFO output is now registered and push and pop |
//// only works if not full or empty. |
//// The rst signal is removed, now clr is the only reset. |
//// nopush and nopop signal are added to indicate if a push or pop operation |
//// is not executed. |
//// and the memory used in the FIFO is now the same from the mod_sim_exp |
//// opencores project |
|
// CVS Log |
// |
// $Id: generic_fifo_dc.v,v 1.1.1.1 2002-09-25 05:42:02 rudi Exp $ |
// |
// $Date: 2002-09-25 05:42:02 $ |
// $Revision: 1.1.1.1 $ |
// $Author: rudi $ |
// $Locker: $ |
// $State: Exp $ |
// |
// Change History: |
// $Log: not supported by cvs2svn $ |
// |
// |
// |
// |
// |
// |
// |
// |
// |
// |
|
//`include "timescale.v" |
|
/* |
|
Description |
=========== |
|
I/Os |
---- |
rd_clk Read Port Clock |
wr_clk Write Port Clock |
rst low active, either sync. or async. master reset (see below how to select) |
clr synchronous clear (just like reset but always synchronous), high active |
re read enable, synchronous, high active |
we read enable, synchronous, high active |
din Data Input |
dout Data Output |
|
full Indicates the FIFO is full (driven at the rising edge of wr_clk) |
empty Indicates the FIFO is empty (driven at the rising edge of rd_clk) |
|
full_n Indicates if the FIFO has space for N entries (driven of wr_clk) |
empty_n Indicates the FIFO has at least N entries (driven of rd_clk) |
|
level indicates the FIFO level: |
2'b00 0-25% full |
2'b01 25-50% full |
2'b10 50-75% full |
2'b11 %75-100% full |
|
Status Timing |
------------- |
All status outputs are registered. They are asserted immediately |
as the full/empty condition occurs, however, there is a 2 cycle |
delay before they are de-asserted once the condition is not true |
anymore. |
|
Parameters |
---------- |
The FIFO takes 3 parameters: |
dw Data bus width |
aw Address bus width (Determines the FIFO size by evaluating 2^aw) |
n N is a second status threshold constant for full_n and empty_n |
If you have no need for the second status threshold, do not |
connect the outputs and the logic should be removed by your |
synthesis tool. |
|
Synthesis Results |
----------------- |
In a Spartan 2e a 8 bit wide, 8 entries deep FIFO, takes 85 LUTs and runs |
at about 116 MHz (IO insertion disabled). The registered status outputs |
are valid after 2.1NS, the combinatorial once take out to 6.5 NS to be |
available. |
|
Misc |
---- |
This design assumes you will do appropriate status checking externally. |
|
IMPORTANT ! writing while the FIFO is full or reading while the FIFO is |
empty will place the FIFO in an undefined state. |
|
*/ |
|
module generic_fifo_dc(rd_clk, wr_clk, clr, din, we, dout, re, |
full, empty, full_n, empty_n, level, nopop, nopush ); |
|
parameter dw=32; |
parameter aw=7; |
parameter n=32; |
parameter max_size = 1<<aw; |
|
input rd_clk, wr_clk, clr; |
input [dw-1:0] din; |
input we; |
output [dw-1:0] dout; |
input re; |
output full; |
output empty; |
output full_n; |
output empty_n; |
output [1:0] level; |
output nopop; |
output nopush; |
|
//////////////////////////////////////////////////////////////////// |
// |
// Local Wires |
// |
|
reg [aw:0] wp; |
wire [aw:0] wp_pl1; |
reg [aw:0] rp; |
wire [aw:0] rp_pl1; |
reg [aw:0] wp_s, rp_s; |
wire [aw:0] diff; |
reg [aw:0] diff_r1, diff_r2; |
reg re_r, we_r; |
reg full, empty, full_n, empty_n; |
reg [1:0] level; |
wire [dw-1:0] dout_ram; |
reg [dw-1:0] dout; |
reg nopop, nopush; |
|
//////////////////////////////////////////////////////////////////// |
// |
// Memory Block |
// |
|
dpram_generic #(2**aw) u0( |
.clkA(wr_clk), |
.waddrA(wp[aw-1:0]), |
.weA(we & !full), |
.dinA(din), |
.clkB(rd_clk), |
.raddrB(rp[aw-1:0]), |
.doutB(dout_ram) |
); |
|
always @(posedge rd_clk) |
if(re & !empty) dout <= #1 dout_ram; |
|
//generic_dpram #(aw, dw)u0( |
// .rclk(rd_clk), |
// .rrst( !rst), |
// .rce(1'b1), |
// .oe(1'b1), |
// .raddr(rp[aw-1:0]), |
// .do(dout), |
// .wclk(wr_clk), |
// .wrst( !rst), |
// .wce(1'b1), |
// .we(we), |
// .waddr(wp[aw-1:0]), |
// .di(din) |
// ); |
|
//////////////////////////////////////////////////////////////////// |
// |
// Read/Write Pointers Logic |
// |
|
always @(posedge wr_clk) |
if(clr) wp <= #1 {aw+1{1'b0}}; |
else |
if(we & !full) wp <= #1 wp_pl1; |
|
assign wp_pl1 = wp + { {aw{1'b0}}, 1'b1}; |
|
always @(posedge rd_clk) |
if(clr) rp <= #1 {aw+1{1'b0}}; |
else |
if(re & !empty) rp <= #1 rp_pl1; |
|
assign rp_pl1 = rp + { {aw{1'b0}}, 1'b1}; |
|
//////////////////////////////////////////////////////////////////// |
// |
// Synchronization Logic |
// |
|
// write pointer |
always @(posedge rd_clk) wp_s <= #1 wp; |
|
// read pointer |
always @(posedge wr_clk) rp_s <= #1 rp; |
|
//////////////////////////////////////////////////////////////////// |
// |
// Registered Full & Empty Flags |
// |
|
always @(posedge rd_clk) |
empty <= #1 (wp_s == rp) | (re & (wp_s == rp_pl1)); |
|
always @(posedge wr_clk) |
full <= #1 ((wp[aw-1:0] == rp_s[aw-1:0]) & (wp[aw] != rp_s[aw])) | |
(we & (wp_pl1[aw-1:0] == rp_s[aw-1:0]) & (wp_pl1[aw] != rp_s[aw])); |
|
//////////////////////////////////////////////////////////////////// |
// |
// Registered Full_n & Empty_n Flags |
// |
|
assign diff = wp-rp; |
|
always @(posedge rd_clk) |
re_r <= #1 re; |
|
always @(posedge rd_clk) |
diff_r1 <= #1 diff; |
|
always @(posedge rd_clk) |
empty_n <= #1 (diff_r1 < n) | ((diff_r1==n) & (re | re_r)); |
|
always @(posedge wr_clk) |
we_r <= #1 we; |
|
always @(posedge wr_clk) |
diff_r2 <= #1 diff; |
|
always @(posedge wr_clk) |
full_n <= #1 (diff_r2 > max_size-n) | ((diff_r2==max_size-n) & (we | we_r)); |
|
always @(posedge wr_clk) |
level <= #1 {2{diff[aw]}} | diff[aw-1:aw-2]; |
|
//////////////////////////////////////////////////////////////////// |
// |
// nopop & nopush Flags |
// |
|
always @(posedge rd_clk) |
nopop <= #1 ((re & empty) | (re & clr)); |
|
always @(posedge wr_clk) |
nopush <= #1 ((we & full) | (we & clr)); |
|
//////////////////////////////////////////////////////////////////// |
// |
// Sanity Check |
// |
|
// synopsys translate_off |
always @(posedge wr_clk) |
if(we & full) |
$display("%m WARNING: Writing while fifo is FULL (%t)",$time); |
|
always @(posedge rd_clk) |
if(re & empty) |
$display("%m WARNING: Reading while fifo is EMPTY (%t)",$time); |
// synopsys translate_on |
|
endmodule |
|
/verilog/generic_fifo_dc_gray.v
0,0 → 1,333
///////////////////////////////////////////////////////////////////// |
//// //// |
//// Universal FIFO Dual Clock, gray encoded //// |
//// //// |
//// //// |
//// Author: Rudolf Usselmann //// |
//// rudi@asics.ws //// |
//// //// |
//// //// |
//// D/L from: http://www.opencores.org/cores/generic_fifos/ //// |
//// //// |
///////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000-2002 Rudolf Usselmann //// |
//// www.asics.ws //// |
//// rudi@asics.ws //// |
//// //// |
//// 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 SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// |
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// |
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// |
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// |
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// |
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// |
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// |
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// |
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// |
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// |
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// |
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// |
//// POSSIBILITY OF SUCH DAMAGE. //// |
//// //// |
///////////////////////////////////////////////////////////////////// |
|
//// Some minor modifactions are done by Jonas De Craene, JonasDC@opencores.org |
//// in this version. The FIFO output is now registered and push and pop |
//// only works if not full or empty. |
//// The rst signal is removed, now clr is the only reset. |
//// nopush and nopop signal are added to indicate if a push or pop operation |
//// is not executed. |
//// and the memory used in the FIFO is now the same from the mod_sim_exp |
//// opencores project |
|
// CVS Log |
// |
// $Id: generic_fifo_dc_gray.v,v 1.2 2004-01-13 09:11:55 rudi Exp $ |
// |
// $Date: 2004-01-13 09:11:55 $ |
// $Revision: 1.2 $ |
// $Author: rudi $ |
// $Locker: $ |
// $State: Exp $ |
// |
// Change History: |
// $Log: not supported by cvs2svn $ |
// Revision 1.1 2003/10/14 09:34:41 rudi |
// Dual clock FIFO Gray Code encoded version. |
// |
// |
// |
// |
// |
|
|
//`include "timescale.v" |
|
/* |
|
Description |
=========== |
|
I/Os |
---- |
rd_clk Read Port Clock |
wr_clk Write Port Clock |
rst low active, either sync. or async. master reset (see below how to select) |
clr synchronous clear (just like reset but always synchronous), high active |
re read enable, synchronous, high active |
we read enable, synchronous, high active |
din Data Input |
dout Data Output |
|
full Indicates the FIFO is full (driven at the rising edge of wr_clk) |
empty Indicates the FIFO is empty (driven at the rising edge of rd_clk) |
|
wr_level indicates the FIFO level: |
2'b00 0-25% full |
2'b01 25-50% full |
2'b10 50-75% full |
2'b11 %75-100% full |
|
rd_level indicates the FIFO level: |
2'b00 0-25% empty |
2'b01 25-50% empty |
2'b10 50-75% empty |
2'b11 %75-100% empty |
|
Status Timing |
------------- |
All status outputs are registered. They are asserted immediately |
as the full/empty condition occurs, however, there is a 2 cycle |
delay before they are de-asserted once the condition is not true |
anymore. |
|
Parameters |
---------- |
The FIFO takes 2 parameters: |
dw Data bus width |
aw Address bus width (Determines the FIFO size by evaluating 2^aw) |
|
Synthesis Results |
----------------- |
In a Spartan 2e a 8 bit wide, 8 entries deep FIFO, takes 97 LUTs and runs |
at about 113 MHz (IO insertion disabled). |
|
Misc |
---- |
This design assumes you will do appropriate status checking externally. |
|
IMPORTANT ! writing while the FIFO is full or reading while the FIFO is |
empty will place the FIFO in an undefined state. |
|
*/ |
|
|
module generic_fifo_dc_gray( rd_clk, wr_clk, clr, din, we, |
dout, re, full, empty, wr_level, rd_level, nopop, nopush ); |
|
parameter dw=32; |
parameter aw=7; |
|
input rd_clk, wr_clk, clr; |
input [dw-1:0] din; |
input we; |
output [dw-1:0] dout; |
input re; |
output full; |
output empty; |
output [1:0] wr_level; |
output [1:0] rd_level; |
output nopop; |
output nopush; |
|
//////////////////////////////////////////////////////////////////// |
// |
// Local Wires |
// |
|
reg [aw:0] wp_bin, wp_gray; |
reg [aw:0] rp_bin, rp_gray; |
reg [aw:0] wp_s, rp_s; |
reg full, empty; |
|
wire [aw:0] wp_bin_next, wp_gray_next; |
wire [aw:0] rp_bin_next, rp_gray_next; |
|
wire [aw:0] wp_bin_x, rp_bin_x; |
reg [aw-1:0] d1, d2; |
|
reg rd_clr, wr_clr; |
reg rd_clr_r, wr_clr_r; |
wire [dw-1:0] dout_ram; |
reg [dw-1:0] dout; |
reg nopop, nopush; |
|
//////////////////////////////////////////////////////////////////// |
// |
// Reset Logic |
// |
|
always @(posedge rd_clk or posedge clr) |
if(clr) rd_clr <= 1'b1; |
else |
if(!rd_clr_r) rd_clr <= 1'b0; // Release Clear |
|
always @(posedge rd_clk or posedge clr) |
if(clr) rd_clr_r <= 1'b1; |
else rd_clr_r <= 1'b0; |
|
always @(posedge wr_clk or posedge clr) |
if(clr) wr_clr <= 1'b1; |
else |
if(!wr_clr_r) wr_clr <= 1'b0; // Release Clear |
|
always @(posedge wr_clk or posedge clr) |
if(clr) wr_clr_r <= 1'b1; |
else wr_clr_r <= 1'b0; |
|
//////////////////////////////////////////////////////////////////// |
// |
// Memory Block |
// |
|
|
dpram_generic #(2**aw) u0( |
.clkA(wr_clk), |
.waddrA(wp_bin[aw-1:0]), |
.weA(we & !full), |
.dinA(din), |
.clkB(rd_clk), |
.raddrB(rp_bin[aw-1:0]), |
.doutB(dout_ram) |
); |
|
//generic_dpram #(aw,dw) u0( |
// .rclk( rd_clk ), |
// .rrst( !rd_rst ), |
// .rce( 1'b1 ), |
// .oe( 1'b1 ), |
// .raddr( rp_bin[aw-1:0] ), |
// .do( dout ), |
// .wclk( wr_clk ), |
// .wrst( !wr_rst ), |
// .wce( 1'b1 ), |
// .we( we ), |
// .waddr( wp_bin[aw-1:0] ), |
// .di( din ) |
// ); |
|
always @(posedge rd_clk) |
if(re & !empty) dout <= #1 dout_ram; |
|
//////////////////////////////////////////////////////////////////// |
// |
// Read/Write Pointers Logic |
// |
|
always @(posedge wr_clk) |
if(wr_clr) wp_bin <= {aw+1{1'b0}}; |
else |
if(we & !full) wp_bin <= wp_bin_next; |
|
always @(posedge wr_clk) |
if(wr_clr) wp_gray <= {aw+1{1'b0}}; |
else |
if(we & !full) wp_gray <= wp_gray_next; |
|
assign wp_bin_next = wp_bin + {{aw{1'b0}},1'b1}; |
assign wp_gray_next = wp_bin_next ^ {1'b0, wp_bin_next[aw:1]}; |
|
always @(posedge rd_clk) |
if(rd_clr) rp_bin <= {aw+1{1'b0}}; |
else |
if(re & !empty) rp_bin <= rp_bin_next; |
|
always @(posedge rd_clk) |
if(rd_clr) rp_gray <= {aw+1{1'b0}}; |
else |
if(re & !empty) rp_gray <= rp_gray_next; |
|
assign rp_bin_next = rp_bin + {{aw{1'b0}},1'b1}; |
assign rp_gray_next = rp_bin_next ^ {1'b0, rp_bin_next[aw:1]}; |
|
//////////////////////////////////////////////////////////////////// |
// |
// Synchronization Logic |
// |
|
// write pointer |
always @(posedge rd_clk) wp_s <= wp_gray; |
|
// read pointer |
always @(posedge wr_clk) rp_s <= rp_gray; |
|
//////////////////////////////////////////////////////////////////// |
// |
// Registered Full & Empty Flags |
// |
|
assign wp_bin_x = wp_s ^ {1'b0, wp_bin_x[aw:1]}; // convert gray to binary |
assign rp_bin_x = rp_s ^ {1'b0, rp_bin_x[aw:1]}; // convert gray to binary |
|
always @(posedge rd_clk) |
empty <= (wp_s == rp_gray) | (re & (wp_s == rp_gray_next)); |
|
always @(posedge wr_clk) |
full <= ((wp_bin[aw-1:0] == rp_bin_x[aw-1:0]) & (wp_bin[aw] != rp_bin_x[aw])) | |
(we & (wp_bin_next[aw-1:0] == rp_bin_x[aw-1:0]) & (wp_bin_next[aw] != rp_bin_x[aw])); |
|
//////////////////////////////////////////////////////////////////// |
// |
// nopop & nopush Flags |
// |
|
always @(posedge rd_clk) |
nopop <= #1 ((re & empty) | (re & clr)); |
|
always @(posedge wr_clk) |
nopush <= #1 ((we & full) | (we & clr)); |
|
//////////////////////////////////////////////////////////////////// |
// |
// Registered Level Indicators |
// |
reg [1:0] wr_level; |
reg [1:0] rd_level; |
reg [aw-1:0] wp_bin_xr, rp_bin_xr; |
reg full_rc; |
reg full_wc; |
|
always @(posedge wr_clk) full_wc <= full; |
always @(posedge wr_clk) rp_bin_xr <= ~rp_bin_x[aw-1:0] + {{aw-1{1'b0}}, 1'b1}; |
always @(posedge wr_clk) d1 <= wp_bin[aw-1:0] + rp_bin_xr[aw-1:0]; |
|
always @(posedge wr_clk) wr_level <= {d1[aw-1] | full | full_wc, d1[aw-2] | full | full_wc}; |
|
always @(posedge rd_clk) wp_bin_xr <= ~wp_bin_x[aw-1:0]; |
always @(posedge rd_clk) d2 <= rp_bin[aw-1:0] + wp_bin_xr[aw-1:0]; |
|
always @(posedge rd_clk) full_rc <= full; |
always @(posedge rd_clk) rd_level <= full_rc ? 2'h0 : {d2[aw-1] | empty, d2[aw-2] | empty}; |
|
//////////////////////////////////////////////////////////////////// |
// |
// Sanity Check |
// |
|
// synopsys translate_off |
always @(posedge wr_clk) |
if(we && full) |
$display("%m WARNING: Writing while fifo is FULL (%t)",$time); |
|
always @(posedge rd_clk) |
if(re && empty) |
$display("%m WARNING: Reading while fifo is EMPTY (%t)",$time); |
// synopsys translate_on |
|
endmodule |
|
/vhdl/ram/dpram_generic.vhd
56,14 → 56,15
depth : integer := 2 |
); |
port ( |
clk : in std_logic; |
-- write port |
waddr : in std_logic_vector(log2(depth)-1 downto 0); |
we : in std_logic; |
din : in std_logic_vector(31 downto 0); |
-- read port |
raddr : in std_logic_vector(log2(depth)-1 downto 0); |
dout : out std_logic_vector(31 downto 0) |
-- 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) |
); |
end dpram_generic; |
|
70,11 → 71,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); |
signal RAM : ram_type := (others => (others => '0')); |
shared variable RAM : ram_type := (others => (others => '0')); |
|
-- xilinx constraint to use blockram resources |
attribute ram_style : string; |
attribute ram_style of ram:signal is "block"; |
attribute ram_style of ram:variable is "block"; |
-- altera constraints: |
-- for smal depths: |
-- if the synthesis option "allow any size of RAM to be inferred" is on, these lines |
81,16 → 82,23
-- may be left commented. |
-- uncomment this attribute if that option is off and you know wich primitives should be used. |
--attribute ramstyle : string; |
--attribute ramstyle of RAM : signal is "M9K, no_rw_check"; |
--attribute ramstyle of RAM : variable is "M9K, no_rw_check"; |
begin |
process (clk) |
process (clkA) |
begin |
if (clk'event and clk = '1') then |
if (we = '1') then |
RAM(conv_integer(waddr)) <= din; |
if rising_edge(clkA) then |
if (weA = '1') then |
RAM(conv_integer(waddrA)) := dinA; |
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; |
|
/vhdl/ram/tdpram_asym.vhd
62,13 → 62,14
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); |
91,12 → 92,9
-- - the RAM has two write ports, |
-- - the RAM has only one write port whose data width is maxWIDTH |
-- In all other cases, ram can be a signal. |
shared variable ram : ramType := (others => (others => '0')); |
signal clkA : std_logic; |
signal clkB : std_logic; |
shared variable ram : ramType := (others => (others => '0')); |
|
begin |
clkA <= clk; |
process (clkA) |
begin |
if rising_edge(clkA) then |
107,7 → 105,6
end if; |
end process; |
|
clkB <= clk; |
process (clkB) |
begin |
if rising_edge(clkB) then |
149,9 → 146,9
end generate unpack; |
|
--port B |
process(clk) |
process(clkB) |
begin |
if(rising_edge(clk)) then |
if(rising_edge(clkB)) then |
if(weB = '1') then |
ram(conv_integer(addrB)) <= wB_local; |
end if; |
160,9 → 157,9
end process; |
|
-- port A |
process(clk) |
process(clkA) |
begin |
if(rising_edge(clk)) then |
if(rising_edge(clkA)) 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; |
/vhdl/ram/dpramblock_asym.vhd
62,14 → 62,15
device : string := "xilinx" |
); |
port ( |
clk : in std_logic; |
-- write port |
waddr : in std_logic_vector(log2((width*depth)/32)-1 downto 0); |
we : in std_logic; |
din : in std_logic_vector(31 downto 0); |
-- read port |
raddr : in std_logic_vector(log2(depth)-1 downto 0); |
dout : out std_logic_vector(width-1 downto 0) |
-- 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) |
); |
end dpramblock_asym; |
|
92,18 → 93,20
device => device |
) |
port map( |
clk => clk, |
|
-- write port |
waddr => waddr, |
we => we, |
din => din((i+1)*RAMwrwidth-1 downto RAMwrwidth*i), |
clkA => clkA, |
waddrA => waddrA, |
weA => weA, |
dinA => dinA((i+1)*RAMwrwidth-1 downto RAMwrwidth*i), |
-- read port |
raddr => raddr, |
dout => dout_RAM(i) |
clkB => clkB, |
raddrB => raddrB, |
doutB => dout_RAM(i) |
); |
|
map_output : for j in 0 to nrRAMs-1 generate |
dout(j*32+(i+1)*RAMwrwidth-1 downto j*32+i*RAMwrwidth) |
doutB(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; |
/vhdl/ram/tdpramblock_asym.vhd
61,14 → 61,15
width : integer := 512; -- width of portB |
device : string := "xilinx" |
); |
port ( |
clk : in std_logic; |
port ( |
-- 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); |
95,13 → 96,14
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), |
/vhdl/ram/dpram_asym.vhd
61,15 → 61,16
wrwidth : integer := 2; -- write width, must be smaller than or equal to 32 |
device : string := "xilinx" -- device template to use |
); |
port ( |
clk : in std_logic; |
port ( |
-- write port |
waddr : in std_logic_vector(log2((rddepth*32)/wrwidth)-1 downto 0); |
we : in std_logic; |
din : in std_logic_vector(wrwidth-1 downto 0); |
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); |
-- read port |
raddr : in std_logic_vector(log2(rddepth)-1 downto 0); |
dout : out std_logic_vector(31 downto 0) |
clkB : in std_logic; |
raddrB : in std_logic_vector(log2(rddepth)-1 downto 0); |
doutB : out std_logic_vector(31 downto 0) |
); |
end dpram_asym; |
|
82,21 → 83,29
xilinx_device : if device="xilinx" generate |
-- the memory |
type ram_type is array (wrdepth-1 downto 0) of std_logic_vector (wrwidth-1 downto 0); |
signal RAM : ram_type := (others => (others => '0')); |
shared variable RAM : ram_type := (others => (others => '0')); |
|
-- xilinx constraint to use blockram resources |
attribute ram_style : string; |
attribute ram_style of ram:signal is "block"; |
attribute ram_style of RAM:variable is "block"; |
begin |
process (clk) |
-- Write port A |
process (clkA) |
begin |
if (clk'event and clk = '1') then |
if (we = '1') then |
RAM(conv_integer(waddr)) <= din; |
if rising_edge(clkA) then |
if (weA = '1') then |
RAM(conv_integer(waddrA)) := dinA; |
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 |
dout((i+1)*wrwidth-1 downto i*wrwidth) |
<= RAM(conv_integer(raddr & conv_std_logic_vector(i,log2(R)))); |
doutB((i+1)*wrwidth-1 downto i*wrwidth) |
<= RAM(conv_integer(raddrB & conv_std_logic_vector(i,log2(R)))); |
end loop; |
end if; |
end process; |
107,7 → 116,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; |
|
signal ram : ram_t; |
shared variable ram : ram_t; |
signal q_local : word_t; |
-- altera constraints: |
-- for smal depths: |
118,18 → 127,24
--attribute ramstyle of RAM : signal is "M9K, no_rw_check"; |
begin |
unpack: for i in 0 to R - 1 generate |
dout(wrwidth*(i+1) - 1 downto wrwidth*i) <= q_local(i); |
doutB(wrwidth*(i+1) - 1 downto wrwidth*i) <= q_local(i); |
end generate unpack; |
|
process(clk, we) |
process(clkA) |
begin |
if(rising_edge(clk)) then |
if(we = '1') then |
ram(conv_integer(waddr)/R)(conv_integer(waddr) mod R) <= din; |
if(rising_edge(clkA)) then |
if(weA = '1') then |
ram(conv_integer(waddrA)/R)(conv_integer(waddrA) mod R) := dinA; |
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; |
/vhdl/interface/axi/msec_ipcore_axilite.vhd
99,7 → 99,7
C_NR_STAGES_TOTAL : integer := 96; |
C_NR_STAGES_LOW : integer := 32; |
C_SPLIT_PIPELINE : boolean := true; |
C_FIFO_DEPTH : integer := 32; |
C_FIFO_AW : integer := 7; |
C_MEM_STYLE : string := "asym"; -- xil_prim, generic, asym are valid options |
C_FPGA_MAN : string := "xilinx"; -- xilinx, altera are valid options |
-- Bus protocol parameters |
110,6 → 110,7
); |
port( |
--USER ports |
core_clk : in std_logic; |
calc_time : out std_logic; |
IntrEvent : out std_logic; |
------------------------- |
394,13 → 395,14
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_FIFO_AW => C_FIFO_AW, |
C_MEM_STYLE => C_MEM_STYLE, |
C_FPGA_MAN => C_FPGA_MAN |
) |
port map( |
clk => S_AXI_ACLK, |
reset => reset, |
bus_clk => S_AXI_ACLK, |
core_clk => core_clk, |
reset => reset, |
-- operand memory interface (plb shared memory) |
write_enable => core_write_enable, |
data_in => S_AXI_WDATA(31 downto 0), |
/vhdl/interface/plb/mod_sim_exp_IPcore.vhd
162,7 → 162,7
C_NR_STAGES_TOTAL : integer := 96; |
C_NR_STAGES_LOW : integer := 32; |
C_SPLIT_PIPELINE : boolean := true; |
C_FIFO_DEPTH : integer := 32; |
C_FIFO_AW : integer := 7; |
C_MEM_STYLE : string := "xil_prim"; -- xil_prim, generic, asym are valid options |
C_FPGA_MAN : string := "xilinx"; -- xilinx, altera are valid options |
-- ADD USER GENERICS ABOVE THIS LINE --------------- |
200,7 → 200,8
( |
-- ADD USER PORTS BELOW THIS LINE ------------------ |
--USER ports added here |
calc_time : out std_logic; |
calc_time : out std_logic; |
core_clk : in std_logic; |
-- ADD USER PORTS ABOVE THIS LINE ------------------ |
|
-- DO NOT EDIT BELOW THIS LINE --------------------- |
580,7 → 581,7
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_FIFO_AW => C_FIFO_AW, |
C_MEM_STYLE => C_MEM_STYLE, |
C_FPGA_MAN => C_FPGA_MAN, |
-- MAP USER GENERICS ABOVE THIS LINE --------------- |
596,6 → 597,7
-- MAP USER PORTS BELOW THIS LINE ------------------ |
--USER ports mapped here |
calc_time => calc_time, |
core_clk => core_clk, |
-- MAP USER PORTS ABOVE THIS LINE ------------------ |
|
Bus2IP_Clk => ipif_Bus2IP_Clk, |
/vhdl/interface/plb/user_logic.vhd
100,7 → 100,7
C_NR_STAGES_TOTAL : integer := 96; |
C_NR_STAGES_LOW : integer := 32; |
C_SPLIT_PIPELINE : boolean := true; |
C_FIFO_DEPTH : integer := 32; |
C_FIFO_AW : integer := 7; |
C_MEM_STYLE : string := "xil_prim"; -- xil_prim, generic, asym are valid options |
C_FPGA_MAN : string := "xilinx"; -- xilinx, altera are valid options |
-- ADD USER GENERICS ABOVE THIS LINE --------------- |
118,8 → 118,8
( |
-- ADD USER PORTS BELOW THIS LINE ------------------ |
--USER ports added here |
calc_time : out std_logic; |
-- ctrl_sigs : out std_logic_vector( downto ); |
calc_time : out std_logic; |
core_clk : in std_logic; |
-- ADD USER PORTS ABOVE THIS LINE ------------------ |
|
-- DO NOT EDIT BELOW THIS LINE --------------------- |
406,13 → 406,14
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_FIFO_AW => C_FIFO_AW, |
C_MEM_STYLE => C_MEM_STYLE, |
C_FPGA_MAN => C_FPGA_MAN |
) |
port map( |
clk => Bus2IP_Clk, |
reset => Bus2IP_Reset, |
core_clk => core_clk, |
bus_clk => Bus2IP_Clk, |
reset => Bus2IP_Reset, |
-- operand memory interface (plb shared memory) |
write_enable => core_write_enable, |
data_in => core_data_in, |
/vhdl/core/fifo_generic.vhd
File deleted
/vhdl/core/pulse_cdc.vhd
0,0 → 1,97
---------------------------------------------------------------------- |
---- pulse_cdc ---- |
---- ---- |
---- This file is part of the ---- |
---- Modular Simultaneous Exponentiation Core project ---- |
---- http://www.opencores.org/cores/mod_sim_exp/ ---- |
---- ---- |
---- Description ---- |
---- transfers a pulse (1clk wide) from clock domain A to ---- |
---- clock domain B by using a toggling signal. This design ---- |
---- avoids metastable states ---- |
---- ---- |
---- Dependencies: none ---- |
---- ---- |
---- Authors: ---- |
---- - Geoffrey Ottoy, DraMCo research group ---- |
---- - Jonas De Craene, JonasDC@opencores.org ---- |
---- ---- |
---------------------------------------------------------------------- |
---- ---- |
---- Copyright (C) 2011 DraMCo research group and OPENCORES.ORG ---- |
---- ---- |
---- This source file may be used and distributed without ---- |
---- restriction provided that this copyright statement is not ---- |
---- removed from the file and that any derivative work contains ---- |
---- the original copyright notice and the associated disclaimer. ---- |
---- ---- |
---- This source file is free software; you can redistribute it ---- |
---- and/or modify it under the terms of the GNU Lesser General ---- |
---- Public License as published by the Free Software Foundation; ---- |
---- either version 2.1 of the License, or (at your option) any ---- |
---- later version. ---- |
---- ---- |
---- This source is distributed in the hope that it will be ---- |
---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- |
---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- |
---- PURPOSE. See the GNU Lesser General Public License for more ---- |
---- details. ---- |
---- ---- |
---- You should have received a copy of the GNU Lesser General ---- |
---- Public License along with this source; if not, download it ---- |
---- from http://www.opencores.org/lgpl.shtml ---- |
---- ---- |
---------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_unsigned.all; |
|
entity 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 pulse_cdc; |
|
|
architecture arch of pulse_cdc is |
signal pulseA_d : std_logic; |
signal toggle : std_logic := '0'; |
signal toggle_d, toggle_d2, toggle_d3 : std_logic; |
begin |
|
-- Convert pulse from clock domain A to a toggling signal |
PulseAtoToggle : process (clkA, reset) |
begin |
if reset='1' then |
toggle <= '0'; |
else |
if rising_edge(clkA) then |
pulseA_d <= pulseA; |
toggle <= toggle xor (pulseA and not pulseA_d); |
end if; |
end if; |
end process; |
|
-- Convert toggling signal to a pulse of 1clk wide to clock domain B |
ToggletoPulseB : process (clkB, reset) |
begin |
if reset='1' then |
toggle_d <= '0'; |
toggle_d2 <= '0'; |
toggle_d3 <= '0'; |
else |
if rising_edge(clkB) then |
toggle_d <= toggle; -- this signal may have metastability isues |
toggle_d2 <= toggle_d; -- stable now |
toggle_d3 <= toggle_d2; |
end if; |
end if; |
end process; |
|
pulseB <= toggle_d2 xor toggle_d3; |
end arch; |
/vhdl/core/fifo_primitive.vhd
54,16 → 54,17
|
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 |
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 |
); |
end fifo_primitive; |
|
86,13 → 87,13
push_i <= push and (not reset_i); |
|
-- makes the reset at least three clk_cycles long |
RESET_PROC: process (reset, clk) |
RESET_PROC: process (reset, push_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 |
elsif rising_edge(push_clk) then |
if clk_counter = 0 then |
clk_counter := 0; |
reset_i <= '0'; |
109,7 → 110,7
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") |
EN_SYN => FALSE, -- 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 |
135,8 → 136,8
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 |
RDCLK => pop_clk, -- 1-bit read clock input |
WRCLK => push_clk, -- 1-bit write clock input |
WREN => push_i -- 1-bit write enable input |
); |
|
/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,6 → 71,7
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 |
88,22 → 89,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 doutB_RAM : wordsplit; |
signal doutA_RAM : wordsplit; |
--- PORT A : 32-bit write | (width)-bit read |
signal dinA : std_logic_vector(31 downto 0); |
signal doutA : std_logic_vector(width-1 downto 0); |
signal doutA : std_logic_vector(31 downto 0); |
signal weA : std_logic; |
signal addrA : std_logic_vector(RAMselect_aw-1 downto 0); |
signal op_selA : std_logic_vector(RAMdepth_aw-1 downto 0); |
--- PORT B : 32-bit read | (width)-bit write |
signal dinB : std_logic_vector(width-1 downto 0); |
signal doutB : std_logic_vector(31 downto 0); |
signal doutB : std_logic_vector(width-1 downto 0); |
signal weB : std_logic; |
signal addrB : std_logic_vector(RAMselect_aw-1 downto 0); |
signal op_selB : std_logic_vector(RAMdepth_aw-1 downto 0); |
|
signal write_operand_i : std_logic; |
signal op_selA_i : std_logic_vector(RAMdepth_aw-1 downto 0); |
signal op_selB_i : std_logic_vector(RAMdepth_aw-1 downto 0); |
begin |
|
-- WARNING: Very Important! |
115,29 → 116,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_operand_i select |
op_selA_i <= operand_in_sel when '1', |
with write_result select |
op_selB_i <= result_dest_op when '1', |
operand_out_sel when others; |
|
-- map signals to RAM |
-- PORTA |
weA <= write_operand_i; |
op_selA <= op_selA_i; |
op_selA <= operand_in_sel; |
addrA <= operand_addr; |
dinA <= operand_in; |
operand_out <= doutA; |
result_out <= doutA; |
-- PORT B |
weB <= write_result; |
op_selB <= result_dest_op; -- portB locked to result operand |
op_selB <= op_selB_i; -- portB locked to result operand |
addrB <= operand_addr; |
dinB <= result_in; |
result_out <= doutB; |
operand_out <= doutB; |
|
-- generate (width/32) blocks of 32-bit ram with a given depth |
-- these rams are tyed together to form the following structure |
-- True dual port ram: |
-- - PORT A : 32-bit write | (width)-bit read |
-- - PORT B : 32-bit read | (width)-bit write |
-- - PORT A : 32-bit write | 32-bit read |
-- - PORT B : (width)-bit read | (width)-bit write |
-- ^ ^ |
-- addres addr op_sel |
-- |
148,17 → 149,17
) |
port map( |
-- port A : 32-bit |
clkA => clk, |
clkA => bus_clk, |
addrA => op_selA, |
weA => weA_RAM(i), |
dinA => dinA, |
doutA => doutA(((i+1)*32)-1 downto i*32), |
doutA => doutA_RAM(i), |
-- port B : 32-bit |
clkB => clk, |
clkB => core_clk, |
addrB => op_selB, |
weB => weB, |
dinB => dinB(((i+1)*32)-1 downto i*32), |
doutB => doutB_RAM(i) |
doutB => doutB(((i+1)*32)-1 downto i*32) |
); |
-- demultiplexer for write enable A signal |
process (addrA, weA) |
171,7 → 172,7
end process; |
end generate; |
-- PORTB 32-bit read |
doutB <= doutB_RAM(conv_integer(addrB)) when (conv_integer(addrB)<nrRAMs) |
doutA <= doutA_RAM(conv_integer(addrA)) when (conv_integer(addrA)<nrRAMs) |
else (others=>'0'); |
|
end Behavioral; |
/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,6 → 78,7
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 |
126,13 → 127,14
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, |
159,13 → 161,14
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), |
208,13 → 211,14
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), |
/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 := "xilinx" |
device : string := "altera" |
); |
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,6 → 75,7
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; |
107,14 → 108,15
device => device |
) |
port map( |
clk => clk, |
-- write port |
waddr => waddr, |
we => write_modulus, |
din => modulus_in, |
clkA => bus_clk, |
waddrA => waddr, |
weA => write_modulus, |
dinA => modulus_in, |
-- read port |
raddr => modulus_sel, |
dout => modulus_out |
clkB => core_clk, |
raddrB => modulus_sel, |
doutB => modulus_out |
); |
end generate; |
|
135,14 → 137,15
device => device |
) |
port map( |
clk => clk, |
-- write port |
waddr => waddr, |
we => we_RAM(i), |
din => modulus_in, |
clkA => bus_clk, |
waddrA => waddr, |
weA => we_RAM(i), |
dinA => modulus_in, |
-- read port |
raddr => modulus_sel, |
dout => modulus_out((i+1)*RAMblock_maxwidth-1 downto i*RAMblock_maxwidth) |
clkB => core_clk, |
raddrB => modulus_sel, |
doutB => modulus_out((i+1)*RAMblock_maxwidth-1 downto i*RAMblock_maxwidth) |
); |
-- we |
process (write_modulus, modulus_addr) |
169,14 → 172,15
device => device |
) |
port map( |
clk => clk, |
-- write port |
waddr => waddr_part, |
we => we_part, |
din => modulus_in, |
clkA => bus_clk, |
waddrA => waddr_part, |
weA => we_part, |
dinA => modulus_in, |
-- read port |
raddr => modulus_sel, |
dout => modulus_out(width-1 downto i*RAMblock_maxwidth) |
clkB => core_clk, |
raddrB => modulus_sel, |
doutB => modulus_out(width-1 downto i*RAMblock_maxwidth) |
); |
|
-- we_part |
/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,6 → 69,7
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; |
96,14 → 97,15
depth => depth |
) |
port map( |
clk => clk, |
-- write port |
waddr => modulus_wraddr(total_aw-1 downto RAMselect_aw), |
we => we(i), |
din => modulus_in, |
clkA => bus_clk, |
waddrA => modulus_wraddr(total_aw-1 downto RAMselect_aw), |
weA => we(i), |
dinA => modulus_in, |
-- read port |
raddr => modulus_rdaddr, |
dout => modulus_out(((i+1)*32)-1 downto i*32) |
clkB => core_clk, |
raddrB => modulus_rdaddr, |
doutB => modulus_out(((i+1)*32)-1 downto i*32) |
); |
-- connect the w |
process (write_modulus, modulus_wraddr) |
/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(511 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(5 downto 0); |
addrb : in std_logic_vector(1 downto 0); |
dinb : in std_logic_vector(511 downto 0); |
doutb : out std_logic_vector(31 downto 0) |
doutb : out std_logic_vector(511 downto 0) |
); |
end component operand_dp; |
|
510,16 → 510,17
-- |
component fifo_primitive is |
port ( |
clk : in std_logic; |
din : in std_logic_vector (31 downto 0); |
dout : out std_logic_vector (31 downto 0); |
empty : out std_logic; |
full : out std_logic; |
push : in std_logic; |
pop : in std_logic; |
reset : in std_logic; |
nopop : out std_logic; |
nopush : out std_logic |
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 |
); |
end component fifo_primitive; |
|
532,9 → 533,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); |
541,6 → 542,7
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 |
578,14 → 580,15
depth : integer := 2 |
); |
port ( |
clk : in std_logic; |
-- write port |
waddr : in std_logic_vector(log2(depth)-1 downto 0); |
we : in std_logic; |
din : in std_logic_vector(31 downto 0); |
-- read port |
raddr : in std_logic_vector(log2(depth)-1 downto 0); |
dout : out std_logic_vector(31 downto 0) |
-- 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) |
); |
end component dpram_generic; |
|
651,8 → 654,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 |
659,6 → 662,7
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; |
676,9 → 680,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 |
686,6 → 690,7
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 |
706,20 → 711,21
-- 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( |
clk : in std_logic; |
port ( |
-- write port |
waddr : in std_logic_vector(log2((rddepth*32)/wrwidth)-1 downto 0); |
we : in std_logic; |
din : in std_logic_vector(wrwidth-1 downto 0); |
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); |
-- read port |
raddr : in std_logic_vector(log2(rddepth)-1 downto 0); |
dout : out std_logic_vector(31 downto 0) |
clkB : in std_logic; |
raddrB : in std_logic_vector(log2(rddepth)-1 downto 0); |
doutB : out std_logic_vector(31 downto 0) |
); |
end component dpram_asym; |
|
731,20 → 737,21
-- port. |
-- |
component dpramblock_asym is |
generic( |
generic ( |
width : integer := 256; -- read width |
depth : integer := 2; -- nr of (width)-bit words |
device : string := "xilinx" |
); |
port( |
clk : in std_logic; |
-- write port |
waddr : in std_logic_vector(log2((width*depth)/32)-1 downto 0); |
we : in std_logic; |
din : in std_logic_vector(31 downto 0); |
-- read port |
raddr : in std_logic_vector(log2(depth)-1 downto 0); |
dout : out std_logic_vector(width-1 downto 0) |
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) |
); |
end component dpramblock_asym; |
|
757,19 → 764,20
-- 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( |
clk : in std_logic; |
port ( |
-- 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); |
790,14 → 798,15
width : integer := 512; -- width of portB |
device : string := "xilinx" |
); |
port ( |
clk : in std_logic; |
port ( |
-- 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); |
822,8 → 831,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 |
830,6 → 839,7
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; |
852,9 → 862,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 |
862,6 → 872,7
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 |
893,14 → 904,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); |
914,7 → 925,39
end component operand_mem; |
|
|
---------------------- CLOCK DOMAIN CROSSING ---------------------- |
|
-------------------------------------------------------------------- |
-- pulse_cdc |
-------------------------------------------------------------------- |
-- transfers a pulse (1clk wide) from clock domain A to clock domain B |
-- by using a toggling signal. This design avoids metastable states |
-- |
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; |
|
-------------------------------------------------------------------- |
-- clk_sync |
-------------------------------------------------------------------- |
-- transfers a signal from clock domain A to clock domain B. |
-- This design avoids metastable states |
-- |
component clk_sync is |
port ( |
sigA : in std_logic; |
clkB : in std_logic; |
sigB : out std_logic |
); |
end component clk_sync; |
|
|
---------------------------- TOP LEVEL ----------------------------- |
|
-------------------------------------------------------------------- |
930,14 → 973,15
C_NR_STAGES_TOTAL : integer := 96; |
C_NR_STAGES_LOW : integer := 32; |
C_SPLIT_PIPELINE : boolean := true; |
C_FIFO_DEPTH : integer := 32; |
C_MEM_STYLE : string := "generic"; -- xil_prim, generic, asym are valid options |
C_FIFO_AW : integer := 7; -- Address width for FIFO pointers |
C_MEM_STYLE : string := "asym"; -- xil_prim, generic, asym are valid options |
C_FPGA_MAN : string := "xilinx" -- xilinx, altera are valid options |
); |
port( |
clk : in std_logic; |
reset : in std_logic; |
core_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 |
957,7 → 1001,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; |
|
/vhdl/core/clk_sync.vhd
0,0 → 1,70
---------------------------------------------------------------------- |
---- clk_sync ---- |
---- ---- |
---- This file is part of the ---- |
---- Modular Simultaneous Exponentiation Core project ---- |
---- http://www.opencores.org/cores/mod_sim_exp/ ---- |
---- ---- |
---- Description ---- |
---- synchronises signal A to clock B, avoiding metastable ---- |
---- states. ---- |
---- ---- |
---- Dependencies: none ---- |
---- ---- |
---- Authors: ---- |
---- - Geoffrey Ottoy, DraMCo research group ---- |
---- - Jonas De Craene, JonasDC@opencores.org ---- |
---- ---- |
---------------------------------------------------------------------- |
---- ---- |
---- Copyright (C) 2011 DraMCo research group and OPENCORES.ORG ---- |
---- ---- |
---- This source file may be used and distributed without ---- |
---- restriction provided that this copyright statement is not ---- |
---- removed from the file and that any derivative work contains ---- |
---- the original copyright notice and the associated disclaimer. ---- |
---- ---- |
---- This source file is free software; you can redistribute it ---- |
---- and/or modify it under the terms of the GNU Lesser General ---- |
---- Public License as published by the Free Software Foundation; ---- |
---- either version 2.1 of the License, or (at your option) any ---- |
---- later version. ---- |
---- ---- |
---- This source is distributed in the hope that it will be ---- |
---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- |
---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- |
---- PURPOSE. See the GNU Lesser General Public License for more ---- |
---- details. ---- |
---- ---- |
---- You should have received a copy of the GNU Lesser General ---- |
---- Public License along with this source; if not, download it ---- |
---- from http://www.opencores.org/lgpl.shtml ---- |
---- ---- |
---------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_unsigned.all; |
|
entity clk_sync is |
port ( |
sigA : in std_logic; |
clkB : in std_logic; |
sigB : out std_logic |
); |
end clk_sync; |
|
|
architecture arch of clk_sync is |
signal sigMeta : std_logic; -- signal where metastable states are possible |
begin |
|
sync : process (clkB) |
begin |
if rising_edge(clkB) then |
sigMeta <= sigA; |
sigB <= sigMeta; |
end if; |
end process; |
|
end arch; |
/vhdl/core/mod_sim_exp_core.vhd
65,14 → 65,15
C_NR_STAGES_TOTAL : integer := 96; |
C_NR_STAGES_LOW : integer := 32; |
C_SPLIT_PIPELINE : boolean := true; |
C_FIFO_DEPTH : integer := 32; |
C_FIFO_AW : integer := 7; -- Address width for FIFO pointers |
C_MEM_STYLE : string := "asym"; -- xil_prim, generic, asym are valid options |
C_FPGA_MAN : string := "xilinx" -- xilinx, altera are valid options |
); |
port( |
clk : in std_logic; |
reset : in std_logic; |
core_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 |
115,6 → 116,10
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; |
127,26 → 132,6
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 |
158,6 → 143,7
device => C_FPGA_MAN |
) |
port map( |
bus_clk => bus_clk, |
data_in => data_in, |
data_out => data_out, |
rw_address => rw_address, |
165,11 → 151,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 => collision, |
clk => clk, |
collision => core_collision, |
modulus_sel => modulus_sel_i |
); |
|
180,7 → 166,8
xil_prim_fifo : if C_MEM_STYLE="xil_prim" generate |
the_exponent_fifo : fifo_primitive |
port map( |
clk => clk, |
push_clk => bus_clk, |
pop_clk => core_clk, |
din => fifo_din, |
dout => fifo_dout, |
empty => fifo_empty, |
192,31 → 179,53
nopush => fifo_nopush |
); |
end generate; |
gen_fifo : if (C_MEM_STYLE="generic") or (C_MEM_STYLE="asym") generate |
the_exponent_fifo : fifo_generic |
gen_fifo : if (C_MEM_STYLE = "generic") or (C_MEM_STYLE = "asym") generate |
the_exponent_fifo : entity mod_sim_exp.generic_fifo_dc |
generic map( |
depth => C_FIFO_DEPTH |
dw => 32, |
aw => C_FIFO_AW |
) |
port map( |
clk => clk, |
wr_clk => bus_clk, |
rd_clk => core_clk, |
din => fifo_din, |
dout => fifo_dout, |
empty => fifo_empty, |
full => fifo_full, |
push => fifo_push, |
pop => fifo_pop, |
reset => reset, |
we => fifo_push, |
re => fifo_pop, |
clr => 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 => clk, |
reset => reset, |
start => start, |
clk => core_clk, |
reset => reset, -- asynchronious reset |
start => core_start, |
x_sel_single => x_sel_single, |
y_sel_single => y_sel_single, |
run_auto => exp_m, |
223,8 → 232,8
op_buffer_empty => fifo_empty, |
op_sel_buffer => fifo_dout, |
read_buffer => fifo_pop, |
done => ready, |
calc_time => calc_time, |
done => core_ready, |
calc_time => core_calc_time, |
op_sel => op_sel, |
load_x => load_x, |
load_result => load_result, |
231,5 → 240,41
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; |
/vhdl/core/operand_dp.vhd
1,75 → 1,50
---------------------------------------------------------------------- |
---- 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. -- |
---------------------------------------------------------------------- |
-------------------------------------------------------------------------------- |
-- (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. -- |
-------------------------------------------------------------------------------- |
-- 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 |
79,46 → 54,40
-- 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; |
|
|
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 |
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; |
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; |
|
-- Configuration specification |
for all : wrapped_operand_dp use entity XilinxCoreLib.blk_mem_gen_v3_3(behavioral) |
131,10 → 100,10
c_has_injecterr => 0, |
c_rst_type => "SYNC", |
c_prim_type => 1, |
c_read_width_b => 32, |
c_read_width_b => 512, |
c_initb_val => "0", |
c_family => "virtex6", |
c_read_width_a => 512, |
c_read_width_a => 32, |
c_disable_warn_bhv_coll => 0, |
c_write_mode_b => "WRITE_FIRST", |
c_init_file_name => "no_coe_file_loaded", |
152,7 → 121,7
c_inita_val => "0", |
c_has_mux_output_regs_a => 0, |
c_addra_width => 6, |
c_addrb_width => 6, |
c_addrb_width => 2, |
c_default_data => "0", |
c_use_ecc => 0, |
c_algorithm => 1, |
159,8 → 128,8
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_read_depth_b => 4, |
c_read_depth_a => 64, |
c_byte_size => 9, |
c_sim_collision_check => "ALL", |
c_common_clk => 0, |
172,24 → 141,23
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; |
|
/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 := "altera" -- xilinx, altera are valid options |
device : string := "xilinx" -- 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,7 → 132,8
-- xy operand storage |
xy_ram_xil : operand_ram |
port map( |
clk => clk, |
bus_clk => bus_clk, |
core_clk => core_clk, |
collision => collision, |
operand_addr => xy_addr_i, |
operand_in => xy_data_i, |
149,7 → 150,7
-- modulus storage |
m_ram_xil : modulus_ram |
port map( |
clk => clk, |
clk => bus_clk, |
modulus_addr => m_addr_i, |
write_modulus => load_m, |
modulus_in => m_data_i, |
165,8 → 166,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, |
175,6 → 176,7
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 |
); |
186,11 → 188,12
depth => nr_m |
) |
port map( |
clk => clk, |
bus_clk => bus_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 |
); |
205,8 → 208,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, |
215,6 → 218,7
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 |
); |
227,11 → 231,12
device => device |
) |
port map( |
clk => clk, |
bus_clk => bus_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 |
); |
/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,6 → 64,7
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 |
81,11 → 82,11
signal write_operand_i : std_logic; |
|
-- port b signals |
signal addrb : std_logic_vector(5 downto 0); |
signal addrb : std_logic_vector(1 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 douta0 : std_logic_vector(31 downto 0); |
signal douta1 : std_logic_vector(31 downto 0); |
signal douta2 : std_logic_vector(31 downto 0); |
|
begin |
|
99,70 → 100,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_operand_i select |
addra <= operand_in_sel & operand_addr(3 downto 0) when '1', |
operand_out_sel & "0000" when others; |
with write_result select |
addrb <= result_dest_op when '1', |
operand_out_sel 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; |
|
with write_operand select |
wea <= part_enable when '1', |
"0000" when others; |
|
addra <= operand_in_sel & operand_addr(3 downto 0); |
|
-- we can only read back from the result (stored in result_dest_op) |
addrb <= result_dest_op & operand_addr(3 downto 0); |
|
|
with operand_addr(5 downto 4) select |
result_out <= doutb0 when "00", |
doutb1 when "01", |
doutb2 when others; |
result_out <= douta0 when "00", |
douta1 when "01", |
douta2 when others; |
|
-- 3 instances of a dual port ram to store the parts of the operand |
op_0 : operand_dp |
port map ( |
clka => clk, |
clka => bus_clk, |
wea => wea(0 downto 0), |
addra => addra, |
dina => operand_in, |
douta => operand_out(511 downto 0), |
clkb => clk, |
douta => douta0, |
clkb => core_clk, |
web => web, |
addrb => addrb, |
dinb => result_in(511 downto 0), |
doutb => doutb0 |
doutb => operand_out(511 downto 0) |
); |
|
op_1 : operand_dp |
port map ( |
clka => clk, |
clka => bus_clk, |
wea => wea(1 downto 1), |
addra => addra, |
dina => operand_in, |
douta => operand_out(1023 downto 512), |
clkb => clk, |
douta => douta1, |
clkb => core_clk, |
web => web, |
addrb => addrb, |
dinb => result_in(1023 downto 512), |
doutb => doutb1 |
doutb => operand_out(1023 downto 512) |
); |
|
op_2 : operand_dp |
port map ( |
clka => clk, |
clka => bus_clk, |
wea => wea(2 downto 2), |
addra => addra, |
dina => operand_in, |
douta => operand_out(1535 downto 1024), |
clkb => clk, |
douta => douta2, |
clkb => core_clk, |
web => web, |
addrb => addrb, |
dinb => result_in(1535 downto 1024), |
doutb => doutb2 |
doutb => operand_out(1535 downto 1024) |
); |
|
end Behavioral; |