From 25e338149fdb8e06c82d99600769a8498a85ef2c Mon Sep 17 00:00:00 2001
From: "Pavel V. Shatov (Meister)" <meisterpaul1@yandex.ru>
Date: Mon, 31 Oct 2016 00:14:51 +0300
Subject: Initial commit of base point multiplier core for ECDSA curve P-256.

---
 rtl/curve/curve_dbl_add_256.v   | 868 ++++++++++++++++++++++++++++++++++++++++
 rtl/curve/curve_mul_256.v       | 720 +++++++++++++++++++++++++++++++++
 rtl/curve/rom/brom_p256_delta.v |  68 ++++
 rtl/curve/rom/brom_p256_g_x.v   |  68 ++++
 rtl/curve/rom/brom_p256_g_y.v   |  68 ++++
 rtl/curve/rom/brom_p256_h_x.v   |  68 ++++
 rtl/curve/rom/brom_p256_h_y.v   |  68 ++++
 rtl/curve/rom/brom_p256_one.v   |  68 ++++
 rtl/curve/rom/brom_p256_q.v     |  68 ++++
 rtl/curve/rom/brom_p256_zero.v  |  70 ++++
 rtl/curve/uop/uop_add_rom.v     |  66 +++
 rtl/curve/uop/uop_conv_rom.v    |  38 ++
 rtl/curve/uop/uop_dbl_rom.v     |  58 +++
 rtl/curve/uop/uop_init_rom.v    |  33 ++
 rtl/curve/uop_ecdsa.v           |  50 +++
 15 files changed, 2379 insertions(+)
 create mode 100644 rtl/curve/curve_dbl_add_256.v
 create mode 100644 rtl/curve/curve_mul_256.v
 create mode 100644 rtl/curve/rom/brom_p256_delta.v
 create mode 100644 rtl/curve/rom/brom_p256_g_x.v
 create mode 100644 rtl/curve/rom/brom_p256_g_y.v
 create mode 100644 rtl/curve/rom/brom_p256_h_x.v
 create mode 100644 rtl/curve/rom/brom_p256_h_y.v
 create mode 100644 rtl/curve/rom/brom_p256_one.v
 create mode 100644 rtl/curve/rom/brom_p256_q.v
 create mode 100644 rtl/curve/rom/brom_p256_zero.v
 create mode 100644 rtl/curve/uop/uop_add_rom.v
 create mode 100644 rtl/curve/uop/uop_conv_rom.v
 create mode 100644 rtl/curve/uop/uop_dbl_rom.v
 create mode 100644 rtl/curve/uop/uop_init_rom.v
 create mode 100644 rtl/curve/uop_ecdsa.v

(limited to 'rtl/curve')

