aboutsummaryrefslogtreecommitdiff
path: root/rtl/modexpng_mem.v
diff options
context:
space:
mode:
authorPavel V. Shatov (Meister) <meisterpaul1@yandex.ru>2019-10-01 15:01:43 +0300
committerPavel V. Shatov (Meister) <meisterpaul1@yandex.ru>2019-10-01 15:01:43 +0300
commit29fb6afd018c601a2e0c7376656d5e37beb565d6 (patch)
treedc11ee0c8e5a30113052254be23594da74a8a572 /rtl/modexpng_mem.v
parentec07464d239f7f6379a682ac57b58b863d3f0374 (diff)
Started working on the pipelined Montgomery modular multiplier. Currently can
do the "square" part of the multiplication, i.e. compute the twice larger intermediate product AB = A * B.
Diffstat (limited to 'rtl/modexpng_mem.v')
-rw-r--r--rtl/modexpng_mem.v93
1 files changed, 93 insertions, 0 deletions
diff --git a/rtl/modexpng_mem.v b/rtl/modexpng_mem.v
new file mode 100644
index 0000000..ca89214
--- /dev/null
+++ b/rtl/modexpng_mem.v
@@ -0,0 +1,93 @@
+//
+// TODO: Add license text!
+//
+
+module modexpng_mem #
+(
+ parameter MEM_WIDTH = 17,
+ parameter MEM_ADDR_BITS = 6
+)
+(
+ input clk,
+
+ input [MEM_ADDR_BITS-1:0] a_addr,
+ input a_en,
+ input a_wr,
+ input [MEM_WIDTH -1:0] a_in,
+ output [MEM_WIDTH -1:0] a_out,
+
+ input [MEM_ADDR_BITS-1:0] b_addr,
+ input b_en,
+ input b_reg_en,
+ output [MEM_WIDTH -1:0] b_out
+);
+
+
+ //
+ // BRAM
+ //
+ (* RAM_STYLE="BLOCK" *)
+ reg [MEM_WIDTH-1:0] bram[0:(2**MEM_ADDR_BITS)-1];
+
+
+ //
+ // Initialization for Simulation
+ //
+ /*
+ integer c;
+ initial begin
+ for (c=0; c<(2**MEM_ADDR_BITS); c=c+1)
+ bram[c] = {MEM_WIDTH{1'b0}};
+ end
+ */
+
+
+
+ //
+ // Output Registers
+ //
+ reg [MEM_WIDTH-1:0] bram_b;
+ reg [MEM_WIDTH-1:0] bram_b_reg;
+
+ assign a_out = 32'hDEADCE11;
+ assign b_out = bram_b_reg;
+
+
+ //
+ // Note, that when both ports are accessing the same location, conflict can
+ // potentionally arise. See Xilinx UG473 (pages 19-20, "Conflict
+ // Avoidance") for more information. In our configuration to avoid that the
+ // write port must be coded to operate in READ_FIRST mode. If the write
+ // port is overwriting the same address the read port is accessing, the
+ // write port must read the previously stored data (not the data it is
+ // writing, as that would be WRITE_FIRST mode).
+ //
+
+
+ //
+ // Write-Only Port A
+ //
+ always @(posedge clk)
+ //
+ if (a_en)
+ //
+ if (a_wr) bram[a_addr] <= a_in;
+
+
+ //
+ // Read-Only Port B
+ //
+ always @(posedge clk)
+ //
+ if (b_en)
+ //
+ bram_b <= bram[b_addr];
+
+ always @(posedge clk)
+ //
+ if (b_reg_en)
+ //
+ bram_b_reg <= bram_b;
+
+
+endmodule