diff --git a/rtl/curve/curve_dbl_add_256.v b/rtl/curve/curve_dbl_add_256.v
new file mode 100644
index 0000000..08a9931
--- /dev/null
+++ b/rtl/curve/curve_dbl_add_256.v
@@ -0,0 +1,868 @@
+//------------------------------------------------------------------------------
+//
+// curve_adder_256.v
+// -----------------------------------------------------------------------------
+// Elliptic curve point adder.
+//
+// Authors: Pavel Shatov
+//
+// Copyright (c) 2016, NORDUnet A/S
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// - Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+//
+// - Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+//
+// - Neither the name of the NORDUnet nor the names of its contributors may be
+//   used to endorse or promote products derived from this software without
+//   specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
+//
+//------------------------------------------------------------------------------
+
+module curve_dbl_add_256
+	(
+		clk, rst_n,
+		ena, rdy,
+		uop_addr, uop,
+		px_addr, py_addr, pz_addr, rx_addr, ry_addr, rz_addr, q_addr, v_addr,
+		rx_wren, ry_wren, rz_wren,
+		px_din, py_din, pz_din,
+		rx_din, ry_din, rz_din,
+		rx_dout, ry_dout, rz_dout, q_din, v_din
+	);
+
+
+		//
+		// Microcode
+		//
+`include "uop_ecdsa.v"
+
+
+		//
+		// Constants
+		//
+	localparam	WORD_COUNTER_WIDTH	= 3;	// 0 .. 7
+	localparam	OPERAND_NUM_WORDS		= 8;	// 8 * 32 = 256
+
+	
+		//
+		// Ports
+		//
+	input		wire	clk;		// system clock
+	input		wire	rst_n;	// active-low async reset
+	
+	input		wire	ena;		// enable input
+	output	wire	rdy;		// ready output
+		
+	output	reg	[ 6-1: 0]	uop_addr;
+	input		wire	[20-1: 0]	uop;
+		
+	output	reg	[WORD_COUNTER_WIDTH-1:0]	px_addr;
+	output	reg	[WORD_COUNTER_WIDTH-1:0]	py_addr;
+	output	reg	[WORD_COUNTER_WIDTH-1:0]	pz_addr;
+	output	reg	[WORD_COUNTER_WIDTH-1:0]	rx_addr;
+	output	reg	[WORD_COUNTER_WIDTH-1:0]	ry_addr;
+	output	reg	[WORD_COUNTER_WIDTH-1:0]	rz_addr;
+	output	reg	[WORD_COUNTER_WIDTH-1:0]	v_addr;
+	output	wire	[WORD_COUNTER_WIDTH-1:0]	q_addr;
+	
+	output	wire										rx_wren;
+	output	wire										ry_wren;
+	output	wire										rz_wren;
+
+	input		wire	[                32-1:0]	px_din;
+	input		wire	[                32-1:0]	py_din;
+	input		wire	[                32-1:0]	pz_din;
+	input		wire	[                32-1:0]	rx_din;
+	input		wire	[                32-1:0]	ry_din;
+	input		wire	[                32-1:0]	rz_din;
+	output	wire	[                32-1:0]	rx_dout;
+	output	wire	[                32-1:0]	ry_dout;
+	output	wire	[                32-1:0]	rz_dout;
+	input		wire	[                32-1:0]	q_din;
+	input		wire	[                32-1:0]	v_din;
+
+	
+		//
+		// Microcode
+		//   
+	wire	[ 4: 0]	uop_opcode	= uop[19:15];
+	wire	[ 4: 0]	uop_src_a	= uop[14:10];
+	wire	[ 4: 0]	uop_src_b	= uop[ 9: 5];
+	wire	[ 2: 0]	uop_dst		= uop[ 4: 2];
+	wire	[ 1: 0]	uop_exec		= uop[ 1: 0];
+	
+
+		//
+		// Multi-Word Comparator
+		//
+	wire	mw_cmp_ena;
+	wire	mw_cmp_rdy;
+		
+	wire	mw_cmp_out_l;
+	wire	mw_cmp_out_e;
+	wire	mw_cmp_out_g;
+	
+	wire	[WORD_COUNTER_WIDTH-1:0]	mw_cmp_addr_xy;
+	
+	wire	[                32-1:0]	mw_cmp_din_x;
+	wire	[                32-1:0]	mw_cmp_din_y;
+
+		// flags
+	reg	flag_pz_is_zero;
+	reg	flag_t1_is_zero;
+	reg	flag_t2_is_zero;
+	
+	mw_comparator #
+	(
+		.WORD_COUNTER_WIDTH	(WORD_COUNTER_WIDTH),
+		.OPERAND_NUM_WORDS	(OPERAND_NUM_WORDS)
+	)
+	mw_comparator_inst
+	(
+		.clk			(clk),
+		.rst_n		(rst_n),
+		
+		.ena			(mw_cmp_ena),
+		.rdy			(mw_cmp_rdy),
+		
+		.xy_addr		(mw_cmp_addr_xy),
+		.x_din		(mw_cmp_din_x),
+		.y_din		(mw_cmp_din_y),
+		
+		.cmp_l		(mw_cmp_out_l),
+		.cmp_e		(mw_cmp_out_e),
+		.cmp_g		(mw_cmp_out_g)
+	);
+	
+	
+		//
+		// Modular Adder
+		//
+	wire	mod_add_ena;
+	wire	mod_add_rdy;
+	
+	wire	[WORD_COUNTER_WIDTH-1:0]	mod_add_addr_ab;
+	wire	[WORD_COUNTER_WIDTH-1:0]	mod_add_addr_n;
+	wire	[WORD_COUNTER_WIDTH-1:0]	mod_add_addr_s;
+	wire										mod_add_wren_s;
+	
+	wire	[                32-1:0]	mod_add_din_a;
+	wire	[                32-1:0]	mod_add_din_b;
+	wire	[                32-1:0]	mod_add_din_n;
+	wire	[                32-1:0]	mod_add_dout_s;
+	
+	assign mod_add_din_n = q_din;
+	
+	modular_adder #
+	(
+		.WORD_COUNTER_WIDTH	(WORD_COUNTER_WIDTH),
+		.OPERAND_NUM_WORDS	(OPERAND_NUM_WORDS)
+	)
+	modular_adder_inst
+	(
+		.clk			(clk),
+		.rst_n		(rst_n),
+		
+		.ena			(mod_add_ena),
+		.rdy			(mod_add_rdy),
+		
+		.ab_addr		(mod_add_addr_ab),
+		.n_addr		(mod_add_addr_n),
+		.s_addr		(mod_add_addr_s),
+		.s_wren		(mod_add_wren_s),
+		
+		.a_din		(mod_add_din_a),
+		.b_din		(mod_add_din_b),
+		.n_din		(mod_add_din_n),
+		.s_dout		(mod_add_dout_s)
+	);
+	
+	
+		//
+		// Modular Subtractor
+		//
+	wire	mod_sub_ena;
+	wire	mod_sub_rdy;
+	
+	wire	[WORD_COUNTER_WIDTH-1:0]	mod_sub_addr_ab;
+	wire	[WORD_COUNTER_WIDTH-1:0]	mod_sub_addr_n;
+	wire	[WORD_COUNTER_WIDTH-1:0]	mod_sub_addr_d;
+	wire										mod_sub_wren_d;
+	
+	wire	[                32-1:0]	mod_sub_din_a;
+	wire	[                32-1:0]	mod_sub_din_b;
+	wire	[                32-1:0]	mod_sub_din_n;
+	wire	[                32-1:0]	mod_sub_dout_d;
+	
+	assign mod_sub_din_n = q_din;
+	
+	modular_subtractor #
+	(
+		.WORD_COUNTER_WIDTH	(WORD_COUNTER_WIDTH),
+		.OPERAND_NUM_WORDS	(OPERAND_NUM_WORDS)
+	)
+	modular_subtractor_inst
+	(
+		.clk			(clk),
+		.rst_n		(rst_n),
+		
+		.ena			(mod_sub_ena),
+		.rdy			(mod_sub_rdy),
+		
+		.ab_addr		(mod_sub_addr_ab),
+		.n_addr		(mod_sub_addr_n),
+		.d_addr		(mod_sub_addr_d),
+		.d_wren		(mod_sub_wren_d),
+		
+		.a_din		(mod_sub_din_a),
+		.b_din		(mod_sub_din_b),
+		.n_din		(mod_sub_din_n),
+		.d_dout		(mod_sub_dout_d)
+	);
+	
+	
+		//
+		// Modular Multiplier
+		//
+	wire	mod_mul_ena;
+	wire	mod_mul_rdy;
+	
+	wire	[WORD_COUNTER_WIDTH-1:0]	mod_mul_addr_a;
+	wire	[WORD_COUNTER_WIDTH-1:0]	mod_mul_addr_b;
+	wire	[WORD_COUNTER_WIDTH-1:0]	mod_mul_addr_n;
+	wire	[WORD_COUNTER_WIDTH-1:0]	mod_mul_addr_p;
+	wire										mod_mul_wren_p;
+	
+	wire	[                32-1:0]	mod_mul_din_a;
+	wire	[                32-1:0]	mod_mul_din_b;
+	wire	[                32-1:0]	mod_mul_din_n;
+	wire	[                32-1:0]	mod_mul_dout_p;
+	
+	assign mod_mul_din_n = q_din;
+	
+	modular_multiplier_256 modular_multiplier_inst
+	(
+		.clk		(clk),
+		.rst_n	(rst_n),
+		
+		.ena		(mod_mul_ena),
+		.rdy		(mod_mul_rdy),
+		
+		.a_addr	(mod_mul_addr_a),
+		.b_addr	(mod_mul_addr_b),
+		.n_addr	(mod_mul_addr_n),
+		.p_addr	(mod_mul_addr_p),
+		.p_wren	(mod_mul_wren_p),
+		
+		.a_din	(mod_mul_din_a),
+		.b_din	(mod_mul_din_b),
+		.n_din	(mod_mul_din_n),
+		.p_dout	(mod_mul_dout_p)
+	);
+	
+	
+		//
+		// Multi-Word Data Mover
+		//
+	wire	mw_mov_ena;
+	wire	mw_mov_rdy;
+	
+	wire	[WORD_COUNTER_WIDTH-1:0]	mw_mov_addr_x;
+	wire	[WORD_COUNTER_WIDTH-1:0]	mw_mov_addr_y;
+	wire										mw_mov_wren_y;
+	
+	wire	[                32-1:0]	mw_mov_din_x;
+	wire	[                32-1:0]	mw_mov_dout_y;
+	
+	mw_mover mw_mover_inst
+	(
+		.clk		(clk),
+		.rst_n	(rst_n),
+		
+		.ena		(mw_mov_ena),
+		.rdy		(mw_mov_rdy),
+		
+		.x_addr	(mw_mov_addr_x),
+		.y_addr	(mw_mov_addr_y),
+		.y_wren	(mw_mov_wren_y),
+		
+		.x_din	(mw_mov_din_x),
+		.y_dout	(mw_mov_dout_y)
+	);
+	
+	
+		//
+		// ROMs
+		//
+	reg	[WORD_COUNTER_WIDTH-1:0]	brom_one_addr;
+	//reg	[WORD_COUNTER_WIDTH-1:0]	brom_zero_addr;
+	reg	[WORD_COUNTER_WIDTH-1:0]	brom_delta_addr;
+	reg	[WORD_COUNTER_WIDTH-1:0]	brom_g_x_addr;
+	reg	[WORD_COUNTER_WIDTH-1:0]	brom_g_y_addr;
+	reg	[WORD_COUNTER_WIDTH-1:0]	brom_h_x_addr;
+	reg	[WORD_COUNTER_WIDTH-1:0]	brom_h_y_addr;
+
+	wire	[                32-1:0]	brom_one_dout;
+	wire	[                32-1:0]	brom_zero_dout;
+	wire	[                32-1:0]	brom_delta_dout;
+	wire	[                32-1:0]	brom_g_x_dout;
+	wire	[                32-1:0]	brom_g_y_dout;
+	wire	[                32-1:0]	brom_h_x_dout;
+	wire	[                32-1:0]	brom_h_y_dout;
+	
+	(* ROM_STYLE="BLOCK" *) brom_p256_one brom_one_inst
+		(.clk(clk), .b_addr(brom_one_addr), .b_out(brom_one_dout));
+		
+	brom_p256_zero brom_zero_inst
+		(.b_out(brom_zero_dout));
+		
+	(* ROM_STYLE="BLOCK" *) brom_p256_delta brom_delta_inst
+		(.clk(clk), .b_addr(brom_delta_addr), .b_out(brom_delta_dout));
+	
+	(* ROM_STYLE="BLOCK" *) brom_p256_g_x brom_g_x_inst
+		(.clk(clk), .b_addr(brom_g_x_addr), .b_out(brom_g_x_dout));
+
+	(* ROM_STYLE="BLOCK" *) brom_p256_g_y brom_g_y_inst
+		(.clk(clk), .b_addr(brom_g_y_addr), .b_out(brom_g_y_dout));
+		
+	(* ROM_STYLE="BLOCK" *) brom_p256_h_x brom_h_x_inst
+		(.clk(clk), .b_addr(brom_h_x_addr), .b_out(brom_h_x_dout));
+
+	(* ROM_STYLE="BLOCK" *) brom_p256_h_y brom_h_y_inst
+		(.clk(clk), .b_addr(brom_h_y_addr), .b_out(brom_h_y_dout));
+
+	
+		//
+		// Temporary Variables
+		//
+	reg	[WORD_COUNTER_WIDTH-1:0]	bram_t1_wr_addr;
+	reg	[WORD_COUNTER_WIDTH-1:0]	bram_t2_wr_addr;
+	reg	[WORD_COUNTER_WIDTH-1:0]	bram_t3_wr_addr;
+	reg	[WORD_COUNTER_WIDTH-1:0]	bram_t4_wr_addr;
+	
+	reg	[WORD_COUNTER_WIDTH-1:0]	bram_t1_rd_addr;
+	reg	[WORD_COUNTER_WIDTH-1:0]	bram_t2_rd_addr;
+	reg	[WORD_COUNTER_WIDTH-1:0]	bram_t3_rd_addr;
+	reg	[WORD_COUNTER_WIDTH-1:0]	bram_t4_rd_addr;
+	
+	wire										bram_t1_wr_en;
+	wire										bram_t2_wr_en;
+	wire										bram_t3_wr_en;
+	wire										bram_t4_wr_en;
+	
+	wire	[                32-1:0]	bram_t1_wr_data;
+	wire	[                32-1:0]	bram_t2_wr_data;
+	wire	[                32-1:0]	bram_t3_wr_data;
+	wire	[                32-1:0]	bram_t4_wr_data;
+	
+	wire	[                32-1:0]	bram_t1_rd_data;
+	wire	[                32-1:0]	bram_t2_rd_data;
+	wire	[                32-1:0]	bram_t3_rd_data;
+	wire	[                32-1:0]	bram_t4_rd_data;
+		
+	bram_1rw_1ro_readfirst #
+	(	.MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH)
+	)
+	bram_t1
+	(	.clk		(clk),
+		.a_addr(bram_t1_wr_addr), .a_wr(bram_t1_wr_en), .a_in(bram_t1_wr_data), .a_out(),
+		.b_addr(bram_t1_rd_addr),                                               .b_out(bram_t1_rd_data)
+	);
+	
+	bram_1rw_1ro_readfirst #
+	(	.MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH)
+	)
+	bram_t2
+	(	.clk		(clk),
+		.a_addr(bram_t2_wr_addr), .a_wr(bram_t2_wr_en), .a_in(bram_t2_wr_data), .a_out(),
+		.b_addr(bram_t2_rd_addr),                                               .b_out(bram_t2_rd_data)
+	);
+	
+	bram_1rw_1ro_readfirst #
+	(	.MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH)
+	)
+	bram_t3
+	(	.clk		(clk),
+		.a_addr(bram_t3_wr_addr), .a_wr(bram_t3_wr_en), .a_in(bram_t3_wr_data), .a_out(),
+		.b_addr(bram_t3_rd_addr),                                               .b_out(bram_t3_rd_data)
+	);
+	
+	bram_1rw_1ro_readfirst #
+	(	.MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH)
+	)
+	bram_t4
+	(	.clk		(clk),
+		.a_addr(bram_t4_wr_addr), .a_wr(bram_t4_wr_en), .a_in(bram_t4_wr_data), .a_out(),
+		.b_addr(bram_t4_rd_addr),                                               .b_out(bram_t4_rd_data)
+	);
+	
+
+		//
+		// uOP Trigger Logic
+		//
+	reg	uop_trig;
+	always @(posedge clk or negedge rst_n)
+		//
+		if (rst_n == 1'b0)	uop_trig <= 1'b0;
+		else						uop_trig <= (fsm_state == FSM_STATE_FETCH) ? 1'b1 : 1'b0;
+		
+
+		//
+		// FSM
+		//
+	localparam	[ 1: 0]	FSM_STATE_STALL	= 2'b00;
+	localparam	[ 1: 0]	FSM_STATE_FETCH	= 2'b01;
+	localparam	[ 1: 0]	FSM_STATE_EXECUTE	= 2'b10;
+	
+	reg	[ 1: 0]	fsm_state		= FSM_STATE_STALL;
+	wire	[ 1: 0]	fsm_state_next	= (uop_opcode == OPCODE_RDY) ? FSM_STATE_STALL : FSM_STATE_FETCH;
+	
+	
+		//
+		// FSM Transition Logic
+		//
+	reg	uop_done;
+	
+	always @(posedge clk or negedge rst_n)
+		//
+		if (rst_n == 1'b0)		fsm_state <= FSM_STATE_STALL;
+		else case (fsm_state)
+			FSM_STATE_STALL:		fsm_state <= ena ? FSM_STATE_FETCH : FSM_STATE_STALL;
+			FSM_STATE_FETCH:		fsm_state <= FSM_STATE_EXECUTE;
+			FSM_STATE_EXECUTE:	fsm_state <= (!uop_trig && uop_done) ? fsm_state_next : FSM_STATE_EXECUTE;
+			default:					fsm_state <= FSM_STATE_STALL;
+		endcase
+	
+	
+		//
+		// uOP Address Increment Logic
+		//
+	always @(posedge clk)
+		//
+		if (fsm_state == FSM_STATE_STALL)
+			uop_addr <= 5'd0;
+		else if (fsm_state == FSM_STATE_EXECUTE)
+			if (!uop_trig && uop_done)
+				uop_addr <= (uop_opcode == OPCODE_RDY) ? 5'd0 : uop_addr + 1'b1;
+		
+	
+		//
+		// uOP Completion Logic
+		//
+	always @(*)
+		//
+		case (uop_opcode)
+			OPCODE_CMP:	uop_done = mw_cmp_rdy;
+			OPCODE_MOV:	uop_done = mw_mov_rdy;
+			OPCODE_ADD:	uop_done = mod_add_rdy;
+			OPCODE_SUB:	uop_done = mod_sub_rdy;
+			OPCODE_MUL:	uop_done = mod_mul_rdy;
+			OPCODE_RDY:	uop_done = 1'b1;
+			default:		uop_done = 1'b0;
+		endcase
+	
+
+		//
+		// Helper Modules Enable Logic
+		//
+	assign mw_cmp_ena		= uop_opcode[0] & uop_trig;
+	assign mw_mov_ena		= uop_opcode[1] & uop_trig;
+	assign mod_add_ena	= uop_opcode[2] & uop_trig;
+	assign mod_sub_ena	= uop_opcode[3] & uop_trig;
+	assign mod_mul_ena	= uop_opcode[4] & uop_trig;
+	
+	
+		//
+		// uOP Source Value Decoding Logic
+		//
+	reg	[31: 0]	uop_src_a_value;
+	
+	always @(*)
+		//
+		case (uop_src_a)
+			UOP_SRC_PX:		uop_src_a_value = px_din;
+			UOP_SRC_PY:		uop_src_a_value = py_din;
+			UOP_SRC_PZ:		uop_src_a_value = pz_din;
+			
+			UOP_SRC_RX:		uop_src_a_value = rx_din;
+			UOP_SRC_RY:		uop_src_a_value = ry_din;
+			UOP_SRC_RZ:		uop_src_a_value = rz_din;
+			
+			UOP_SRC_T1:		uop_src_a_value = bram_t1_rd_data;
+			UOP_SRC_T2:		uop_src_a_value = bram_t2_rd_data;
+			UOP_SRC_T3:		uop_src_a_value = bram_t3_rd_data;
+			UOP_SRC_T4:		uop_src_a_value = bram_t4_rd_data;
+			
+			UOP_SRC_ONE:	uop_src_a_value = brom_one_dout;
+			UOP_SRC_ZERO:	uop_src_a_value = brom_zero_dout;
+			UOP_SRC_DELTA:	uop_src_a_value = brom_delta_dout;
+			
+			UOP_SRC_G_X:	uop_src_a_value = brom_g_x_dout;
+			UOP_SRC_G_Y:	uop_src_a_value = brom_g_y_dout;
+
+			UOP_SRC_H_X:	uop_src_a_value = brom_h_x_dout;
+			UOP_SRC_H_Y:	uop_src_a_value = brom_h_y_dout;
+			
+			UOP_SRC_V:		uop_src_a_value = v_din;
+			
+			default:			uop_src_a_value = {32{1'bX}};
+		endcase
+
+		
+	assign mw_cmp_din_x  = uop_src_a_value;
+	assign mw_mov_din_x  = uop_src_a_value;
+	assign mod_add_din_a = uop_src_a_value;
+	assign mod_sub_din_a = uop_src_a_value;
+	assign mod_mul_din_a = uop_src_a_value;
+	
+	reg	[31: 0]	uop_src_b_value;
+		
+	always @(*)
+		//
+		case (uop_src_b)
+			UOP_SRC_PX:		uop_src_b_value = px_din;
+			UOP_SRC_PY:		uop_src_b_value = py_din;
+			UOP_SRC_PZ:		uop_src_b_value = pz_din;
+			
+			UOP_SRC_RX:		uop_src_b_value = rx_din;
+			UOP_SRC_RY:		uop_src_b_value = ry_din;
+			UOP_SRC_RZ:		uop_src_b_value = rz_din;
+			
+			UOP_SRC_T1:		uop_src_b_value = bram_t1_rd_data;
+			UOP_SRC_T2:		uop_src_b_value = bram_t2_rd_data;
+			UOP_SRC_T3:		uop_src_b_value = bram_t3_rd_data;
+			UOP_SRC_T4:		uop_src_b_value = bram_t4_rd_data;
+			
+			UOP_SRC_ONE:	uop_src_b_value = brom_one_dout;
+			UOP_SRC_ZERO:	uop_src_b_value = brom_zero_dout;
+			UOP_SRC_DELTA:	uop_src_b_value = brom_delta_dout;
+
+			UOP_SRC_G_X:	uop_src_b_value = brom_g_x_dout;
+			UOP_SRC_G_Y:	uop_src_b_value = brom_g_y_dout;
+
+			UOP_SRC_H_X:	uop_src_b_value = brom_h_x_dout;
+			UOP_SRC_H_Y:	uop_src_b_value = brom_h_y_dout;
+			
+			UOP_SRC_V:		uop_src_b_value = v_din;
+			
+			default:			uop_src_b_value = {32{1'bX}};
+		endcase
+	
+	assign mw_cmp_din_y  = uop_src_b_value;
+	assign mod_add_din_b = uop_src_b_value;
+	assign mod_sub_din_b = uop_src_b_value;
+	assign mod_mul_din_b = uop_src_b_value;
+	
+	
+		//
+		// uOP Source & Destination Address Decoding Logic
+		//
+	reg	[WORD_COUNTER_WIDTH-1:0]	uop_src_a_addr;
+	reg	[WORD_COUNTER_WIDTH-1:0]	uop_src_b_addr;
+	reg	[WORD_COUNTER_WIDTH-1:0]	uop_dst_addr;
+	reg	[WORD_COUNTER_WIDTH-1:0]	uop_q_addr;
+	
+	assign q_addr = uop_q_addr;
+	
+	always @(*)
+		//
+		case (uop_opcode)
+			//
+			OPCODE_CMP:	begin
+				uop_src_a_addr = mw_cmp_addr_xy;
+				uop_src_b_addr = mw_cmp_addr_xy;
+				uop_dst_addr	= {WORD_COUNTER_WIDTH{1'bX}};
+				uop_q_addr		= {WORD_COUNTER_WIDTH{1'bX}};
+			end
+			//
+			OPCODE_MOV:	begin
+				uop_src_a_addr = mw_mov_addr_x;
+				uop_src_b_addr = {WORD_COUNTER_WIDTH{1'bX}};
+				uop_dst_addr	= mw_mov_addr_y;
+				uop_q_addr		= {WORD_COUNTER_WIDTH{1'bX}};
+			end
+			//
+			OPCODE_ADD:	begin
+				uop_src_a_addr = mod_add_addr_ab;
+				uop_src_b_addr = mod_add_addr_ab;
+				uop_dst_addr	= mod_add_addr_s;
+				uop_q_addr		= mod_add_addr_n;
+			end
+			//
+			OPCODE_SUB:	begin
+				uop_src_a_addr = mod_sub_addr_ab;
+				uop_src_b_addr = mod_sub_addr_ab;
+				uop_dst_addr	= mod_sub_addr_d;
+				uop_q_addr		= mod_sub_addr_n;
+			end
+			//
+			OPCODE_MUL:	begin
+				uop_src_a_addr = mod_mul_addr_a;
+				uop_src_b_addr = mod_mul_addr_b;
+				uop_dst_addr	= mod_mul_addr_p;
+				uop_q_addr		= mod_mul_addr_n;
+			end
+			//
+			default: begin
+				uop_src_a_addr = {WORD_COUNTER_WIDTH{1'bX}};
+				uop_src_b_addr = {WORD_COUNTER_WIDTH{1'bX}};
+				uop_dst_addr	= {WORD_COUNTER_WIDTH{1'bX}};
+				uop_q_addr		= {WORD_COUNTER_WIDTH{1'bX}};
+			end
+			//
+		endcase
+	
+	
+		//
+		// uOP Conditional Execution Logic
+		//
+	reg	uop_exec_effective;
+
+	always @(*)
+		//
+		case (uop_exec)
+			UOP_EXEC_ALWAYS:		uop_exec_effective = 1'b1;
+			UOP_EXEC_PZT1T2_0XX:	uop_exec_effective =  flag_pz_is_zero;
+			UOP_EXEC_PZT1T2_100:	uop_exec_effective = !flag_pz_is_zero && flag_t1_is_zero &&  flag_t2_is_zero;
+			UOP_EXEC_PZT1T2_101:	uop_exec_effective = !flag_pz_is_zero && flag_t1_is_zero && !flag_t2_is_zero;
+		endcase
+
+
+		//
+		// uOP Destination Store Logic
+		//
+	reg	uop_dst_wren;
+	
+	always @(*)
+		//
+		case (uop_opcode)
+			//
+			OPCODE_MOV:	uop_dst_wren = mw_mov_wren_y & uop_exec_effective;
+			OPCODE_ADD:	uop_dst_wren = mod_add_wren_s;
+			OPCODE_SUB:	uop_dst_wren = mod_sub_wren_d;
+			OPCODE_MUL:	uop_dst_wren = mod_mul_wren_p;
+			default:		uop_dst_wren = 1'b0;
+			//
+		endcase
+		
+	
+	always @(*) begin
+		//
+		//
+		//
+		if      (uop_src_a == UOP_SRC_PX) px_addr = uop_src_a_addr;
+		else if (uop_src_b == UOP_SRC_PX) px_addr = uop_src_b_addr;
+		else                              px_addr = {WORD_COUNTER_WIDTH{1'bX}};
+		//
+		if      (uop_src_a == UOP_SRC_PY) py_addr = uop_src_a_addr;
+		else if (uop_src_b == UOP_SRC_PY) py_addr = uop_src_b_addr;
+		else                              py_addr = {WORD_COUNTER_WIDTH{1'bX}};
+		//
+		if      (uop_src_a == UOP_SRC_PZ) pz_addr = uop_src_a_addr;
+		else if (uop_src_b == UOP_SRC_PZ) pz_addr = uop_src_b_addr;
+		else                              pz_addr = {WORD_COUNTER_WIDTH{1'bX}};
+		//
+		//
+		//
+		if      (uop_src_a == UOP_SRC_ONE)   brom_one_addr = uop_src_a_addr;
+		else if (uop_src_b == UOP_SRC_ONE)   brom_one_addr = uop_src_b_addr;
+		else                                 brom_one_addr = {WORD_COUNTER_WIDTH{1'bX}};
+		//
+		//if      (uop_src_a == UOP_SRC_ZERO)  brom_zero_addr = uop_src_a_addr;
+		//else if (uop_src_b == UOP_SRC_ZERO)  brom_zero_addr = uop_src_b_addr;
+		//else                                 brom_zero_addr = {WORD_COUNTER_WIDTH{1'bX}};
+		//
+		if      (uop_src_a == UOP_SRC_DELTA) brom_delta_addr = uop_src_a_addr;
+		else if (uop_src_b == UOP_SRC_DELTA) brom_delta_addr = uop_src_b_addr;
+		else                                 brom_delta_addr = {WORD_COUNTER_WIDTH{1'bX}};
+		//
+		//
+		//
+		if      (uop_src_a == UOP_SRC_G_X) brom_g_x_addr = uop_src_a_addr;
+		else if (uop_src_b == UOP_SRC_G_X) brom_g_x_addr = uop_src_b_addr;
+		else                               brom_g_x_addr = {WORD_COUNTER_WIDTH{1'bX}};
+		//
+		if      (uop_src_a == UOP_SRC_G_Y) brom_g_y_addr = uop_src_a_addr;
+		else if (uop_src_b == UOP_SRC_G_Y) brom_g_y_addr = uop_src_b_addr;
+		else                               brom_g_y_addr = {WORD_COUNTER_WIDTH{1'bX}};
+		//
+		//
+		//
+		if      (uop_src_a == UOP_SRC_H_X) brom_h_x_addr = uop_src_a_addr;
+		else if (uop_src_b == UOP_SRC_H_X) brom_h_x_addr = uop_src_b_addr;
+		else                               brom_h_x_addr = {WORD_COUNTER_WIDTH{1'bX}};
+		//
+		if      (uop_src_a == UOP_SRC_H_Y) brom_h_y_addr = uop_src_a_addr;
+		else if (uop_src_b == UOP_SRC_H_Y) brom_h_y_addr = uop_src_b_addr;
+		else                               brom_h_y_addr = {WORD_COUNTER_WIDTH{1'bX}};
+		//
+		//
+		//
+		if      (uop_src_a == UOP_SRC_V) v_addr = uop_src_a_addr;
+		else if (uop_src_b == UOP_SRC_V) v_addr = uop_src_b_addr;
+		else                             v_addr = {WORD_COUNTER_WIDTH{1'bX}};
+		//
+		//
+		//
+		if      (uop_src_a == UOP_SRC_T1) bram_t1_rd_addr = uop_src_a_addr;
+		else if (uop_src_b == UOP_SRC_T1) bram_t1_rd_addr = uop_src_b_addr;
+		else                              bram_t1_rd_addr = {WORD_COUNTER_WIDTH{1'bX}};
+		//
+		if      (uop_src_a == UOP_SRC_T2) bram_t2_rd_addr = uop_src_a_addr;
+		else if (uop_src_b == UOP_SRC_T2) bram_t2_rd_addr = uop_src_b_addr;
+		else                              bram_t2_rd_addr = {WORD_COUNTER_WIDTH{1'bX}};
+		//
+		if      (uop_src_a == UOP_SRC_T3) bram_t3_rd_addr = uop_src_a_addr;
+		else if (uop_src_b == UOP_SRC_T3) bram_t3_rd_addr = uop_src_b_addr;
+		else                              bram_t3_rd_addr = {WORD_COUNTER_WIDTH{1'bX}};
+		//
+		if      (uop_src_a == UOP_SRC_T4) bram_t4_rd_addr = uop_src_a_addr;
+		else if (uop_src_b == UOP_SRC_T4) bram_t4_rd_addr = uop_src_b_addr;
+		else                              bram_t4_rd_addr = {WORD_COUNTER_WIDTH{1'bX}};
+		//
+		//
+		//
+		if (uop_dst == UOP_DST_T1) bram_t1_wr_addr = uop_dst_addr;
+		else                       bram_t1_wr_addr = {WORD_COUNTER_WIDTH{1'bX}};
+		//
+		if (uop_dst == UOP_DST_T2) bram_t2_wr_addr = uop_dst_addr;
+		else                       bram_t2_wr_addr = {WORD_COUNTER_WIDTH{1'bX}};
+		//
+		if (uop_dst == UOP_DST_T3) bram_t3_wr_addr = uop_dst_addr;
+		else                       bram_t3_wr_addr = {WORD_COUNTER_WIDTH{1'bX}};
+		//
+		if (uop_dst == UOP_DST_T4) bram_t4_wr_addr = uop_dst_addr;
+		else                       bram_t4_wr_addr = {WORD_COUNTER_WIDTH{1'bX}};
+		//
+		//
+		//
+		if ((uop_dst == UOP_DST_RX) && (uop_dst_wren))	rx_addr = uop_dst_addr;
+		else begin
+			if      (uop_src_a == UOP_SRC_RX) 				rx_addr = uop_src_a_addr;
+			else if (uop_src_b == UOP_SRC_RX) 				rx_addr = uop_src_b_addr;
+			else                              				rx_addr = {WORD_COUNTER_WIDTH{1'bX}};
+		end
+		//
+		if ((uop_dst == UOP_DST_RY) && (uop_dst_wren))	ry_addr = uop_dst_addr;
+		else begin
+			if      (uop_src_a == UOP_SRC_RY) 				ry_addr = uop_src_a_addr;
+			else if (uop_src_b == UOP_SRC_RY) 				ry_addr = uop_src_b_addr;
+			else                              				ry_addr = {WORD_COUNTER_WIDTH{1'bX}};
+		end
+		//
+		if ((uop_dst == UOP_DST_RZ) && (uop_dst_wren))	rz_addr = uop_dst_addr;
+		else begin
+			if      (uop_src_a == UOP_SRC_RZ) 				rz_addr = uop_src_a_addr;
+			else if (uop_src_b == UOP_SRC_RZ) 				rz_addr = uop_src_b_addr;
+			else                              				rz_addr = {WORD_COUNTER_WIDTH{1'bX}};
+		end
+		//
+	end
+	
+	
+	assign rx_wren = uop_dst_wren && (uop_dst == UOP_DST_RX);
+	assign ry_wren = uop_dst_wren && (uop_dst == UOP_DST_RY);
+	assign rz_wren = uop_dst_wren && (uop_dst == UOP_DST_RZ);
+	
+	assign bram_t1_wr_en = uop_dst_wren && (uop_dst == UOP_DST_T1);
+	assign bram_t2_wr_en = uop_dst_wren && (uop_dst == UOP_DST_T2);
+	assign bram_t3_wr_en = uop_dst_wren && (uop_dst == UOP_DST_T3);
+	assign bram_t4_wr_en = uop_dst_wren && (uop_dst == UOP_DST_T4);
+	
+	
+	
+		//
+		// Destination Value Selector
+		//
+	reg	[31: 0]	uop_dst_value;
+	
+	always @(*)
+		//
+		case (uop_opcode)
+		
+			OPCODE_MOV:	uop_dst_value = mw_mov_dout_y;
+			OPCODE_ADD:	uop_dst_value = mod_add_dout_s;
+			OPCODE_SUB:	uop_dst_value = mod_sub_dout_d;
+			OPCODE_MUL:	uop_dst_value = mod_mul_dout_p;
+			
+			default:		uop_dst_value = {32{1'bX}};
+			
+		endcase
+	
+	assign rx_dout = uop_dst_value;
+	assign ry_dout = uop_dst_value;
+	assign rz_dout = uop_dst_value;
+	
+	assign bram_t1_wr_data = uop_dst_value;
+	assign bram_t2_wr_data = uop_dst_value;
+	assign bram_t3_wr_data = uop_dst_value;
+	assign bram_t4_wr_data = uop_dst_value;
+
+
+		//
+		// Latch Comparison Flags
+		//
+	always @(posedge clk)
+		//
+		if (	(fsm_state  == FSM_STATE_EXECUTE) &&
+				(uop_opcode == OPCODE_CMP)        &&
+				(uop_done && !uop_trig) ) begin
+			
+			if ( (uop_src_a == UOP_SRC_PZ) && (uop_src_b == UOP_SRC_ZERO) )
+				flag_pz_is_zero <= !mw_cmp_out_l && mw_cmp_out_e && !mw_cmp_out_g;
+				
+			if ( (uop_src_a == UOP_SRC_T1) && (uop_src_b == UOP_SRC_ZERO) )
+				flag_t1_is_zero <= !mw_cmp_out_l && mw_cmp_out_e && !mw_cmp_out_g;
+				
+			if ( (uop_src_a == UOP_SRC_T2) && (uop_src_b == UOP_SRC_ZERO) )
+				flag_t2_is_zero <= !mw_cmp_out_l && mw_cmp_out_e && !mw_cmp_out_g;
+				
+		end
+
+	
+		//
+		// Ready Flag Logic
+		//
+	reg rdy_reg = 1'b1;
+	assign rdy = rdy_reg;
+		
+	always @(posedge clk or negedge rst_n)
+		//
+		if (rst_n == 1'b0) rdy_reg <= 1'b1;
+		else begin
+			
+				/* clear flag */
+			if (fsm_state == FSM_STATE_STALL)
+				if (ena) rdy_reg <= 1'b0;
+			
+				/* set flag */
+			if ((fsm_state == FSM_STATE_EXECUTE) && !uop_trig && uop_done)
+				if (uop_opcode == OPCODE_RDY) rdy_reg <= 1'b1;
+				
+		end
+			
+	
+endmodule
+
+
+//------------------------------------------------------------------------------
+// End-of-File
+//------------------------------------------------------------------------------
diff --git a/rtl/curve/curve_mul_256.v b/rtl/curve/curve_mul_256.v
new file mode 100644
index 0000000..0ac2be0
--- /dev/null
+++ b/rtl/curve/curve_mul_256.v
@@ -0,0 +1,720 @@
+//------------------------------------------------------------------------------
+//
+// curve_mul_256.v
+// -----------------------------------------------------------------------------
+// Elliptic curve point scalar multiplier.
+//
+// Authors: Pavel Shatov
+//
+// Copyright (c) 2016, NORDUnet A/S
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// - Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+//
+// - Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+//
+// - Neither the name of the NORDUnet nor the names of its contributors may be
+//   used to endorse or promote products derived from this software without
+//   specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
+//
+//------------------------------------------------------------------------------
+
+module curve_mul_256
+	(
+		clk, rst_n,
+		ena, rdy,
+		k_addr, rx_addr, ry_addr,
+		rx_wren, ry_wren,
+		k_din,
+		rx_dout, ry_dout
+	);
+	
+
+		//
+		// Constants
+		//
+	localparam	WORD_COUNTER_WIDTH	= 3;	// 0 .. 7
+	localparam	OPERAND_NUM_WORDS		= 8;	// 8 * 32 = 256
+
+	
+		//
+		// Ports
+		//
+	input		wire	clk;		// system clock
+	input		wire	rst_n;	// active-low async reset
+	
+	input		wire	ena;		// enable input
+	output	wire	rdy;		// ready output
+				
+	output	wire	[ 2: 0]	k_addr;
+	output	wire	[ 2: 0]	rx_addr;
+	output	wire	[ 2: 0]	ry_addr;
+		
+	output	wire				rx_wren;
+	output	wire				ry_wren;
+
+	input		wire	[31: 0]	k_din;
+
+	output	wire	[31: 0]	rx_dout;
+	output	wire	[31: 0]	ry_dout;
+	
+
+		//
+		// Temporary Variables
+		//
+	reg	[ 2: 0]	bram_tx_wr_addr;
+	reg	[ 2: 0]	bram_ty_wr_addr;
+	reg	[ 2: 0]	bram_tz_wr_addr;
+	
+	reg	[ 2: 0]	bram_rx_wr_addr;
+	reg	[ 2: 0]	bram_ry_wr_addr;
+	reg	[ 2: 0]	bram_rz_wr_addr;
+	wire	[ 2: 0]	bram_rz1_wr_addr;
+	
+	reg	[ 2: 0]	bram_tx_rd_addr;
+	reg	[ 2: 0]	bram_ty_rd_addr;
+	reg	[ 2: 0]	bram_tz_rd_addr;
+	
+	reg	[ 2: 0]	bram_rx_rd_addr;
+	reg	[ 2: 0]	bram_ry_rd_addr;
+	reg	[ 2: 0]	bram_rz_rd_addr;
+	wire	[ 2: 0]	bram_rz1_rd_addr;
+	
+	reg				bram_tx_wr_en;
+	reg				bram_ty_wr_en;
+	reg				bram_tz_wr_en;
+
+	reg				bram_rx_wr_en;
+	reg				bram_ry_wr_en;
+	reg				bram_rz_wr_en;
+	wire				bram_rz1_wr_en;
+	
+	wire	[31: 0]	bram_tx_rd_data;
+	wire	[31: 0]	bram_ty_rd_data;
+	wire	[31: 0]	bram_tz_rd_data;	
+
+	wire	[31: 0]	bram_rx_rd_data;
+	wire	[31: 0]	bram_ry_rd_data;
+	wire	[31: 0]	bram_rz_rd_data;
+	wire	[31: 0]	bram_rz1_rd_data;
+	
+	reg	[31: 0]	bram_tx_wr_data_in;
+	reg	[31: 0]	bram_ty_wr_data_in;
+	reg	[31: 0]	bram_tz_wr_data_in;
+
+	reg	[31: 0]	bram_rx_wr_data_in;
+	reg	[31: 0]	bram_ry_wr_data_in;
+	reg	[31: 0]	bram_rz_wr_data_in;
+	wire	[31: 0]	bram_rz1_wr_data_in;
+	
+	wire	[31: 0]	bram_tx_wr_data_out;
+	wire	[31: 0]	bram_ty_wr_data_out;
+	wire	[31: 0]	bram_tz_wr_data_out;
+	
+	wire	[31: 0]	bram_rx_wr_data_out;
+	wire	[31: 0]	bram_ry_wr_data_out;
+	wire	[31: 0]	bram_rz_wr_data_out;
+		
+	bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(3))
+	bram_tx (.clk(clk),
+		.a_addr(bram_tx_wr_addr), .a_wr(bram_tx_wr_en), .a_in(bram_tx_wr_data_in), .a_out(bram_tx_wr_data_out),
+		.b_addr(bram_tx_rd_addr),                                                  .b_out(bram_tx_rd_data));
+	
+	bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(3))
+	bram_ty (.clk(clk),
+		.a_addr(bram_ty_wr_addr), .a_wr(bram_ty_wr_en), .a_in(bram_ty_wr_data_in), .a_out(bram_ty_wr_data_out),
+		.b_addr(bram_ty_rd_addr),                                                  .b_out(bram_ty_rd_data));
+
+	bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(3))
+	bram_tz (.clk(clk),
+		.a_addr(bram_tz_wr_addr), .a_wr(bram_tz_wr_en), .a_in(bram_tz_wr_data_in), .a_out(bram_tz_wr_data_out),
+		.b_addr(bram_tz_rd_addr),                                                  .b_out(bram_tz_rd_data));
+	
+	bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(3))
+	bram_rx (.clk(clk),
+		.a_addr(bram_rx_wr_addr), .a_wr(bram_rx_wr_en), .a_in(bram_rx_wr_data_in), .a_out(bram_rx_wr_data_out),
+		.b_addr(bram_rx_rd_addr),                                                  .b_out(bram_rx_rd_data));
+	
+	bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(3))
+	bram_ry (.clk(clk),
+		.a_addr(bram_ry_wr_addr), .a_wr(bram_ry_wr_en), .a_in(bram_ry_wr_data_in), .a_out(bram_ry_wr_data_out),
+		.b_addr(bram_ry_rd_addr),                                                  .b_out(bram_ry_rd_data));
+
+	bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(3))
+	bram_rz (.clk(clk),
+		.a_addr(bram_rz_wr_addr), .a_wr(bram_rz_wr_en), .a_in(bram_rz_wr_data_in), .a_out(bram_rz_wr_data_out),
+		.b_addr(bram_rz_rd_addr),                                                  .b_out(bram_rz_rd_data));
+		
+	bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(3))
+	bram_rz1 (.clk(clk),
+		.a_addr(bram_rz1_wr_addr), .a_wr(bram_rz1_wr_en), .a_in(bram_rz1_wr_data_in), .a_out(),
+		.b_addr(bram_rz1_rd_addr),                                                    .b_out(bram_rz1_rd_data));
+
+
+		//
+		// FSM
+		//
+	localparam	[ 3: 0]	FSM_STATE_IDLE				= 4'd00;
+	localparam	[ 3: 0]	FSM_STATE_PREPARE_TRIG	= 4'd01;
+	localparam	[ 3: 0]	FSM_STATE_PREPARE_WAIT	= 4'd02;
+	localparam	[ 3: 0]	FSM_STATE_DOUBLE_TRIG	= 4'd03;
+	localparam	[ 3: 0]	FSM_STATE_DOUBLE_WAIT	= 4'd04;
+	localparam	[ 3: 0]	FSM_STATE_ADD_TRIG		= 4'd05;
+	localparam	[ 3: 0]	FSM_STATE_ADD_WAIT		= 4'd06;
+	localparam	[ 3: 0]	FSM_STATE_COPY_TRIG		= 4'd07;
+	localparam	[ 3: 0]	FSM_STATE_COPY_WAIT		= 4'd08;
+	localparam	[ 3: 0]	FSM_STATE_INVERT_TRIG	= 4'd09;
+	localparam	[ 3: 0]	FSM_STATE_INVERT_WAIT	= 4'd10;
+	localparam	[ 3: 0]	FSM_STATE_CONVERT_TRIG	= 4'd11;
+	localparam	[ 3: 0]	FSM_STATE_CONVERT_WAIT	= 4'd12;
+	localparam	[ 3: 0]	FSM_STATE_DONE				= 4'd13;
+	
+	reg [3:0] fsm_state = FSM_STATE_IDLE;
+	
+
+		//
+		// Round Counter
+		//
+	reg	[ 7: 0]	bit_counter;
+	wire	[ 7: 0]	bit_counter_max = 8'd255;
+	wire	[ 7: 0]	bit_counter_zero = 8'd0;
+	wire	[ 7: 0]	bit_counter_next =
+		(bit_counter < bit_counter_max) ? bit_counter + 1'b1 : bit_counter_zero;
+		
+		
+		//
+		// Round Completion
+		//
+	wire [ 3: 0]	fsm_state_round_next = (bit_counter < bit_counter_max) ?
+		FSM_STATE_DOUBLE_TRIG : FSM_STATE_INVERT_TRIG;
+		
+
+		//
+		// OP Trigger Logic
+		//
+	reg	op_trig;
+	wire	op_done;
+	
+	always @(posedge clk or negedge rst_n)
+		//
+		if (rst_n == 1'b0)	op_trig <= 1'b0;
+		else						op_trig <=	(fsm_state == FSM_STATE_PREPARE_TRIG) ||
+													(fsm_state == FSM_STATE_DOUBLE_TRIG) ||
+													(fsm_state == FSM_STATE_ADD_TRIG) ||
+													(fsm_state == FSM_STATE_CONVERT_TRIG);
+		
+		//
+		// Microprograms
+		//
+	wire	[ 5: 0]	op_rom_addr;
+	wire	[19: 0]	op_rom_init_data;
+	wire	[19: 0]	op_rom_dbl_data;
+	wire	[19: 0]	op_rom_add_data;
+	wire	[19: 0]	op_rom_conv_data;
+	reg	[19: 0]	op_rom_mux_data;
+
+	(* RAM_STYLE="BLOCK" *)
+	uop_init_rom op_rom_init
+	(
+		.clk	(clk),
+		.addr	(op_rom_addr),
+		.data	(op_rom_init_data)
+	);
+	
+	(* RAM_STYLE="BLOCK" *)
+	uop_dbl_rom op_rom_dbl
+	(
+		.clk	(clk),
+		.addr	(op_rom_addr),
+		.data	(op_rom_dbl_data)
+	);
+
+	(* RAM_STYLE="BLOCK" *)
+	uop_add_rom op_rom_add
+	(
+		.clk	(clk),
+		.addr	(op_rom_addr),
+		.data	(op_rom_add_data)
+	);
+	
+	(* RAM_STYLE="BLOCK" *)
+	uop_conv_rom op_rom_conv
+	(
+		.clk	(clk),
+		.addr	(op_rom_addr),
+		.data	(op_rom_conv_data)
+	);
+	
+	always @(*)
+		//
+		case (fsm_state)
+			FSM_STATE_PREPARE_WAIT:	op_rom_mux_data = op_rom_init_data;
+			FSM_STATE_DOUBLE_WAIT:	op_rom_mux_data = op_rom_dbl_data;
+			FSM_STATE_ADD_WAIT:		op_rom_mux_data = op_rom_add_data;
+			FSM_STATE_CONVERT_WAIT:	op_rom_mux_data = op_rom_conv_data;
+			default:						op_rom_mux_data = {20{1'bX}};
+		endcase
+
+
+	
+		//
+		// Modulus
+		//
+	reg	[ 2: 0]	rom_q_addr;
+	wire	[31: 0]	rom_q_data;
+	
+	brom_p256_q rom_q
+   (
+		.clk		(clk),
+		.b_addr	(rom_q_addr),
+		.b_out	(rom_q_data)
+    );
+
+
+		//
+		// Worker
+		//
+	wire	[ 2: 0]	worker_addr_px;
+	wire	[ 2: 0]	worker_addr_py;
+	wire	[ 2: 0]	worker_addr_pz;
+	
+	wire	[ 2: 0]	worker_addr_rx;
+	wire	[ 2: 0]	worker_addr_ry;
+	wire	[ 2: 0]	worker_addr_rz;
+
+	wire	[ 2: 0]	worker_addr_q;
+	
+	wire				worker_wren_rx;
+	wire				worker_wren_ry;
+	wire				worker_wren_rz;
+	
+	reg	[31: 0]	worker_din_px;
+	reg	[31: 0]	worker_din_py;
+	reg	[31: 0]	worker_din_pz;
+	
+	reg	[31: 0]	worker_din_rx;
+	reg	[31: 0]	worker_din_ry;
+	reg	[31: 0]	worker_din_rz;
+	
+	wire	[31: 0]	worker_dout_rx;
+	wire	[31: 0]	worker_dout_ry;
+	wire	[31: 0]	worker_dout_rz;
+	
+	curve_dbl_add_256 worker
+	(
+		.clk			(clk),
+		.rst_n		(rst_n),
+		
+		.ena			(op_trig),
+		.rdy			(op_done),
+		
+		.uop_addr	(op_rom_addr),
+		.uop			(op_rom_mux_data),
+		
+		.px_addr		(worker_addr_px),
+		.py_addr		(worker_addr_py),
+		.pz_addr		(worker_addr_pz),
+		
+		.rx_addr		(worker_addr_rx),
+		.ry_addr		(worker_addr_ry),
+		.rz_addr		(worker_addr_rz),
+		
+		.q_addr		(worker_addr_q),
+		
+		.v_addr		(bram_rz1_rd_addr),
+		
+		.rx_wren		(worker_wren_rx),
+		.ry_wren		(worker_wren_ry),
+		.rz_wren		(worker_wren_rz),
+		
+		.px_din		(worker_din_px),
+		.py_din		(worker_din_py),
+		.pz_din		(worker_din_pz),
+		
+		.rx_din		(worker_din_rx),
+		.ry_din		(worker_din_ry),
+		.rz_din		(worker_din_rz),
+		
+		.rx_dout		(worker_dout_rx),
+		.ry_dout		(worker_dout_ry),
+		.rz_dout		(worker_dout_rz),
+		
+		.q_din		(rom_q_data),
+		
+		.v_din		(bram_rz1_rd_data)
+	);
+
+	
+		//
+		// Mover
+		//
+	reg	move_trig;
+	wire	move_done;
+	
+	wire	[ 2: 0]	mover_addr_x;
+	wire	[ 2: 0]	mover_addr_y;
+	
+	wire				mover_wren_y;
+	
+	always @(posedge clk or negedge rst_n)
+		//
+		if (rst_n == 1'b0)	move_trig <= 1'b0;
+		else						move_trig <= (fsm_state == FSM_STATE_COPY_TRIG);
+
+	mw_mover #
+	(
+		.WORD_COUNTER_WIDTH	(3),
+		.OPERAND_NUM_WORDS	(8)
+	)
+	mover
+	(
+		.clk		(clk),
+		.rst_n	(rst_n),
+		
+		.ena		(move_trig),
+		.rdy		(move_done),
+		
+		.x_addr	(mover_addr_x),
+		.y_addr	(mover_addr_y),
+		.y_wren	(mover_wren_y),
+		
+		.x_din	({32{1'bX}}),
+		.y_dout	()
+	);
+
+
+		//
+		// Invertor
+		//
+	reg	invert_trig;
+	wire	invert_done;
+
+	wire	[ 2: 0]	invertor_addr_a;
+	wire	[ 2: 0]	invertor_addr_q;
+
+	always @(posedge clk or negedge rst_n)
+		//
+		if (rst_n == 1'b0)	invert_trig <= 1'b0;
+		else						invert_trig <= (fsm_state == FSM_STATE_INVERT_TRIG);
+	
+	modular_invertor #
+	(
+		.MAX_OPERAND_WIDTH(256)
+	)
+	invertor
+	(
+		.clk			(clk),
+		.rst_n		(rst_n),
+		
+		.ena			(invert_trig),
+		.rdy			(invert_done),
+		
+		.a_addr		(invertor_addr_a),
+		.q_addr		(invertor_addr_q),
+		.a1_addr		(bram_rz1_wr_addr),
+		.a1_wren		(bram_rz1_wr_en),
+		
+		.a_din		(bram_rz_rd_data),
+		.q_din		(rom_q_data),
+		.a1_dout		(bram_rz1_wr_data_in)
+	);
+	
+	
+		//
+		// FSM Transition Logic
+		//
+	always @(posedge clk or negedge rst_n)
+		//
+		if (rst_n == 1'b0)			fsm_state <= FSM_STATE_IDLE;
+		else case (fsm_state)
+		
+			FSM_STATE_IDLE:			fsm_state <= ena ? FSM_STATE_PREPARE_TRIG : FSM_STATE_IDLE;
+			
+			FSM_STATE_PREPARE_TRIG:	fsm_state <= FSM_STATE_PREPARE_WAIT;
+			FSM_STATE_PREPARE_WAIT:	fsm_state <= (!op_trig && op_done) ? FSM_STATE_DOUBLE_TRIG : FSM_STATE_PREPARE_WAIT;
+			
+			FSM_STATE_DOUBLE_TRIG:	fsm_state <= FSM_STATE_DOUBLE_WAIT;
+			FSM_STATE_DOUBLE_WAIT:	fsm_state <= (!op_trig && op_done) ? FSM_STATE_ADD_TRIG : FSM_STATE_DOUBLE_WAIT;
+			
+			FSM_STATE_ADD_TRIG:		fsm_state <= FSM_STATE_ADD_WAIT;
+			FSM_STATE_ADD_WAIT:		fsm_state <= (!op_trig && op_done) ? FSM_STATE_COPY_TRIG : FSM_STATE_ADD_WAIT;
+			
+			FSM_STATE_COPY_TRIG:		fsm_state <= FSM_STATE_COPY_WAIT;
+			FSM_STATE_COPY_WAIT:		fsm_state <= (!move_trig && move_done) ? fsm_state_round_next : FSM_STATE_COPY_WAIT;
+			
+			FSM_STATE_INVERT_TRIG:	fsm_state <= FSM_STATE_INVERT_WAIT;
+			FSM_STATE_INVERT_WAIT:	fsm_state <= (!invert_trig && invert_done) ? FSM_STATE_CONVERT_TRIG : FSM_STATE_INVERT_WAIT;
+			
+			FSM_STATE_CONVERT_TRIG:	fsm_state <= FSM_STATE_CONVERT_WAIT;
+			FSM_STATE_CONVERT_WAIT:	fsm_state <= (!op_trig && op_done) ? FSM_STATE_DONE : FSM_STATE_CONVERT_WAIT;
+			
+			FSM_STATE_DONE:			fsm_state <= FSM_STATE_IDLE;
+			
+			default:						fsm_state <= FSM_STATE_IDLE;
+					
+		endcase
+	
+	
+		//
+		// Bit Counter Increment
+		//
+	always @(posedge clk) begin
+		//
+		if ((fsm_state == FSM_STATE_PREPARE_WAIT) && !op_trig && op_done)
+			bit_counter <= bit_counter_zero;
+		//	
+		if ((fsm_state == FSM_STATE_COPY_WAIT) && !move_trig && move_done)
+			bit_counter <= bit_counter_next;
+		//
+	end
+
+
+		//
+		// K Latch Logic
+		//
+	reg	[ 2: 0]	k_addr_reg;
+	reg	[31: 0]	k_din_reg;
+	
+	assign k_addr = k_addr_reg;
+	
+	always @(posedge clk) begin
+		//
+		if (fsm_state == FSM_STATE_DOUBLE_TRIG)
+			k_addr_reg <= 3'd7 - bit_counter[7:5];
+		//
+		if (fsm_state == FSM_STATE_ADD_TRIG)
+			k_din_reg <= (bit_counter[4:0] == 5'd0) ? k_din : {k_din_reg[30:0], 1'bX};
+		//
+	end
+			
+		
+		
+		//
+		// Copy Inhibit Logic
+		//
+	wire	move_inhibit = k_din_reg[31];
+	
+	wire	copy_t2r_int = mover_wren_y & ~move_inhibit;
+		
+	
+	always @(*) begin
+		//
+		// Q
+		//
+		case (fsm_state)
+			FSM_STATE_DOUBLE_WAIT:	rom_q_addr = worker_addr_q;
+			FSM_STATE_ADD_WAIT:		rom_q_addr = worker_addr_q;
+			FSM_STATE_INVERT_WAIT:	rom_q_addr = invertor_addr_q;
+			FSM_STATE_CONVERT_WAIT:	rom_q_addr = worker_addr_q;
+			default:						rom_q_addr = worker_addr_q;
+		endcase
+			
+		//
+		// R(X,Y,Z)
+		//
+		case (fsm_state)
+			//
+			FSM_STATE_PREPARE_WAIT: begin
+				//
+				bram_rx_rd_addr    <= {3{1'bX}};      bram_ry_rd_addr    <= {3{1'bX}};      bram_rz_rd_addr    <= {3{1'bX}};
+				bram_rx_wr_addr    <= worker_addr_rx; bram_ry_wr_addr    <= worker_addr_ry; bram_rz_wr_addr    <= worker_addr_rz;
+				bram_rx_wr_en      <= worker_wren_rx; bram_ry_wr_en      <= worker_wren_ry; bram_rz_wr_en      <= worker_wren_rz;
+				bram_rx_wr_data_in <= worker_dout_rx; bram_ry_wr_data_in <= worker_dout_ry; bram_rz_wr_data_in <= worker_dout_rz;
+				//
+			end
+			//
+			FSM_STATE_DOUBLE_WAIT: begin
+				//
+				bram_rx_rd_addr    <= worker_addr_px; bram_ry_rd_addr    <= worker_addr_py; bram_rz_rd_addr    <= worker_addr_pz;
+				bram_rx_wr_addr    <= {3{1'bX}};      bram_ry_wr_addr    <= {3{1'bX}};      bram_rz_wr_addr    <= {3{1'bX}};
+				bram_rx_wr_en      <= 1'b0;           bram_ry_wr_en      <= 1'b0;           bram_rz_wr_en      <= 1'b0;
+				bram_rx_wr_data_in <= {32{1'bX}};     bram_ry_wr_data_in <= {32{1'bX}};     bram_rz_wr_data_in <= {32{1'bX}};
+				//
+			end
+			//
+			FSM_STATE_ADD_WAIT: begin
+				//
+				bram_rx_rd_addr    <= {3{1'bX}};      bram_ry_rd_addr    <= {3{1'bX}};      bram_rz_rd_addr    <= {3{1'bX}};
+				bram_rx_wr_addr    <= worker_addr_rx; bram_ry_wr_addr    <= worker_addr_ry; bram_rz_wr_addr    <= worker_addr_rz;
+				bram_rx_wr_en      <= worker_wren_rx; bram_ry_wr_en      <= worker_wren_ry; bram_rz_wr_en      <= worker_wren_rz;
+				bram_rx_wr_data_in <= worker_dout_rx; bram_ry_wr_data_in <= worker_dout_ry; bram_rz_wr_data_in <= worker_dout_rz;
+				//
+			end
+			//
+			FSM_STATE_COPY_WAIT: begin
+				//
+				bram_rx_rd_addr    <= {3{1'bX}};       bram_ry_rd_addr    <= {3{1'bX}};       bram_rz_rd_addr    <= {3{1'bX}};
+				bram_rx_wr_addr    <= mover_addr_y;    bram_ry_wr_addr    <= mover_addr_y;    bram_rz_wr_addr    <= mover_addr_y;
+				bram_rx_wr_en      <= copy_t2r_int;    bram_ry_wr_en      <= copy_t2r_int;    bram_rz_wr_en      <= copy_t2r_int;
+				bram_rx_wr_data_in <= bram_tx_rd_data; bram_ry_wr_data_in <= bram_ty_rd_data; bram_rz_wr_data_in <= bram_tz_rd_data;
+				//
+			end
+			//
+			FSM_STATE_INVERT_WAIT: begin
+				//
+				bram_rx_rd_addr    <= {3{1'bX}};  bram_ry_rd_addr    <= {3{1'bX}};  bram_rz_rd_addr    <= invertor_addr_a;
+				bram_rx_wr_addr    <= {3{1'bX}};  bram_ry_wr_addr    <= {3{1'bX}};  bram_rz_wr_addr    <= {3{1'bX}};
+				bram_rx_wr_en      <= 1'b0;       bram_ry_wr_en      <= 1'b0;       bram_rz_wr_en      <= 1'b0;
+				bram_rx_wr_data_in <= {32{1'bX}}; bram_ry_wr_data_in <= {32{1'bX}}; bram_rz_wr_data_in <= {32{1'bX}};
+				//
+			end
+			//
+			FSM_STATE_CONVERT_WAIT: begin
+				//
+				bram_rx_rd_addr    <= worker_addr_px; bram_ry_rd_addr    <= worker_addr_py; bram_rz_rd_addr    <= worker_addr_pz;
+				bram_rx_wr_addr    <= {3{1'bX}};      bram_ry_wr_addr    <= {3{1'bX}};      bram_rz_wr_addr    <= {3{1'bX}};
+				bram_rx_wr_en      <= 1'b0;           bram_ry_wr_en      <= 1'b0;           bram_rz_wr_en      <= 1'b0;
+				bram_rx_wr_data_in <= {32{1'bX}};     bram_ry_wr_data_in <= {32{1'bX}};     bram_rz_wr_data_in <= {32{1'bX}};
+				//
+			end
+
+			//
+			default: begin
+				//
+				bram_rx_rd_addr    <= {3{1'bX}};  bram_ry_rd_addr    <= {3{1'bX}};  bram_rz_rd_addr    <= {3{1'bX}};
+				bram_rx_wr_addr    <= {3{1'bX}};  bram_ry_wr_addr    <= {3{1'bX}};  bram_rz_wr_addr    <= {3{1'bX}};
+				bram_rx_wr_en      <= 1'b0;       bram_ry_wr_en      <= 1'b0;       bram_rz_wr_en      <= 1'b0;
+				bram_rx_wr_data_in <= {32{1'bX}}; bram_ry_wr_data_in <= {32{1'bX}}; bram_rz_wr_data_in <= {32{1'bX}};
+				//
+			end
+			//
+		endcase
+		//
+		// T(X,Y,Z)
+		//
+		case (fsm_state)
+			//
+			FSM_STATE_DOUBLE_WAIT: begin
+				//
+				bram_tx_rd_addr    <= {3{1'bX}};      bram_ty_rd_addr    <= {3{1'bX}};      bram_tz_rd_addr    <= {3{1'bX}};
+				bram_tx_wr_addr    <= worker_addr_rx; bram_ty_wr_addr    <= worker_addr_ry; bram_tz_wr_addr    <= worker_addr_rz;
+				bram_tx_wr_en      <= worker_wren_rx; bram_ty_wr_en      <= worker_wren_ry; bram_tz_wr_en      <= worker_wren_rz;
+				bram_tx_wr_data_in <= worker_dout_rx; bram_ty_wr_data_in <= worker_dout_ry; bram_tz_wr_data_in <= worker_dout_rz;
+				//
+			end
+			//
+			FSM_STATE_ADD_WAIT: begin
+				//
+				bram_tx_rd_addr    <= worker_addr_px; bram_ty_rd_addr    <= worker_addr_py; bram_tz_rd_addr    <= worker_addr_pz;
+				bram_tx_wr_addr    <= {3{1'bX}};      bram_ty_wr_addr    <= {3{1'bX}};      bram_tz_wr_addr    <= {3{1'bX}};
+				bram_tx_wr_en      <= 1'b0;           bram_ty_wr_en      <= 1'b0;           bram_tz_wr_en      <= 1'b0;
+				bram_tx_wr_data_in <= {32{1'bX}};     bram_ty_wr_data_in <= {32{1'bX}};     bram_tz_wr_data_in <= {32{1'bX}};
+				//
+			end
+			//
+			FSM_STATE_COPY_WAIT: begin
+				//
+				bram_tx_rd_addr    <= mover_addr_x; bram_ty_rd_addr    <= mover_addr_x; bram_tz_rd_addr    <= mover_addr_x;
+				bram_tx_wr_addr    <= {3{1'bX}};    bram_ty_wr_addr    <= {3{1'bX}};    bram_tz_wr_addr    <= {3{1'bX}};
+				bram_tx_wr_en      <= 1'b0;         bram_ty_wr_en      <= 1'b0;         bram_tz_wr_en      <= 1'b0;
+				bram_tx_wr_data_in <= {32{1'bX}};   bram_ty_wr_data_in <= {32{1'bX}};   bram_tz_wr_data_in <= {32{1'bX}};
+				//
+			end
+			
+			//
+			default: begin
+				//
+				bram_tx_rd_addr    <= {3{1'bX}};  bram_ty_rd_addr    <= {3{1'bX}};  bram_tz_rd_addr    <= {3{1'bX}};
+				bram_tx_wr_addr    <= {3{1'bX}};  bram_ty_wr_addr    <= {3{1'bX}};  bram_tz_wr_addr    <= {3{1'bX}};
+				bram_tx_wr_en      <= 1'b0;       bram_ty_wr_en      <= 1'b0;       bram_tz_wr_en      <= 1'b0;
+				bram_tx_wr_data_in <= {32{1'bX}}; bram_ty_wr_data_in <= {32{1'bX}}; bram_tz_wr_data_in <= {32{1'bX}};
+				//
+			end
+			//
+		endcase
+		//
+		// Worker
+		//
+		case (fsm_state)
+			//
+			FSM_STATE_DOUBLE_WAIT: begin
+				//
+				worker_din_px <= bram_rx_rd_data;     worker_din_py <= bram_ry_rd_data;     worker_din_pz <= bram_rz_rd_data;
+				worker_din_rx <= bram_tx_wr_data_out; worker_din_ry <= bram_ty_wr_data_out; worker_din_rz <= bram_tz_wr_data_out;
+				//
+			end
+			//
+			FSM_STATE_ADD_WAIT: begin
+				//
+				worker_din_px <= bram_tx_rd_data;     worker_din_py <= bram_ty_rd_data;     worker_din_pz <= bram_tz_rd_data;
+				worker_din_rx <= bram_rx_wr_data_out; worker_din_ry <= bram_ry_wr_data_out; worker_din_rz <= bram_rz_wr_data_out;
+				//
+			end
+			//
+			FSM_STATE_CONVERT_WAIT: begin
+				//
+				worker_din_px <= bram_rx_rd_data; worker_din_py <= bram_ry_rd_data; worker_din_pz <= bram_rz_rd_data;
+				worker_din_rx <= {32{1'bX}};      worker_din_ry <= {32{1'bX}};      worker_din_rz <= {32{1'bX}};
+				//
+			end
+			//
+			default: begin
+				//
+				worker_din_px <= {32{1'bX}}; worker_din_py <= {32{1'bX}}; worker_din_pz <= {32{1'bX}};
+				worker_din_rx <= {32{1'bX}}; worker_din_ry <= {32{1'bX}}; worker_din_rz <= {32{1'bX}};
+				//
+			end
+			//
+		endcase
+		//
+	end
+
+
+		//
+		// Output Mapping
+		//
+	assign	rx_wren = worker_wren_rx && (fsm_state == FSM_STATE_CONVERT_WAIT);
+	assign	ry_wren = worker_wren_ry && (fsm_state == FSM_STATE_CONVERT_WAIT);
+
+	assign	rx_dout = worker_dout_rx;
+	assign	ry_dout = worker_dout_ry;
+	
+	assign	rx_addr = worker_addr_rx;
+	assign	ry_addr = worker_addr_ry;
+
+	
+		//
+		// Ready Flag Logic
+		//
+	reg rdy_reg = 1'b1;
+	assign rdy = rdy_reg;
+		
+	always @(posedge clk or negedge rst_n)
+		
+		if (rst_n == 1'b0) rdy_reg <= 1'b1;
+		else begin
+			
+				/* clear flag */
+			if ((fsm_state == FSM_STATE_IDLE) && ena)
+				rdy_reg <= 1'b0;
+			
+				/* set flag */
+			if (fsm_state == FSM_STATE_DONE)
+				rdy_reg <= 1'b1;
+				
+		end
+			
+	
+endmodule
+
+
+//------------------------------------------------------------------------------
+// End-of-File
+//------------------------------------------------------------------------------
diff --git a/rtl/curve/rom/brom_p256_delta.v b/rtl/curve/rom/brom_p256_delta.v
new file mode 100644
index 0000000..b9a345a
--- /dev/null
+++ b/rtl/curve/rom/brom_p256_delta.v
@@ -0,0 +1,68 @@
+//======================================================================
+//
+// Copyright (c) 2016, NORDUnet A/S All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// - Redistributions of source code must retain the above copyright
+//   notice, this list of conditions and the following disclaimer.
+//
+// - Redistributions in binary form must reproduce the above copyright
+//   notice, this list of conditions and the following disclaimer in the
+//   documentation and/or other materials provided with the distribution.
+//
+// - Neither the name of the NORDUnet nor the names of its contributors may
+//   be used to endorse or promote products derived from this software
+//   without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// HOLDER 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.
+//
+//======================================================================
+
+`timescale 1ns / 1ps
+
+module brom_p256_delta
+   (
+		input		wire				clk,
+		input		wire	[ 3-1:0]	b_addr,
+		output	wire	[32-1:0]	b_out
+    );
+
+
+   //
+   // Output Registers
+   //
+   reg [31:0] bram_reg_b;
+
+   assign b_out = bram_reg_b;
+
+
+   //
+   // Read-Only Port B
+	//
+	always @(posedge clk)
+		//
+		case (b_addr)
+			3'b000:	bram_reg_b <= 32'h00000000;
+			3'b001:	bram_reg_b <= 32'h00000000;
+			3'b010:	bram_reg_b <= 32'h80000000;
+			3'b011:	bram_reg_b <= 32'h00000000;
+			3'b100:	bram_reg_b <= 32'h00000000;
+			3'b101:	bram_reg_b <= 32'h80000000;
+			3'b110:	bram_reg_b <= 32'h80000000;
+			3'b111:	bram_reg_b <= 32'h7fffffff;
+		endcase
+
+
+endmodule
diff --git a/rtl/curve/rom/brom_p256_g_x.v b/rtl/curve/rom/brom_p256_g_x.v
new file mode 100644
index 0000000..0816ef6
--- /dev/null
+++ b/rtl/curve/rom/brom_p256_g_x.v
@@ -0,0 +1,68 @@
+//======================================================================
+//
+// Copyright (c) 2016, NORDUnet A/S All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// - Redistributions of source code must retain the above copyright
+//   notice, this list of conditions and the following disclaimer.
+//
+// - Redistributions in binary form must reproduce the above copyright
+//   notice, this list of conditions and the following disclaimer in the
+//   documentation and/or other materials provided with the distribution.
+//
+// - Neither the name of the NORDUnet nor the names of its contributors may
+//   be used to endorse or promote products derived from this software
+//   without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// HOLDER 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.
+//
+//======================================================================
+
+`timescale 1ns / 1ps
+
+module brom_p256_g_x
+   (
+		input		wire				clk,
+		input		wire	[ 3-1:0]	b_addr,
+		output	wire	[32-1:0]	b_out
+    );
+
+
+   //
+   // Output Registers
+   //
+   reg [31:0] bram_reg_b;
+
+   assign b_out = bram_reg_b;
+
+
+   //
+   // Read-Only Port B
+	//
+	always @(posedge clk)
+		//
+		case (b_addr)
+			3'b000:	bram_reg_b <= 32'hd898c296;
+			3'b001:	bram_reg_b <= 32'hf4a13945;
+			3'b010:	bram_reg_b <= 32'h2deb33a0;
+			3'b011:	bram_reg_b <= 32'h77037d81;
+			3'b100:	bram_reg_b <= 32'h63a440f2;
+			3'b101:	bram_reg_b <= 32'hf8bce6e5;
+			3'b110:	bram_reg_b <= 32'he12c4247;
+			3'b111:	bram_reg_b <= 32'h6b17d1f2;
+		endcase
+
+
+endmodule
diff --git a/rtl/curve/rom/brom_p256_g_y.v b/rtl/curve/rom/brom_p256_g_y.v
new file mode 100644
index 0000000..4d9c61e
--- /dev/null
+++ b/rtl/curve/rom/brom_p256_g_y.v
@@ -0,0 +1,68 @@
+//======================================================================
+//
+// Copyright (c) 2016, NORDUnet A/S All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// - Redistributions of source code must retain the above copyright
+//   notice, this list of conditions and the following disclaimer.
+//
+// - Redistributions in binary form must reproduce the above copyright
+//   notice, this list of conditions and the following disclaimer in the
+//   documentation and/or other materials provided with the distribution.
+//
+// - Neither the name of the NORDUnet nor the names of its contributors may
+//   be used to endorse or promote products derived from this software
+//   without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// HOLDER 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.
+//
+//======================================================================
+
+`timescale 1ns / 1ps
+
+module brom_p256_g_y
+   (
+		input		wire				clk,
+		input		wire	[ 3-1:0]	b_addr,
+		output	wire	[32-1:0]	b_out
+    );
+
+
+   //
+   // Output Registers
+   //
+   reg [31:0] bram_reg_b;
+
+   assign b_out = bram_reg_b;
+
+
+   //
+   // Read-Only Port B
+	//
+	always @(posedge clk)
+		//
+		case (b_addr)
+			3'b000:	bram_reg_b <= 32'h37bf51f5;
+			3'b001:	bram_reg_b <= 32'hcbb64068;
+			3'b010:	bram_reg_b <= 32'h6b315ece;
+			3'b011:	bram_reg_b <= 32'h2bce3357;
+			3'b100:	bram_reg_b <= 32'h7c0f9e16;
+			3'b101:	bram_reg_b <= 32'h8ee7eb4a;
+			3'b110:	bram_reg_b <= 32'hfe1a7f9b;
+			3'b111:	bram_reg_b <= 32'h4fe342e2;
+		endcase
+
+
+endmodule
diff --git a/rtl/curve/rom/brom_p256_h_x.v b/rtl/curve/rom/brom_p256_h_x.v
new file mode 100644
index 0000000..0b69f77
--- /dev/null
+++ b/rtl/curve/rom/brom_p256_h_x.v
@@ -0,0 +1,68 @@
+//======================================================================
+//
+// Copyright (c) 2016, NORDUnet A/S All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// - Redistributions of source code must retain the above copyright
+//   notice, this list of conditions and the following disclaimer.
+//
+// - Redistributions in binary form must reproduce the above copyright
+//   notice, this list of conditions and the following disclaimer in the
+//   documentation and/or other materials provided with the distribution.
+//
+// - Neither the name of the NORDUnet nor the names of its contributors may
+//   be used to endorse or promote products derived from this software
+//   without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// HOLDER 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.
+//
+//======================================================================
+
+`timescale 1ns / 1ps
+
+module brom_p256_h_x
+   (
+		input		wire				clk,
+		input		wire	[ 3-1:0]	b_addr,
+		output	wire	[32-1:0]	b_out
+    );
+
+
+   //
+   // Output Registers
+   //
+   reg [31:0] bram_reg_b;
+
+   assign b_out = bram_reg_b;
+
+
+   //
+   // Read-Only Port B
+	//
+	always @(posedge clk)
+		//
+		case (b_addr)
+			3'b000:	bram_reg_b <= 32'h4ece7ad0;
+			3'b001:	bram_reg_b <= 32'h16bd8d74;
+			3'b010:	bram_reg_b <= 32'ha42998be;
+			3'b011:	bram_reg_b <= 32'h11f904fe;
+			3'b100:	bram_reg_b <= 32'h38b77e1b;
+			3'b101:	bram_reg_b <= 32'h0e863235;
+			3'b110:	bram_reg_b <= 32'h3da77b71;
+			3'b111:	bram_reg_b <= 32'h29d05c19;
+		endcase
+
+
+endmodule
diff --git a/rtl/curve/rom/brom_p256_h_y.v b/rtl/curve/rom/brom_p256_h_y.v
new file mode 100644
index 0000000..362fce6
--- /dev/null
+++ b/rtl/curve/rom/brom_p256_h_y.v
@@ -0,0 +1,68 @@
+//======================================================================
+//
+// Copyright (c) 2016, NORDUnet A/S All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// - Redistributions of source code must retain the above copyright
+//   notice, this list of conditions and the following disclaimer.
+//
+// - Redistributions in binary form must reproduce the above copyright
+//   notice, this list of conditions and the following disclaimer in the
+//   documentation and/or other materials provided with the distribution.
+//
+// - Neither the name of the NORDUnet nor the names of its contributors may
+//   be used to endorse or promote products derived from this software
+//   without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// HOLDER 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.
+//
+//======================================================================
+
+`timescale 1ns / 1ps
+
+module brom_p256_h_y
+   (
+		input		wire				clk,
+		input		wire	[ 3-1:0]	b_addr,
+		output	wire	[32-1:0]	b_out
+    );
+
+
+   //
+   // Output Registers
+   //
+   reg [31:0] bram_reg_b;
+
+   assign b_out = bram_reg_b;
+
+
+   //
+   // Read-Only Port B
+	//
+	always @(posedge clk)
+		//
+		case (b_addr)
+			3'b000:	bram_reg_b <= 32'hc840ae07;
+			3'b001:	bram_reg_b <= 32'h3449bf97;
+			3'b010:	bram_reg_b <= 32'h94cea131;
+			3'b011:	bram_reg_b <= 32'hd431cca9;
+			3'b100:	bram_reg_b <= 32'h83f061e9;
+			3'b101:	bram_reg_b <= 32'h711814b5;
+			3'b110:	bram_reg_b <= 32'h01e58065;
+			3'b111:	bram_reg_b <= 32'hb01cbd1c;
+		endcase
+
+
+endmodule
diff --git a/rtl/curve/rom/brom_p256_one.v b/rtl/curve/rom/brom_p256_one.v
new file mode 100644
index 0000000..4097874
--- /dev/null
+++ b/rtl/curve/rom/brom_p256_one.v
@@ -0,0 +1,68 @@
+//======================================================================
+//
+// Copyright (c) 2016, NORDUnet A/S All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// - Redistributions of source code must retain the above copyright
+//   notice, this list of conditions and the following disclaimer.
+//
+// - Redistributions in binary form must reproduce the above copyright
+//   notice, this list of conditions and the following disclaimer in the
+//   documentation and/or other materials provided with the distribution.
+//
+// - Neither the name of the NORDUnet nor the names of its contributors may
+//   be used to endorse or promote products derived from this software
+//   without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// HOLDER 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.
+//
+//======================================================================
+
+`timescale 1ns / 1ps
+
+module brom_p256_one
+   (
+		input		wire				clk,
+		input		wire	[ 3-1:0]	b_addr,
+		output	wire	[32-1:0]	b_out
+    );
+
+
+   //
+   // Output Registers
+   //
+   reg [31:0] bram_reg_b;
+
+   assign b_out = bram_reg_b;
+
+
+   //
+   // Read-Only Port B
+	//
+	always @(posedge clk)
+		//
+		case (b_addr)
+			3'b000:	bram_reg_b <= 32'h00000001;
+			3'b001:	bram_reg_b <= 32'h00000000;
+			3'b010:	bram_reg_b <= 32'h00000000;
+			3'b011:	bram_reg_b <= 32'h00000000;
+			3'b100:	bram_reg_b <= 32'h00000000;
+			3'b101:	bram_reg_b <= 32'h00000000;
+			3'b110:	bram_reg_b <= 32'h00000000;
+			3'b111:	bram_reg_b <= 32'h00000000;
+		endcase
+
+
+endmodule
diff --git a/rtl/curve/rom/brom_p256_q.v b/rtl/curve/rom/brom_p256_q.v
new file mode 100644
index 0000000..fe94593
--- /dev/null
+++ b/rtl/curve/rom/brom_p256_q.v
@@ -0,0 +1,68 @@
+//======================================================================
+//
+// Copyright (c) 2016, NORDUnet A/S All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// - Redistributions of source code must retain the above copyright
+//   notice, this list of conditions and the following disclaimer.
+//
+// - Redistributions in binary form must reproduce the above copyright
+//   notice, this list of conditions and the following disclaimer in the
+//   documentation and/or other materials provided with the distribution.
+//
+// - Neither the name of the NORDUnet nor the names of its contributors may
+//   be used to endorse or promote products derived from this software
+//   without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// HOLDER 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.
+//
+//======================================================================
+
+`timescale 1ns / 1ps
+
+module brom_p256_q
+   (
+		input		wire				clk,
+		input		wire	[ 3-1:0]	b_addr,
+		output	wire	[32-1:0]	b_out
+    );
+
+
+   //
+   // Output Registers
+   //
+   reg [31:0] bram_reg_b;
+
+   assign b_out = bram_reg_b;
+
+
+   //
+   // Read-Only Port B
+	//
+	always @(posedge clk)
+		//
+		case (b_addr)
+			3'b000:	bram_reg_b <= 32'hffffffff;
+			3'b001:	bram_reg_b <= 32'hffffffff;
+			3'b010:	bram_reg_b <= 32'hffffffff;
+			3'b011:	bram_reg_b <= 32'h00000000;
+			3'b100:	bram_reg_b <= 32'h00000000;
+			3'b101:	bram_reg_b <= 32'h00000000;
+			3'b110:	bram_reg_b <= 32'h00000001;
+			3'b111:	bram_reg_b <= 32'hffffffff;
+		endcase
+
+
+endmodule
diff --git a/rtl/curve/rom/brom_p256_zero.v b/rtl/curve/rom/brom_p256_zero.v
new file mode 100644
index 0000000..f6d19a1
--- /dev/null
+++ b/rtl/curve/rom/brom_p256_zero.v
@@ -0,0 +1,70 @@
+//======================================================================
+//
+// Copyright (c) 2016, NORDUnet A/S All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// - Redistributions of source code must retain the above copyright
+//   notice, this list of conditions and the following disclaimer.
+//
+// - Redistributions in binary form must reproduce the above copyright
+//   notice, this list of conditions and the following disclaimer in the
+//   documentation and/or other materials provided with the distribution.
+//
+// - Neither the name of the NORDUnet nor the names of its contributors may
+//   be used to endorse or promote products derived from this software
+//   without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// HOLDER 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.
+//
+//======================================================================
+
+`timescale 1ns / 1ps
+
+module brom_p256_zero
+   (
+		//input		wire				clk,
+		//input		wire	[ 3-1:0]	b_addr,
+		output	wire	[32-1:0]	b_out
+    );
+
+
+	assign b_out = {32{1'b0}};
+
+   //
+   // Output Registers
+   //
+   //reg [31:0] bram_reg_b;
+
+   //assign b_out = bram_reg_b;
+
+
+   //
+   // Read-Only Port B
+	//
+	//always @(posedge clk)
+		//
+		//case (b_addr)
+			//3'b000:	bram_reg_b <= 32'h00000000;
+			//3'b001:	bram_reg_b <= 32'h00000000;
+			//3'b010:	bram_reg_b <= 32'h00000000;
+			//3'b011:	bram_reg_b <= 32'h00000000;
+			//3'b100:	bram_reg_b <= 32'h00000000;
+			//3'b101:	bram_reg_b <= 32'h00000000;
+			//3'b110:	bram_reg_b <= 32'h00000000;
+			//3'b111:	bram_reg_b <= 32'h00000000;
+		//endcase
+
+
+endmodule
diff --git a/rtl/curve/uop/uop_add_rom.v b/rtl/curve/uop/uop_add_rom.v
new file mode 100644
index 0000000..c807736
--- /dev/null
+++ b/rtl/curve/uop/uop_add_rom.v
@@ -0,0 +1,66 @@
+`timescale 1ns / 1ps
+
+module uop_add_rom
+	(
+		input		wire				clk,
+		input		wire	[ 5: 0]	addr,
+		output	reg	[19: 0]	data
+    );
+
+
+		//
+		// Microcode
+		//
+`include "..\uop_ecdsa.v"
+
+
+   	//
+		// Addition Microprogram
+		//
+   always @(posedge clk)
+
+		case (addr)
+		
+/*  2. */6'd00:	data <= {OPCODE_CMP, UOP_SRC_PZ,    UOP_SRC_ZERO,  UOP_DST_DUMMY, UOP_EXEC_ALWAYS};
+/*  3. */6'd01:	data <= {OPCODE_MOV, UOP_SRC_PZ,    UOP_SRC_DUMMY, UOP_DST_T1,    UOP_EXEC_ALWAYS};
+			6'd02:	data <= {OPCODE_MUL, UOP_SRC_PZ,    UOP_SRC_T1,    UOP_DST_T1,    UOP_EXEC_ALWAYS};
+/*  4. */6'd03:	data <= {OPCODE_MUL, UOP_SRC_PZ,    UOP_SRC_T1,    UOP_DST_T2,    UOP_EXEC_ALWAYS};
+/*  5. */6'd04:	data <= {OPCODE_MUL, UOP_SRC_T1,    UOP_SRC_G_X,   UOP_DST_T1,    UOP_EXEC_ALWAYS};
+/*  6. */6'd05:	data <= {OPCODE_MUL, UOP_SRC_T2,    UOP_SRC_G_Y,   UOP_DST_T2,    UOP_EXEC_ALWAYS};
+/*  7. */6'd06:	data <= {OPCODE_SUB, UOP_SRC_T1,    UOP_SRC_PX,    UOP_DST_T1,    UOP_EXEC_ALWAYS};
+/*  8. */6'd07:	data <= {OPCODE_SUB, UOP_SRC_T2,    UOP_SRC_PY,    UOP_DST_T2,    UOP_EXEC_ALWAYS};
+/*  9. */6'd08:	data <= {OPCODE_CMP, UOP_SRC_T1,    UOP_SRC_ZERO,  UOP_DST_DUMMY, UOP_EXEC_ALWAYS};
+			6'd09:	data <= {OPCODE_CMP, UOP_SRC_T2,    UOP_SRC_ZERO,  UOP_DST_DUMMY, UOP_EXEC_ALWAYS};
+/* 10. */6'd10:	data <= {OPCODE_MUL, UOP_SRC_PZ,    UOP_SRC_T1,    UOP_DST_RZ,    UOP_EXEC_ALWAYS};
+/* 11. */6'd11:	data <= {OPCODE_MOV, UOP_SRC_T1,    UOP_SRC_DUMMY, UOP_DST_T3,    UOP_EXEC_ALWAYS};
+			6'd12:	data <= {OPCODE_MUL, UOP_SRC_T1,    UOP_SRC_T3,    UOP_DST_T3,    UOP_EXEC_ALWAYS};
+/* 12. */6'd13:	data <= {OPCODE_MUL, UOP_SRC_T1,    UOP_SRC_T3,    UOP_DST_T4,    UOP_EXEC_ALWAYS};
+/* 13. */6'd14:	data <= {OPCODE_MUL, UOP_SRC_PX,    UOP_SRC_T3,    UOP_DST_T3,    UOP_EXEC_ALWAYS};
+/* 14. */6'd15:	data <= {OPCODE_ADD, UOP_SRC_T3,    UOP_SRC_T3,    UOP_DST_T1,    UOP_EXEC_ALWAYS};
+/* 15. */6'd16:	data <= {OPCODE_MOV, UOP_SRC_T2,    UOP_SRC_DUMMY, UOP_DST_RX,    UOP_EXEC_ALWAYS};
+			6'd17:	data <= {OPCODE_MUL, UOP_SRC_RX,    UOP_SRC_T2,    UOP_DST_RX,    UOP_EXEC_ALWAYS};
+/* 16. */6'd18:	data <= {OPCODE_SUB, UOP_SRC_RX,    UOP_SRC_T1,    UOP_DST_RX,    UOP_EXEC_ALWAYS};
+/* 17. */6'd19:	data <= {OPCODE_SUB, UOP_SRC_RX,    UOP_SRC_T4,    UOP_DST_RX,    UOP_EXEC_ALWAYS};
+/* 18. */6'd20:	data <= {OPCODE_SUB, UOP_SRC_T3,    UOP_SRC_RX,    UOP_DST_T3,    UOP_EXEC_ALWAYS};
+/* 19. */6'd21:	data <= {OPCODE_MUL, UOP_SRC_T2,    UOP_SRC_T3,    UOP_DST_T3,    UOP_EXEC_ALWAYS};
+/* 20. */6'd22:	data <= {OPCODE_MUL, UOP_SRC_PY,    UOP_SRC_T4,    UOP_DST_T4,    UOP_EXEC_ALWAYS};
+/* 21. */6'd23:	data <= {OPCODE_SUB, UOP_SRC_T3,    UOP_SRC_T4,    UOP_DST_RY,    UOP_EXEC_ALWAYS};
+
+			6'd24:	data <= {OPCODE_MOV, UOP_SRC_G_X,   UOP_SRC_DUMMY, UOP_DST_RX,    UOP_EXEC_PZT1T2_0XX};
+			6'd25:	data <= {OPCODE_MOV, UOP_SRC_G_Y,   UOP_SRC_DUMMY, UOP_DST_RY,    UOP_EXEC_PZT1T2_0XX};
+			6'd26:	data <= {OPCODE_MOV, UOP_SRC_ONE,   UOP_SRC_DUMMY, UOP_DST_RZ,    UOP_EXEC_PZT1T2_0XX};
+			
+			6'd27:	data <= {OPCODE_MOV, UOP_SRC_H_X,   UOP_SRC_DUMMY, UOP_DST_RX,    UOP_EXEC_PZT1T2_100};
+			6'd28:	data <= {OPCODE_MOV, UOP_SRC_H_Y,   UOP_SRC_DUMMY, UOP_DST_RY,    UOP_EXEC_PZT1T2_100};
+			6'd29:	data <= {OPCODE_MOV, UOP_SRC_ONE,   UOP_SRC_DUMMY, UOP_DST_RZ,    UOP_EXEC_PZT1T2_100};
+			
+			6'd30:	data <= {OPCODE_MOV, UOP_SRC_ONE,   UOP_SRC_DUMMY, UOP_DST_RX,    UOP_EXEC_PZT1T2_101};
+			6'd31:	data <= {OPCODE_MOV, UOP_SRC_ONE,   UOP_SRC_DUMMY, UOP_DST_RY,    UOP_EXEC_PZT1T2_101};
+			6'd32:	data <= {OPCODE_MOV, UOP_SRC_ZERO,  UOP_SRC_DUMMY, UOP_DST_RZ,    UOP_EXEC_PZT1T2_101};
+			
+			default:	data <= {OPCODE_RDY, UOP_SRC_DUMMY, UOP_SRC_DUMMY, UOP_DST_DUMMY};
+			
+		endcase
+		
+
+endmodule
diff --git a/rtl/curve/uop/uop_conv_rom.v b/rtl/curve/uop/uop_conv_rom.v
new file mode 100644
index 0000000..3097736
--- /dev/null
+++ b/rtl/curve/uop/uop_conv_rom.v
@@ -0,0 +1,38 @@
+`timescale 1ns / 1ps
+
+module uop_conv_rom
+	(
+		input		wire				clk,
+		input		wire	[ 5: 0]	addr,
+		output	reg	[19: 0]	data
+    );
+
+
+		//
+		// Microcode
+		//
+`include "..\uop_ecdsa.v"
+
+
+   	//
+		// Doubling Microprogram
+		//
+   always @(posedge clk)
+
+		case (addr)
+		
+			6'd00:	data <= {OPCODE_CMP, UOP_SRC_PZ,   UOP_SRC_ZERO,  UOP_DST_DUMMY, UOP_EXEC_ALWAYS};
+			6'd01:	data <= {OPCODE_MOV, UOP_SRC_V,    UOP_SRC_DUMMY, UOP_DST_T1,    UOP_EXEC_ALWAYS};
+			6'd02:	data <= {OPCODE_MUL, UOP_SRC_V,    UOP_SRC_T1,    UOP_DST_T2,    UOP_EXEC_ALWAYS};
+			6'd03:	data <= {OPCODE_MUL, UOP_SRC_V,    UOP_SRC_T2,    UOP_DST_T3,    UOP_EXEC_ALWAYS};
+			6'd04:	data <= {OPCODE_MUL, UOP_SRC_PX,   UOP_SRC_T2,    UOP_DST_RX,    UOP_EXEC_ALWAYS};
+			6'd05:	data <= {OPCODE_MUL, UOP_SRC_PY,   UOP_SRC_T3,    UOP_DST_RY,    UOP_EXEC_ALWAYS};
+			6'd06:	data <= {OPCODE_MOV, UOP_SRC_ZERO, UOP_SRC_DUMMY, UOP_DST_RX,    UOP_EXEC_PZT1T2_0XX};
+			6'd07:	data <= {OPCODE_MOV, UOP_SRC_ZERO, UOP_SRC_DUMMY, UOP_DST_RY,    UOP_EXEC_PZT1T2_0XX};
+			
+			default:	data <= {OPCODE_RDY, UOP_SRC_DUMMY, UOP_SRC_DUMMY, UOP_DST_DUMMY};
+			
+		endcase
+		
+
+endmodule
diff --git a/rtl/curve/uop/uop_dbl_rom.v b/rtl/curve/uop/uop_dbl_rom.v
new file mode 100644
index 0000000..1939ca9
--- /dev/null
+++ b/rtl/curve/uop/uop_dbl_rom.v
@@ -0,0 +1,58 @@
+`timescale 1ns / 1ps
+
+module uop_dbl_rom
+	(
+		input		wire				clk,
+		input		wire	[ 5: 0]	addr,
+		output	reg	[19: 0]	data
+    );
+
+
+		//
+		// Microcode
+		//
+`include "..\uop_ecdsa.v"
+
+
+   	//
+		// Doubling Microprogram
+		//
+   always @(posedge clk)
+
+		case (addr)
+		
+/*  1. */6'd00:	data <= {OPCODE_CMP, UOP_SRC_PZ,    UOP_SRC_ZERO,  UOP_DST_DUMMY, UOP_EXEC_ALWAYS};
+/*  2. */6'd01:	data <= {OPCODE_MOV, UOP_SRC_PZ,    UOP_SRC_DUMMY, UOP_DST_T1,    UOP_EXEC_ALWAYS};
+			5'd02:	data <= {OPCODE_MUL, UOP_SRC_PZ,    UOP_SRC_T1,    UOP_DST_T1,    UOP_EXEC_ALWAYS};
+/*  3. */6'd03:	data <= {OPCODE_SUB, UOP_SRC_PX,    UOP_SRC_T1,    UOP_DST_T2,    UOP_EXEC_ALWAYS};
+/*  4. */6'd04:	data <= {OPCODE_ADD, UOP_SRC_PX,    UOP_SRC_T1,    UOP_DST_T1,    UOP_EXEC_ALWAYS};
+/*  5. */6'd05:	data <= {OPCODE_MUL, UOP_SRC_T1,    UOP_SRC_T2,    UOP_DST_T2,    UOP_EXEC_ALWAYS};
+/*  6. */6'd06:	data <= {OPCODE_ADD, UOP_SRC_T2,    UOP_SRC_T2,    UOP_DST_T1,    UOP_EXEC_ALWAYS};
+         6'd07:	data <= {OPCODE_ADD, UOP_SRC_T1,    UOP_SRC_T2,    UOP_DST_T2,    UOP_EXEC_ALWAYS};
+/*  7. */6'd08:	data <= {OPCODE_ADD, UOP_SRC_PY,    UOP_SRC_PY,    UOP_DST_RY,    UOP_EXEC_ALWAYS};
+/*  8. */6'd09:	data <= {OPCODE_MUL, UOP_SRC_PZ,    UOP_SRC_RY,    UOP_DST_RZ,    UOP_EXEC_ALWAYS};
+/*  9. */6'd10:	data <= {OPCODE_MOV, UOP_SRC_RY,    UOP_SRC_DUMMY, UOP_DST_T1,    UOP_EXEC_ALWAYS};
+         6'd11:	data <= {OPCODE_MOV, UOP_SRC_RY,    UOP_SRC_DUMMY, UOP_DST_T3,    UOP_EXEC_ALWAYS};
+         6'd12:	data <= {OPCODE_MUL, UOP_SRC_T1,    UOP_SRC_T3,    UOP_DST_RY,    UOP_EXEC_ALWAYS};
+/* 10. */6'd13:	data <= {OPCODE_MUL, UOP_SRC_PX,    UOP_SRC_RY,    UOP_DST_T3,    UOP_EXEC_ALWAYS};
+/* 11. */6'd14:	data <= {OPCODE_MOV, UOP_SRC_RY,    UOP_SRC_DUMMY, UOP_DST_T1,    UOP_EXEC_ALWAYS};
+         6'd15:	data <= {OPCODE_MUL, UOP_SRC_RY,    UOP_SRC_T1,    UOP_DST_T1,    UOP_EXEC_ALWAYS};
+/* 12. */6'd16:	data <= {OPCODE_MUL, UOP_SRC_T1,    UOP_SRC_DELTA, UOP_DST_RY,    UOP_EXEC_ALWAYS};
+/* 13. */6'd17:	data <= {OPCODE_MOV, UOP_SRC_T2,    UOP_SRC_DUMMY, UOP_DST_T1,    UOP_EXEC_ALWAYS};
+         6'd18:	data <= {OPCODE_MUL, UOP_SRC_T1,    UOP_SRC_T2,    UOP_DST_RX,    UOP_EXEC_ALWAYS};
+/* 14. */6'd19:	data <= {OPCODE_ADD, UOP_SRC_T3,    UOP_SRC_T3,    UOP_DST_T1,    UOP_EXEC_ALWAYS};
+/* 15. */6'd20:	data <= {OPCODE_SUB, UOP_SRC_RX,    UOP_SRC_T1,    UOP_DST_RX,    UOP_EXEC_ALWAYS};
+/* 16. */6'd21:	data <= {OPCODE_SUB, UOP_SRC_T3,    UOP_SRC_RX,    UOP_DST_T1,    UOP_EXEC_ALWAYS};	
+/* 17. */6'd22:	data <= {OPCODE_MUL, UOP_SRC_T1,    UOP_SRC_T2,    UOP_DST_T1,    UOP_EXEC_ALWAYS};
+/* 18. */6'd23:	data <= {OPCODE_SUB, UOP_SRC_T1,    UOP_SRC_RY,    UOP_DST_RY,    UOP_EXEC_ALWAYS};
+
+			6'd24:	data <= {OPCODE_MOV, UOP_SRC_ONE,   UOP_SRC_DUMMY, UOP_DST_RX,    UOP_EXEC_PZT1T2_0XX};
+			6'd25:	data <= {OPCODE_MOV, UOP_SRC_ONE,   UOP_SRC_DUMMY, UOP_DST_RY,    UOP_EXEC_PZT1T2_0XX};
+			6'd26:	data <= {OPCODE_MOV, UOP_SRC_ZERO,  UOP_SRC_DUMMY, UOP_DST_RZ,    UOP_EXEC_PZT1T2_0XX};
+			
+			default:	data <= {OPCODE_RDY, UOP_SRC_DUMMY, UOP_SRC_DUMMY, UOP_DST_DUMMY};
+			
+		endcase
+		
+
+endmodule
diff --git a/rtl/curve/uop/uop_init_rom.v b/rtl/curve/uop/uop_init_rom.v
new file mode 100644
index 0000000..ac44b55
--- /dev/null
+++ b/rtl/curve/uop/uop_init_rom.v
@@ -0,0 +1,33 @@
+`timescale 1ns / 1ps
+
+module uop_init_rom
+	(
+		input		wire				clk,
+		input		wire	[ 5: 0]	addr,
+		output	reg	[19: 0]	data
+    );
+
+
+		//
+		// Microcode
+		//
+`include "..\uop_ecdsa.v"
+
+
+   	//
+		// Doubling Microprogram
+		//
+   always @(posedge clk)
+
+		case (addr)
+		
+			6'd00:	data <= {OPCODE_MOV, UOP_SRC_ONE,  UOP_SRC_DUMMY, UOP_DST_RX, UOP_EXEC_ALWAYS};
+			6'd01:	data <= {OPCODE_MOV, UOP_SRC_ONE,  UOP_SRC_DUMMY, UOP_DST_RY, UOP_EXEC_ALWAYS};
+			6'd02:	data <= {OPCODE_MOV, UOP_SRC_ZERO, UOP_SRC_DUMMY, UOP_DST_RZ, UOP_EXEC_ALWAYS};
+			
+			default:	data <= {OPCODE_RDY, UOP_SRC_DUMMY, UOP_SRC_DUMMY, UOP_DST_DUMMY};
+			
+		endcase
+		
+
+endmodule
diff --git a/rtl/curve/uop_ecdsa.v b/rtl/curve/uop_ecdsa.v
new file mode 100644
index 0000000..e64119d
--- /dev/null
+++ b/rtl/curve/uop_ecdsa.v
@@ -0,0 +1,50 @@
+localparam	[ 4: 0]	OPCODE_CMP			= 5'b00001;
+localparam	[ 4: 0]	OPCODE_MOV			= 5'b00010;
+localparam	[ 4: 0]	OPCODE_ADD			= 5'b00100;
+localparam	[ 4: 0]	OPCODE_SUB			= 5'b01000;
+localparam	[ 4: 0]	OPCODE_MUL			= 5'b10000;
+localparam	[ 4: 0]	OPCODE_RDY			= 5'b00000;
+
+localparam	[ 4: 0]	UOP_SRC_PX			= 5'h0_0;
+localparam	[ 4: 0]	UOP_SRC_PY			= 5'h0_1;
+localparam	[ 4: 0]	UOP_SRC_PZ			= 5'h0_2;
+
+localparam	[ 4: 0]	UOP_SRC_RX			= 5'h0_3;
+localparam	[ 4: 0]	UOP_SRC_RY			= 5'h0_4;
+localparam	[ 4: 0]	UOP_SRC_RZ			= 5'h0_5;
+
+localparam	[ 4: 0]	UOP_SRC_T1			= 5'h0_6;
+localparam	[ 4: 0]	UOP_SRC_T2			= 5'h0_7;
+localparam	[ 4: 0]	UOP_SRC_T3			= 5'h0_8;
+localparam	[ 4: 0]	UOP_SRC_T4			= 5'h0_9;
+
+localparam	[ 4: 0]	UOP_SRC_ONE			= 5'h0_A;
+localparam	[ 4: 0]	UOP_SRC_ZERO		= 5'h0_B;
+localparam	[ 4: 0]	UOP_SRC_DELTA		= 5'h0_C;
+
+localparam	[ 4: 0]	UOP_SRC_V			= 5'h0_F;
+
+localparam	[ 4: 0]	UOP_SRC_G_X			= 5'h1_0;
+localparam	[ 4: 0]	UOP_SRC_G_Y			= 5'h1_1;
+
+localparam	[ 4: 0]	UOP_SRC_H_X			= 5'h1_2;
+localparam	[ 4: 0]	UOP_SRC_H_Y			= 5'h1_3;
+
+localparam	[ 4: 0]	UOP_SRC_DUMMY		= 5'hX_X;
+
+localparam	[ 2: 0]	UOP_DST_RX			= 3'd0;
+localparam	[ 2: 0]	UOP_DST_RY			= 3'd1;
+localparam	[ 2: 0]	UOP_DST_RZ			= 3'd2;
+
+localparam	[ 2: 0]	UOP_DST_T1			= 3'd3;
+localparam	[ 2: 0]	UOP_DST_T2			= 3'd4;
+localparam	[ 2: 0]	UOP_DST_T3			= 3'd5;
+localparam	[ 2: 0]	UOP_DST_T4			= 3'd6;
+
+localparam	[ 2: 0]	UOP_DST_DUMMY		= 3'dX;
+
+localparam				UOP_EXEC_ALWAYS		= 2'b11;	// R
+localparam				UOP_EXEC_PZT1T2_0XX	= 2'b10;	// G
+localparam				UOP_EXEC_PZT1T2_100	= 2'b00;	// H
+localparam				UOP_EXEC_PZT1T2_101	= 2'b01;	// O
+
-- 
cgit v1.2.3