├── README.md ├── system ├── tb.tcl ├── bit_sel_b.v ├── bit_sel.v ├── sha2.v ├── bit_expand.v ├── wave.do ├── comm_buf.v ├── matrix_mul.v ├── sha256.v ├── row_sel.v ├── system_test.v └── system.v ├── SW ├── matrix.h ├── lpn.h ├── matrix.c ├── dac.c ├── dac.h ├── adc.h ├── adc.c ├── lpn.c ├── dma_passthrough.h ├── helloworld.c └── dma_passthrough.c ├── TRNG ├── ringosc.v └── trng_wrapper.v ├── LPN_PUF_complete_test ├── tcl │ ├── my_xdc.xdc │ ├── dma_ex_interrupt.tcl │ └── bd_zedboard.tcl └── lib │ └── xilinx.com_user_tlast_gen_1.0 │ ├── xgui │ └── tlast_gen_v1_0.tcl │ ├── tlast_gen.v │ └── component.xml ├── LICENSE ├── quick_start_guide.txt └── RO └── ro_pair.v /README.md: -------------------------------------------------------------------------------- 1 | # LPN-based_PUF 2 | FPGA implementation of a cryptographically secure physical unclonable function based on learning parity with noise problem. 3 | -------------------------------------------------------------------------------- /system/tb.tcl: -------------------------------------------------------------------------------- 1 | # Copyright [2017] [Secure Computation Lab at UConn]. All rights reserved. 2 | # Use of this source code is governed by a MIT-style 3 | # license that can be found in the LICENSE file. 4 | # 5 | # Author: Chenglu Jin at 6 | # 7 | # This is the tcl file to automate ModelSim simulation. 8 | # To run: source tb.tcl 9 | 10 | quit -sim 11 | vlib work 12 | vlog *.v 13 | vsim system_tb 14 | view wave 15 | do wave.do 16 | run 60000ns 17 | -------------------------------------------------------------------------------- /SW/matrix.h: -------------------------------------------------------------------------------- 1 | // Copyright [2017] [Secure Computation Lab at UConn]. All rights reserved. 2 | // Use of this source code is governed by a MIT-style 3 | // license that can be found in the LICENSE file. 4 | // 5 | // Author: Chenglu Jin at 6 | // 7 | // This is the header file for matrix.c 8 | // 9 | #include 10 | #include 11 | #include 12 | 13 | void generate_random_matrix(int * , int); 14 | 15 | int find_inverse_matrix(int* , int* ); 16 | 17 | void matrix_multiplication(int * a, bool * b, bool *c); 18 | 19 | void xor_vector (bool * a, bool *b, bool* c, int size); 20 | 21 | void reorder_matrix (int* square_matrix); 22 | -------------------------------------------------------------------------------- /TRNG/ringosc.v: -------------------------------------------------------------------------------- 1 | //Taken from https://github.com/teknohog/rautanoppa 2 | 3 | module ringosc (clkout); 4 | output clkout; 5 | // p. 9 of http://www.xilinx.com/products/boards/s3estarter/files/s3esk_frequency_counter.pdf 6 | 7 | // Not necessarily an odd number, since there is only one invert anyway 8 | parameter NUMGATES = 3; 9 | 10 | (* keep="true" *) 11 | wire [NUMGATES-1:0] patch; 12 | 13 | generate 14 | genvar i; 15 | for (i = 0; i < NUMGATES-1; i = i + 1) 16 | begin: for_gates 17 | (* keep="true" *) 18 | assign patch[i+1] = ~patch[i]; 19 | end 20 | endgenerate 21 | 22 | (* keep="true" *) 23 | assign patch[0] = ~patch[NUMGATES-1]; 24 | 25 | // Plain output 26 | assign clkout = patch[0]; 27 | 28 | endmodule 29 | -------------------------------------------------------------------------------- /LPN_PUF_complete_test/tcl/my_xdc.xdc: -------------------------------------------------------------------------------- 1 | # Copyright [2017] [Secure Computation Lab at UConn]. All rights reserved. 2 | # Use of this source code is governed by a MIT-style 3 | # license that can be found in the LICENSE file. 4 | # 5 | # Author: Chenglu Jin at 6 | 7 | set_property PACKAGE_PIN F22 [get_ports {mode}]; # "SW0" 8 | set_property PACKAGE_PIN G22 [get_ports {global_start}]; # "SW1" 9 | set_property PACKAGE_PIN T21 [get_ports {check_result}]; # "LED1" 10 | set_property PACKAGE_PIN U22 [get_ports {hash_result}]; # "LED2" 11 | set_property iostandard LVCMOS15 [get_ports {mode}] 12 | set_property iostandard LVCMOS15 [get_ports {global_start}] 13 | set_property iostandard LVCMOS15 [get_ports {check_result}] 14 | set_property iostandard LVCMOS15 [get_ports {hash_result}] 15 | 16 | -------------------------------------------------------------------------------- /SW/lpn.h: -------------------------------------------------------------------------------- 1 | // Copyright [2017] [Secure Computation Lab at UConn]. All rights reserved. 2 | // Use of this source code is governed by a MIT-style 3 | // license that can be found in the LICENSE file. 4 | // 5 | // Author: Chenglu Jin at 6 | // 7 | // This is the header file for lpn.c 8 | // 9 | #include 10 | #include 11 | #include 12 | #include "matrix.h" 13 | #include "platform.h" 14 | 15 | #define DATA_CORRECT 0 16 | #define DATA_INCORRECT -1 17 | 18 | void convert_integer_to_bool (int* input_array, bool* output_array); 19 | 20 | int index_intersect (bool* index1, bool* index2, bool* output_index, int NUM_RO, int selected_ro); 21 | 22 | int skip_row_sel (bool* selected_index, bool* index_before_sel, int sel_num); 23 | 24 | void select_matrix(int* a, int * selected_matrix, bool* index, int num_selection, int num_ro); 25 | 26 | void convert_bool_to_integer (bool* input_array, int* output_array); 27 | 28 | void clean_index_gen (bool* index); 29 | -------------------------------------------------------------------------------- /TRNG/trng_wrapper.v: -------------------------------------------------------------------------------- 1 | // Copyright [2017] [Secure Computation Lab at UConn]. All rights reserved. 2 | // Use of this source code is governed by a MIT-style 3 | // license that can be found in the LICENSE file. 4 | // 5 | // Author: Chenglu Jin at 6 | // 7 | // This file contains the TRNG wrapper, which XORes 10 ring oscillator result 8 | // together and feeds into a 128-bit long FIFO. 9 | 10 | 11 | module trng_wrapper (clk, resetn, random_num); 12 | input clk; 13 | input resetn; 14 | output reg [127:0] random_num; 15 | 16 | parameter NUMRO_TRNG = 10; 17 | 18 | wire random_bit; 19 | wire [NUMRO_TRNG-1:0] ind_ro_output; 20 | 21 | always @ (posedge clk or negedge resetn) 22 | if (!resetn) 23 | random_num <= 128'h0; 24 | else 25 | random_num <= {random_num[126:0], random_bit}; 26 | 27 | 28 | generate 29 | genvar i; 30 | for (i = 0; i < NUMRO_TRNG; i = i + 1) 31 | begin: Ring_Osc 32 | ringosc RO (ind_ro_output[i]); 33 | end 34 | endgenerate 35 | 36 | assign random_bit = ^ind_ro_output; 37 | 38 | endmodule 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Secure Computation Laboratory 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /LPN_PUF_complete_test/lib/xilinx.com_user_tlast_gen_1.0/xgui/tlast_gen_v1_0.tcl: -------------------------------------------------------------------------------- 1 | # Definitional proc to organize widgets for parameters. 2 | proc init_gui { IPINST } { 3 | ipgui::add_param $IPINST -name "Component_Name" 4 | #Adding Page 5 | set Page_0 [ipgui::add_page $IPINST -name "Page 0"] 6 | ipgui::add_param $IPINST -name "MAX_PKT_LENGTH" -parent ${Page_0} 7 | ipgui::add_param $IPINST -name "TDATA_WIDTH" -parent ${Page_0} 8 | 9 | 10 | } 11 | 12 | proc update_PARAM_VALUE.MAX_PKT_LENGTH { PARAM_VALUE.MAX_PKT_LENGTH } { 13 | # Procedure called to update MAX_PKT_LENGTH when any of the dependent parameters in the arguments change 14 | } 15 | 16 | proc validate_PARAM_VALUE.MAX_PKT_LENGTH { PARAM_VALUE.MAX_PKT_LENGTH } { 17 | # Procedure called to validate MAX_PKT_LENGTH 18 | return true 19 | } 20 | 21 | proc update_PARAM_VALUE.TDATA_WIDTH { PARAM_VALUE.TDATA_WIDTH } { 22 | # Procedure called to update TDATA_WIDTH when any of the dependent parameters in the arguments change 23 | } 24 | 25 | proc validate_PARAM_VALUE.TDATA_WIDTH { PARAM_VALUE.TDATA_WIDTH } { 26 | # Procedure called to validate TDATA_WIDTH 27 | return true 28 | } 29 | 30 | 31 | proc update_MODELPARAM_VALUE.TDATA_WIDTH { MODELPARAM_VALUE.TDATA_WIDTH PARAM_VALUE.TDATA_WIDTH } { 32 | # Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value 33 | set_property value [get_property value ${PARAM_VALUE.TDATA_WIDTH}] ${MODELPARAM_VALUE.TDATA_WIDTH} 34 | } 35 | 36 | proc update_MODELPARAM_VALUE.MAX_PKT_LENGTH { MODELPARAM_VALUE.MAX_PKT_LENGTH PARAM_VALUE.MAX_PKT_LENGTH } { 37 | # Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value 38 | set_property value [get_property value ${PARAM_VALUE.MAX_PKT_LENGTH}] ${MODELPARAM_VALUE.MAX_PKT_LENGTH} 39 | } 40 | 41 | -------------------------------------------------------------------------------- /system/bit_sel_b.v: -------------------------------------------------------------------------------- 1 | // Copyright [2017] [Secure Computation Lab at UConn]. All rights reserved. 2 | // Use of this source code is governed by a MIT-style 3 | // license that can be found in the LICENSE file. 4 | // 5 | // Author: Chenglu Jin at 6 | // 7 | // This module selects 128 bits of b from a 450-bit vector of b according to 8 | // the selected index. 9 | 10 | module bit_sel_b (clk, resetn, en, load_index, load_b, b_w, index_w, selected_b, done); 11 | input clk; 12 | input resetn; 13 | input en; 14 | input load_index; 15 | input load_b; 16 | input [449:0] b_w; 17 | input [449:0] index_w; 18 | output reg [127:0] selected_b; 19 | output done; 20 | 21 | reg [449:0] index; 22 | reg [449:0] b; 23 | reg [8:0] cnt; 24 | 25 | always @ (posedge clk or negedge resetn) 26 | if (!resetn) 27 | selected_b <= 128'b0; 28 | else if (en == 1 && index[449] == 1'b1 && done == 0) 29 | selected_b <= {selected_b[126:0], b[449]}; 30 | else 31 | selected_b <= selected_b; 32 | 33 | always @ (posedge clk or negedge resetn) 34 | if (!resetn) 35 | index <= 450'b0; 36 | else if (load_index == 1'b1) 37 | index <= index_w; 38 | else if (en) 39 | index <= {index[448:0],1'b0}; 40 | else 41 | index <= index; 42 | 43 | always @ (posedge clk or negedge resetn) 44 | if (!resetn) 45 | b <= 450'b0; 46 | else if (load_b == 1'b1) 47 | b <= b_w; 48 | else if (en == 1) 49 | b <= {b[448:0],1'b0}; 50 | else 51 | b <= b; 52 | 53 | always @ (posedge clk or negedge resetn) 54 | if (!resetn) 55 | cnt <= 9'b0; 56 | else if (load_b == 1'b1) 57 | cnt <= 9'b0; 58 | else if (en == 1 && index[449] == 1'b1 && cnt < 9'd128) 59 | cnt <= cnt + 1; 60 | else 61 | cnt <= cnt; 62 | 63 | assign done = (cnt == 9'd128) ? 1'b1 : 1'b0; 64 | 65 | endmodule 66 | 67 | -------------------------------------------------------------------------------- /quick_start_guide.txt: -------------------------------------------------------------------------------- 1 | // Copyright [2017] [Secure Computation Lab at UConn]. All rights reserved. 2 | // Use of this source code is governed by a MIT-style 3 | // license that can be found in the LICENSE file. 4 | // 5 | // Author: Chenglu Jin at 6 | 7 | In this directory, there are four folders. 8 | 9 | -- RO 10 | ------ This folder contains the design of 450 ring oscillator pairs. 11 | 12 | -- TRNG 13 | ------ This folder contains the design of a multiple RO TRNG. 14 | 15 | -- system 16 | ------ This folder has the hardware LPN-core 17 | 18 | -- LPN_PUF_complete_test 19 | ------ Open Vivado, enter tcl directory, enter command "source 20 | dma_ex_interrupt.tcl" in the console. The project will be created and built. 21 | 22 | -- SW 23 | ------ It contains all the software code. 24 | 25 | How to use this? 26 | 1. Package ro_pair.v as one IP core for ZedBoard. 27 | 2. Package all the Verilog files in TRNG folder as one IP core for ZedBoard. 28 | 3. Package all the Verilog files in system folder as one IP core for ZedBoard. 29 | 4. Change the directory of these three IP cores in \LPN_PUF_complete_test\tcl\bd_zedboard.tcl (Search the keyword "Notice") 30 | 5. Update your pin selection in \LPN_PUF_complete_test\tcl\my_xdc.xdc. Notice 31 | that currently switch 0 on ZedBoard is used for selecting the mode Gen (0) or 32 | Ver (1). Switch 1 is used to start the hardware to run. 33 | 6. Open Vivado, enter the tcl folder. Run "source dma_ex_interrupt.tcl" 34 | 7. After this, you will have a post implementation design. Open SDK, import 35 | the hardware design. 36 | 8. Create a new SW project in SDK, and import all the code in SW to your 37 | project. 38 | 9. Set the heap/stack size to 64MB. 39 | 10. Compile the code and program the FPGA. 40 | 11. See the output from a UART terminal with Baud rate 115200. Do not forget 41 | to push switch 0 to select mode, and push switch 1 to start one Gen/Ver 42 | operation. 43 | 44 | -------------------------------------------------------------------------------- /system/bit_sel.v: -------------------------------------------------------------------------------- 1 | // Copyright [2017] [Secure Computation Lab at UConn]. All rights reserved. 2 | // Use of this source code is governed by a MIT-style 3 | // license that can be found in the LICENSE file. 4 | // 5 | // Author: Chenglu Jin at 6 | // 7 | // This module selects 128 or 256 valid bits of e vector from 450 bits. 8 | // The input number_select controls it to select 128 or 256 bits. 9 | 10 | module bit_sel (clk, resetn, en, number_select, start, e_w, index_w, selected_e, done); 11 | input clk; 12 | input resetn; 13 | input en; 14 | input [8:0] number_select; 15 | input start; 16 | input [449:0] e_w; 17 | input [449:0] index_w; 18 | output reg [255:0] selected_e; 19 | output done; 20 | 21 | reg [449:0] index; 22 | reg [449:0] e; 23 | reg [8:0] cnt; 24 | 25 | always @ (posedge clk or negedge resetn) 26 | if (!resetn) 27 | selected_e <= 256'b0; 28 | else if (en == 1 && index[449] == 1'b1 && done == 0) 29 | selected_e <= {selected_e[254:0], e[449]}; 30 | else 31 | selected_e <= selected_e; 32 | 33 | always @ (posedge clk or negedge resetn) 34 | if (!resetn) 35 | index <= 450'b0; 36 | else if (start == 1'b1) 37 | index <= index_w; 38 | else if (en) 39 | index <= {index[448:0],1'b0}; 40 | else 41 | index <= index; 42 | 43 | always @ (posedge clk or negedge resetn) 44 | if (!resetn) 45 | e <= 450'b0; 46 | else if (start == 1'b1) 47 | e <= e_w; 48 | else if (en == 1) 49 | e <= {e[448:0],1'b0}; 50 | else 51 | e <= e; 52 | 53 | always @ (posedge clk or negedge resetn) 54 | if (!resetn) 55 | cnt <= 9'b0; 56 | else if (start == 1'b1) 57 | cnt <= 9'b0; 58 | else if (en == 1 && index[449] == 1'b1 && cnt < number_select) 59 | cnt <= cnt + 1; 60 | else 61 | cnt <= cnt; 62 | 63 | assign done = (cnt == number_select) ? 1'b1 : 1'b0; 64 | 65 | endmodule 66 | 67 | -------------------------------------------------------------------------------- /LPN_PUF_complete_test/lib/xilinx.com_user_tlast_gen_1.0/tlast_gen.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | ////////////////////////////////////////////////////////////////////////////////// 3 | // Company: Xilinx 4 | // Engineer: bwiec 5 | // Create Date: Mon Jun 05 07:43:03 MDT 2015 6 | // Design Name: dma_controller 7 | // Module Name: tlast_gen 8 | // Project Name: DMA Controller 9 | // Target Devices: All 10 | // Tool Versions: 2015.1 11 | // Description: Generate tlast based on configured packet length 12 | // 13 | // Dependencies: None 14 | // 15 | // Revision: 16 | // - Rev 0.20 - Behavior verified in hardware testcase 17 | // - Rev 0.10 - Behavior verified in behavioral simulation 18 | // - Rev 0.01 - File created 19 | // 20 | // Known Issues: 21 | // - Rev 0.20 - None 22 | // - Rev 0.10 - None 23 | // - Rev 0.01 - None 24 | // 25 | // Additional Comments: 26 | // 27 | ////////////////////////////////////////////////////////////////////////////////// 28 | 29 | module tlast_gen 30 | #( 31 | parameter TDATA_WIDTH = 8, 32 | parameter MAX_PKT_LENGTH = 256 33 | ) 34 | ( 35 | // Clocks and resets 36 | input aclk, 37 | input resetn, 38 | 39 | // Control signals 40 | input [$clog2(MAX_PKT_LENGTH):0] pkt_length, 41 | 42 | // Slave interface 43 | input s_axis_tvalid, 44 | output s_axis_tready, 45 | input [TDATA_WIDTH-1:0] s_axis_tdata, 46 | 47 | // Master interface 48 | output m_axis_tvalid, 49 | input m_axis_tready, 50 | output m_axis_tlast, 51 | output [TDATA_WIDTH-1:0] m_axis_tdata 52 | ); 53 | 54 | // Internal signals 55 | wire new_sample; 56 | reg [$clog2(MAX_PKT_LENGTH):0] cnt = 0; 57 | 58 | // Pass through control signals 59 | assign s_axis_tready = m_axis_tready; 60 | assign m_axis_tvalid = s_axis_tvalid; 61 | assign m_axis_tdata = s_axis_tdata; 62 | 63 | // Count samples 64 | assign new_sample = s_axis_tvalid & s_axis_tready; 65 | always @ (posedge aclk) begin 66 | if (~resetn | (m_axis_tlast & new_sample)) 67 | cnt <= 0; 68 | else 69 | if (new_sample) 70 | cnt <= cnt + 1'b1; 71 | end 72 | 73 | // Generate tlast 74 | assign m_axis_tlast = (cnt == pkt_length-1); 75 | 76 | endmodule 77 | 78 | -------------------------------------------------------------------------------- /system/sha2.v: -------------------------------------------------------------------------------- 1 | // Taken from https://github.com/russm/sha2-verilog with some modifications. 2 | // 3 | // generalised round compression function 4 | module sha2_round #( 5 | parameter WORDSIZE=0 6 | ) ( 7 | input [WORDSIZE-1:0] Kj, Wj, 8 | input [WORDSIZE-1:0] a_in, b_in, c_in, d_in, e_in, f_in, g_in, h_in, 9 | input [WORDSIZE-1:0] Ch_e_f_g, Maj_a_b_c, S0_a, S1_e, 10 | output [WORDSIZE-1:0] a_out, b_out, c_out, d_out, e_out, f_out, g_out, h_out 11 | ); 12 | 13 | wire [WORDSIZE-1:0] T1 = h_in + S1_e + Ch_e_f_g + Kj + Wj; 14 | wire [WORDSIZE-1:0] T2 = S0_a + Maj_a_b_c; 15 | 16 | assign a_out = T1 + T2; 17 | assign b_out = a_in; 18 | assign c_out = b_in; 19 | assign d_out = c_in; 20 | assign e_out = d_in + T1; 21 | assign f_out = e_in; 22 | assign g_out = f_in; 23 | assign h_out = g_in; 24 | 25 | endmodule 26 | 27 | 28 | // Ch(x,y,z) 29 | module Ch #(parameter WORDSIZE=0) ( 30 | input wire [WORDSIZE-1:0] x, y, z, 31 | output wire [WORDSIZE-1:0] Ch 32 | ); 33 | 34 | assign Ch = ((x & y) ^ (~x & z)); 35 | 36 | endmodule 37 | 38 | 39 | // Maj(x,y,z) 40 | module Maj #(parameter WORDSIZE=0) ( 41 | input wire [WORDSIZE-1:0] x, y, z, 42 | output wire [WORDSIZE-1:0] Maj 43 | ); 44 | 45 | assign Maj = (x & y) ^ (x & z) ^ (y & z); 46 | 47 | endmodule 48 | 49 | 50 | // the message schedule: a machine that generates Wt values 51 | module W_machine #(parameter WORDSIZE=1) ( 52 | input clk, 53 | input en, 54 | input [WORDSIZE*16-1:0] M, 55 | input M_valid, 56 | output [WORDSIZE-1:0] W_tm2, W_tm15, 57 | input [WORDSIZE-1:0] s1_Wtm2, s0_Wtm15, 58 | output [WORDSIZE-1:0] W 59 | ); 60 | 61 | reg [WORDSIZE*16-1:0] W_stack_q; 62 | // W(t-n) values, from the perspective of Wt_next 63 | assign W_tm2 = W_stack_q[WORDSIZE*2-1:WORDSIZE*1]; 64 | assign W_tm15 = W_stack_q[WORDSIZE*15-1:WORDSIZE*14]; 65 | wire [WORDSIZE-1:0] W_tm7 = W_stack_q[WORDSIZE*7-1:WORDSIZE*6]; 66 | wire [WORDSIZE-1:0] W_tm16 = W_stack_q[WORDSIZE*16-1:WORDSIZE*15]; 67 | // Wt_next is the next Wt to be pushed to the queue, will be consumed in 16 rounds 68 | wire [WORDSIZE-1:0] Wt_next = s1_Wtm2 + W_tm7 + s0_Wtm15 + W_tm16; 69 | 70 | wire [WORDSIZE*16-1:0] W_stack_d = {W_stack_q[WORDSIZE*15-1:0], Wt_next}; 71 | assign W = W_stack_q[WORDSIZE*16-1:WORDSIZE*15]; 72 | 73 | always @(posedge clk) 74 | begin 75 | if (en == 0) 76 | W_stack_q <= W_stack_q; 77 | else if (M_valid) begin 78 | W_stack_q <= M; 79 | end else begin 80 | W_stack_q <= W_stack_d; 81 | end 82 | end 83 | 84 | endmodule 85 | -------------------------------------------------------------------------------- /system/bit_expand.v: -------------------------------------------------------------------------------- 1 | // Copyright [2017] [Secure Computation Lab at UConn]. All rights reserved. 2 | // Use of this source code is governed by a MIT-style 3 | // license that can be found in the LICENSE file. 4 | // 5 | // Author: Chenglu Jin at 6 | // 7 | // This module expands a 256-bit B_{I} vector to a 450-bit B vector according 8 | // to the selected index. 9 | 10 | module bit_expand (clk, resetn, en, index_valid, index, read_short_b, short_b, expanded_b, done); 11 | 12 | input clk; 13 | input resetn; 14 | input en; 15 | input index_valid; 16 | input [449:0] index; 17 | input read_short_b; 18 | input [127:0] short_b; 19 | output [449:0] expanded_b; 20 | output done; 21 | 22 | reg [449:0] expanded_b; 23 | reg [255:0] short_b_reg; 24 | reg [449:0] index_reg; 25 | reg [9:0] cnt; 26 | reg done; 27 | reg flip; 28 | 29 | always @ (posedge clk or negedge resetn) 30 | if (!resetn) 31 | flip <= 1'b0; 32 | else if (read_short_b) 33 | flip <= ~flip; 34 | else 35 | flip <= flip; 36 | 37 | always @ (posedge clk or negedge resetn) 38 | if (!resetn) 39 | short_b_reg <= 256'h0; 40 | else if (read_short_b == 1 && flip == 1'b0) 41 | short_b_reg <= {short_b, short_b_reg[127:0]}; 42 | else if (read_short_b == 1 && flip == 1'b1) 43 | short_b_reg <= {short_b_reg[255:128], short_b}; 44 | else if (en == 1 && index_reg[449] == 1 && cnt < 10'd450 && read_short_b == 0) 45 | short_b_reg <= {short_b_reg[254:0], 1'b0}; 46 | else 47 | short_b_reg <= short_b_reg; 48 | 49 | always @ (posedge clk or negedge resetn) 50 | if (!resetn) 51 | index_reg <= 450'h0; 52 | else if (index_valid) 53 | index_reg <= index; 54 | else if (en && cnt < 10'd450 && read_short_b == 0) 55 | index_reg <= {index_reg[448:0], 1'b0}; 56 | else 57 | index_reg <= index_reg; 58 | 59 | always @ (posedge clk or negedge resetn) 60 | if (!resetn) 61 | expanded_b <= 450'h0; 62 | else if (en && index_reg[449] == 1'b1 && cnt < 10'd450 && read_short_b == 0) 63 | expanded_b <= {expanded_b[448:0], short_b_reg[255]}; 64 | else if (en && index_reg[449] == 1'b0 && cnt < 10'd450 && read_short_b == 0) 65 | expanded_b <= {expanded_b[448:0], 1'b0}; 66 | else 67 | expanded_b <= expanded_b; 68 | 69 | always @ (posedge clk or negedge resetn) 70 | if (!resetn) 71 | cnt <= 10'h0; 72 | else if (index_valid) 73 | cnt <= 10'h0; 74 | else if (en && cnt < 10'd450 && read_short_b == 0) 75 | cnt <= cnt + 1'b1; 76 | else 77 | cnt <= cnt; 78 | 79 | always @ (posedge clk or negedge resetn) 80 | if (!resetn) 81 | done <= 1'b0; 82 | else if (index_valid == 1) 83 | done <= 1'b0; 84 | else if (cnt == 10'd450) 85 | done <= 1'b1; 86 | else 87 | done <= done; 88 | endmodule 89 | -------------------------------------------------------------------------------- /SW/matrix.c: -------------------------------------------------------------------------------- 1 | // Copyright [2017] [Secure Computation Lab at UConn]. All rights reserved. 2 | // Use of this source code is governed by a MIT-style 3 | // license that can be found in the LICENSE file. 4 | // 5 | // Author: Chenglu Jin at 6 | // 7 | // This file contains some functions that are required for matrix operations. 8 | // 9 | #include "matrix.h" 10 | 11 | #define DATA_CORRECT 0 12 | #define DATA_INCORRECT -1 13 | 14 | void reorder_matrix (int* square_matrix) 15 | { 16 | int i, j; 17 | int temp; 18 | for (i = 0; i < 128; i++) 19 | { 20 | for (j = 0; j < 2; j++) 21 | { 22 | temp = square_matrix[4*i+j]; 23 | square_matrix[4*i+j] = square_matrix[4*i+3-j]; 24 | square_matrix[4*i+3-j] = temp; 25 | } 26 | } 27 | } 28 | 29 | void generate_random_matrix(int * a, int matrix_size) { 30 | int temp1, temp2, temp3, temp4; 31 | int i; 32 | 33 | for (i = 0; i < matrix_size; i++) { 34 | temp1 = rand() % 256; 35 | temp2 = rand() % 256; 36 | temp3 = rand() % 256; 37 | temp4 = rand() % 256; 38 | a[i] = (temp1 << 24) ^ (temp2 << 16) ^ (temp3 << 8) ^ temp4; 39 | } 40 | } 41 | 42 | void xor_row(int * a, int* b) //a = a ^ b 43 | { 44 | int i; 45 | for (i = 0; i < 4; i++) { 46 | a[i] = a[i] ^ b[i]; 47 | } 48 | } 49 | 50 | void swap_row(int* a, int*b) // a = b; b = a 51 | { 52 | int i; 53 | int temp; 54 | for (i = 0; i < 4; i++) { 55 | temp = a[i]; 56 | a[i] = b[i]; 57 | b[i] = temp; 58 | } 59 | } 60 | 61 | int find_inverse_matrix(int* a, int* result_matrix) { 62 | //Create a new matrix based on the selected index 63 | int i, j, flag, k; 64 | 65 | //create an identity matrix 66 | //clear it 67 | for (i = 0; i < 512; i++) { 68 | result_matrix[i] = 0; 69 | } 70 | //add elements 71 | for (j = 0; j < 128; j++) { 72 | i = (j / 32) + j * 4; 73 | result_matrix[i] = (0x80000000 >> (j % 32)); 74 | } 75 | 76 | for (j = 0; j < 128; j++) { 77 | i = (j / 32) + j* 4; 78 | if ((a[i] & (0x80000000 >> (j % 32))) != 0) { 79 | for (k = (i % 4); k < 512; k = k + 4) { 80 | if (((a[k] & (0x80000000 >> (j % 32))) != 0) 81 | && (k != i)) { 82 | xor_row(&a[(k / 4) * 4], &a[(i / 4) * 4]); 83 | xor_row(&result_matrix[(k / 4) * 4], 84 | &result_matrix[(i / 4) * 4]); 85 | } 86 | } 87 | } else { 88 | flag = 1; 89 | for (k = i ; k < 512; k = k + 4) { 90 | if ((a[k] & (0x80000000 >> (j % 32))) != 0) { 91 | flag = 0; 92 | swap_row(&a[(k / 4) * 4], 93 | &a[(i / 4) * 4]); 94 | swap_row(&result_matrix[(k / 4) * 4], 95 | &result_matrix[(i / 4) * 4]); 96 | break; 97 | } 98 | } 99 | if (flag == 1) { 100 | return DATA_INCORRECT; 101 | } 102 | for (k = (i % 4); k < 512; k = k + 4) { 103 | if (((a[k] & (0x80000000 >> (j % 32))) != 0) 104 | && (k != i)) { 105 | xor_row(&a[(k / 4) * 4], &a[(i / 4) * 4]); 106 | xor_row(&result_matrix[(k / 4) * 4], 107 | &result_matrix[(i / 4) * 4]); 108 | } 109 | } 110 | } 111 | } 112 | return DATA_CORRECT; 113 | } 114 | -------------------------------------------------------------------------------- /LPN_PUF_complete_test/tcl/dma_ex_interrupt.tcl: -------------------------------------------------------------------------------- 1 | #----------------------------------------------------------- 2 | # dma_ex_interrupt.tcl 3 | #----------------------------------------------------------- 4 | 5 | #----------------------------------------------------------- 6 | # User-editable parameters 7 | #----------------------------------------------------------- 8 | # target_board can be: zedboard, zc702 9 | #set target_board zc702 10 | set target_board zedboard 11 | 12 | #----------------------------------------------------------- 13 | # Constant parameters 14 | #----------------------------------------------------------- 15 | set proj_name dma_ex_interrupt 16 | set design_ver v0_1 17 | set underscore _ 18 | set design_name_full "$proj_name$underscore$design_ver" 19 | puts "NOTE: This file must be executed from the project's 'tcl' directory" 20 | puts "NOTE: Generating design targeting $target_board. You can change the target_board variable in $proj_name.tcl to target another board." 21 | 22 | #----------------------------------------------------------- 23 | # Archive existing design if it already exists 24 | #----------------------------------------------------------- 25 | puts "NOTE: Archive existing $design_name_full design if it exists" 26 | set format_date [clock format [clock seconds] -format %Y%m%d_%H%m] 27 | set date_suffix $underscore$format_date 28 | if { [file exists "../proj/$design_name_full"] == 1 } { 29 | puts "Moving existing $design_name_full to time-stamped suffix $design_name_full$date_suffix" 30 | file rename "../proj/$design_name_full" "../proj/$design_name_full$date_suffix" 31 | } else { 32 | file mkdir ../proj 33 | } 34 | 35 | #----------------------------------------------------------- 36 | # Create project 37 | #----------------------------------------------------------- 38 | puts "Creating project for $design_name_full..." 39 | if { $target_board == "zedboard" } { 40 | set target_part xc7z020clg484-1 41 | set board_property em.avnet.com:zed:part0:1.3 42 | } elseif { $target_board == "zc702" } { 43 | set target_part xc7z020clg484-1 44 | set board_property xilinx.com:zc702:part0:1.2 45 | } else { 46 | puts "ERROR! Selected board is not supported." 47 | exit 48 | } 49 | create_project $design_name_full "../proj/$design_name_full" -part $target_part 50 | set_property board $board_property [current_project] 51 | 52 | #----------------------------------------------------------- 53 | # Add HDL IP repositories 54 | #----------------------------------------------------------- 55 | set_property ip_repo_paths "../lib" [current_fileset] 56 | update_ip_catalog -rebuild 57 | 58 | #----------------------------------------------------------- 59 | # Create BD source 60 | #----------------------------------------------------------- 61 | puts "Creating block diagram..." 62 | source "./bd_$target_board.tcl" 63 | make_wrapper -files [get_files "../proj/$design_name_full/$design_name_full.srcs/sources_1/bd/design_1/design_1.bd"] -top 64 | import_files -force -norecurse "../proj/$design_name_full/$design_name_full.srcs/sources_1/bd/design_1/hdl/design_1_wrapper.v" 65 | 66 | #----------------------------------------------------------- 67 | # Generate bitstream 68 | #----------------------------------------------------------- 69 | launch_runs impl_1 -to_step write_bitstream 70 | wait_on_run impl_1 71 | 72 | #----------------------------------------------------------- 73 | # Export hardware for SDK 74 | #----------------------------------------------------------- 75 | file mkdir "../proj/$design_name_full/$design_name_full.sdk" 76 | file copy -force "../proj/$design_name_full/$design_name_full.runs/impl_1/design_1_wrapper.sysdef" "../proj/$design_name_full/$design_name_full.sdk/design_1_wrapper.hdf" 77 | 78 | -------------------------------------------------------------------------------- /SW/dac.c: -------------------------------------------------------------------------------- 1 | 2 | // Includes 3 | #include 4 | #include "dac.h" 5 | #include "xgpio.h" 6 | #include "dma_passthrough.h" 7 | 8 | // Private data 9 | typedef struct dac_periphs 10 | { 11 | dma_passthrough_t* p_dma_passthrough_inst; 12 | XGpio gpio_inst; 13 | } dac_periphs_t; 14 | 15 | // Object definition 16 | typedef struct dac 17 | { 18 | dac_periphs_t periphs; 19 | int samples_per_frame; 20 | int bytes_per_sample; 21 | } dac_t; 22 | 23 | // Private functions 24 | static int init_gpio(XGpio* p_gpio_inst, int gpio_device_id) 25 | { 26 | 27 | // Local variables 28 | int status = 0; 29 | 30 | // Initialize driver 31 | status = XGpio_Initialize(p_gpio_inst, gpio_device_id); 32 | if (status != XST_SUCCESS) 33 | { 34 | xil_printf("ERROR! Initialization of AXI GPIO instance failed.\n\r"); 35 | return DAC_GPIO_INIT_FAIL; 36 | } 37 | 38 | // Set value to 0 in case set some other way by previous run 39 | XGpio_DiscreteWrite(p_gpio_inst, 1, 0); 40 | 41 | return DAC_SUCCESS; 42 | 43 | } 44 | 45 | // Public functions 46 | dac_t* dac_create(int gpio_device_id, int dma_device_id, int intc_device_id, int s2mm_intr_id, 47 | int mm2s_intr_id, int bytes_per_sample) 48 | { 49 | // Local variables 50 | int status; 51 | dac_t* p_obj; 52 | 53 | // Allocate memory for DAC object 54 | p_obj = (dac_t*) malloc(sizeof(dac_t)); 55 | if (p_obj == NULL) 56 | { 57 | xil_printf("ERROR! Failed to allocate memory for DAC object.\n\r"); 58 | return NULL; 59 | } 60 | 61 | // Create DMA Passthrough object to be used by the DAC 62 | p_obj->periphs.p_dma_passthrough_inst = dma_passthrough_create 63 | ( 64 | dma_device_id, 65 | intc_device_id, 66 | s2mm_intr_id, 67 | mm2s_intr_id, 68 | bytes_per_sample 69 | ); 70 | if (p_obj->periphs.p_dma_passthrough_inst == NULL) 71 | { 72 | xil_printf("ERROR! Failed to create DMA Passthrough object for use by the DAC.\n\r"); 73 | return NULL; 74 | } 75 | 76 | // Register and initialize peripherals 77 | status = init_gpio(&p_obj->periphs.gpio_inst, gpio_device_id); 78 | if (status != XST_SUCCESS) 79 | { 80 | xil_printf("ERROR! Failed to initialize GPIO.\n\r"); 81 | dac_destroy(p_obj); 82 | return NULL; 83 | } 84 | 85 | // Initialize DAC parameters 86 | dac_set_samples_per_frame(p_obj, 1024); 87 | dac_set_bytes_per_sample(p_obj, bytes_per_sample); 88 | 89 | return p_obj; 90 | } 91 | 92 | void dac_destroy(dac_t* p_dac_inst) 93 | { 94 | dma_passthrough_destroy(p_dac_inst->periphs.p_dma_passthrough_inst); 95 | free(p_dac_inst); 96 | } 97 | 98 | void dac_set_samples_per_frame(dac_t* p_dac_inst, int samples_per_frame) 99 | { 100 | p_dac_inst->samples_per_frame = samples_per_frame; 101 | dma_passthrough_set_buf_length(p_dac_inst->periphs.p_dma_passthrough_inst, samples_per_frame); 102 | } 103 | 104 | int dac_get_samples_per_frame(dac_t* p_dac_inst) 105 | { 106 | return (p_dac_inst->samples_per_frame); 107 | } 108 | 109 | void dac_set_bytes_per_sample(dac_t* p_dac_inst, int bytes_per_sample) 110 | { 111 | p_dac_inst->bytes_per_sample = bytes_per_sample; 112 | dma_passthrough_set_sample_size_bytes(p_dac_inst->periphs.p_dma_passthrough_inst, bytes_per_sample); 113 | } 114 | 115 | int dac_get_bytes_per_sample(dac_t* p_dac_inst) 116 | { 117 | return (p_dac_inst->bytes_per_sample); 118 | } 119 | 120 | void dac_enable(dac_t* p_dac_inst) 121 | // The implementation of this function is specific to this hardware where a GPIO 122 | // is used to emulate a data source. This function would obviously be implemented 123 | // completely differently if there were an actual DAC in the system. 124 | { 125 | // For the purposes of this demo, nothing to be done here. 126 | } 127 | 128 | int dac_send_frame(dac_t* p_dac_inst, void* buf) 129 | { 130 | // Local variables 131 | int status; 132 | 133 | dma_passthrough_set_snd_buf(p_dac_inst->periphs.p_dma_passthrough_inst, buf); 134 | status = dma_passthrough_snd(p_dac_inst->periphs.p_dma_passthrough_inst); 135 | if (status != DMA_PASSTHROUGH_SUCCESS) 136 | { 137 | xil_printf("ERROR! DMA Passthrough error occurred when trying to send data.\n\r"); 138 | return DAC_DMA_FAIL; 139 | } 140 | 141 | return DAC_SUCCESS; 142 | 143 | } 144 | 145 | -------------------------------------------------------------------------------- /SW/dac.h: -------------------------------------------------------------------------------- 1 | 2 | ////////////////////////////////////////////////////////////////////////////////// 3 | // 4 | // Company: Xilinx 5 | // Engineer: bwiec 6 | // Create Date: 29 June 2015, 11:37:03 AM 7 | // Library Name: Digital to Analog Converter 8 | // File Name: dac.h 9 | // Target Devices: Zynq 10 | // Tool Versions: 2015.1 11 | // Description: Middleware API for a DAC using the AXI DMA. 12 | // Dependencies: 13 | // - dma_passthrough.h - Driver version v1.0 14 | // Revision History: 15 | // - v1.0 16 | // * Initial release 17 | // * Tested on ZC702 and Zedboard 18 | // Additional Comments: 19 | // - This library is intended to be used as a layer between the base xaxidma 20 | // driver and application software. The programming model is a frame-based 21 | // DAC driver that sends a new buffer of data (via DMA) when dac_send_frame() 22 | // is called. 23 | // - Data buffer must be contiguous. Scatter gather is not supported. 24 | // 25 | ////////////////////////////////////////////////////////////////////////////////// 26 | 27 | #ifndef DAC_H_ 28 | #define DAC_H_ 29 | 30 | // Return types 31 | #define DAC_SUCCESS 0 32 | #define DAC_GPIO_INIT_FAIL -1 33 | #define DAC_DMA_FAIL -2 34 | 35 | // Object forward declaration 36 | typedef struct dac dac_t; 37 | 38 | // Public functions 39 | 40 | // 41 | // dac_create - Create a DAC object. 42 | // 43 | // Arguments 44 | // - gpio_device_id: Device ID of the GPIO instance to use. 45 | // - dma_device_id: Device ID of the DMA instance to use. 46 | // - intc_device_id: Device ID of the Interrupt Controller instance to use. 47 | // - s2mm_intr_id: Interrupt ID for the AXI DMA S2MM channel. 48 | // - mm2s_intr_id: Interrupt ID for the AXI DMA MM2S channel. 49 | // - bytes_per_sample: Number of bytes per sample (i.e. tdata width). 50 | // 51 | // Return 52 | // - dac_t*: Non-NULL pointer to dac_t object on success. 53 | // - NULL: NULL if something failed. 54 | dac_t* dac_create(int gpio_device_id, int dma_device_id, int intc_device_id, int s2mm_intr_id, 55 | int mm2s_intr_id, int bytes_per_sample); 56 | 57 | // 58 | // dac_destroy - Destroy DAC object. 59 | // 60 | // Arguments 61 | // - p_dac_inst: Pointer to dac_t object to be deallocated. 62 | // 63 | void dac_destroy(dac_t* p_dac_inst); 64 | 65 | // 66 | // dac_set_samples_per_frame - Set the number of samples per frame of data to the DAC. 67 | // 68 | // Arguments 69 | // - p_dac_inst: Pointer to dac_t object. 70 | // - samples_per_frame: Number of samples per frame of data to the DAC. 71 | // 72 | void dac_set_samples_per_frame(dac_t* p_dac_inst, int samples_per_frame); 73 | 74 | // 75 | // dac_get_samples_per_frame - Get the number of samples per frame of data to the DAC. 76 | // 77 | // Arguments 78 | // - p_dac_inst: Pointer to dac_t object. 79 | // 80 | // Return 81 | // - int: Number of samples per frame of data to the DAC. 82 | // 83 | int dac_get_samples_per_frame(dac_t* p_dac_inst); 84 | 85 | // 86 | // dac_set_bytes_per_sample - Set the number of bytes per sample in the data to the 87 | // DAC (i.e. tdata width). 88 | // 89 | // Arguments 90 | // - p_dac_inst: Pointer to dac_t object. 91 | // - samples_per_frame: Number of bytes per sample in the data to the DAC (i.e. 92 | // tdata width). 93 | // 94 | void dac_set_bytes_per_sample(dac_t* p_dac_inst, int bytes_per_sample); 95 | 96 | // 97 | // dac_get_bytes_per_sample - Get the number of bytes per sample in the data to the 98 | // DAC (i.e. tdata width). 99 | // 100 | // Arguments 101 | // - p_dac_inst: Pointer to dac_t object. 102 | // 103 | // Return 104 | // - int: Number of bytes per sample in the data to the DAC (i.e. tdata 105 | // width). 106 | // 107 | int dac_get_bytes_per_sample(dac_t* p_dac_inst); 108 | 109 | // 110 | // dac_enable - Enable the DAC to start streaming samples. 111 | // 112 | // Arguments 113 | // - p_dac_inst: Pointer to the dac_t object. 114 | // 115 | void dac_enable(dac_t* p_dac_inst); 116 | 117 | // 118 | // dac_send_frame - Send the next frame of data to the DAC. 119 | // 120 | // Arguments 121 | // - p_dac_inst: Pointer to the dac_t object. 122 | // - buf: Buffer containing the next frame of data to the DAC. 123 | // 124 | int dac_send_frame(dac_t* p_dac_inst, void* buf); 125 | 126 | #endif /* DAC_H_ */ 127 | 128 | -------------------------------------------------------------------------------- /SW/adc.h: -------------------------------------------------------------------------------- 1 | 2 | ////////////////////////////////////////////////////////////////////////////////// 3 | // 4 | // Company: Xilinx 5 | // Engineer: bwiec 6 | // Create Date: 29 June 2015, 11:37:03 AM 7 | // Library Name: Analog to Digital Converter 8 | // File Name: adc.h 9 | // Target Devices: Zynq 10 | // Tool Versions: 2015.1 11 | // Description: Middleware API for an ADC using the AXI DMA. 12 | // Dependencies: 13 | // - dma_passthrough.h - Driver version v1.0 14 | // Revision History: 15 | // - v1.0 16 | // * Initial release 17 | // * Tested on ZC702 and Zedboard 18 | // Additional Comments: 19 | // - This library is intended to be used as a layer between the base xaxidma 20 | // driver and application software. The programming model is a frame-based 21 | // ADC driver that accepts a new buffer of data (via DMA) when adc_get_frame() 22 | // is called. 23 | // - Data buffer must be contiguous. Scatter gather is not supported. 24 | // 25 | ////////////////////////////////////////////////////////////////////////////////// 26 | 27 | #ifndef ADC_H_ 28 | #define ADC_H_ 29 | 30 | // Return types 31 | #define ADC_SUCCESS 0 32 | #define ADC_GPIO_INIT_FAIL -1 33 | #define ADC_DMA_FAIL -2 34 | 35 | // Object forward declaration 36 | typedef struct adc adc_t; 37 | 38 | // Public functions 39 | 40 | // 41 | // adc_create - Create an ADC object. 42 | // 43 | // Arguments 44 | // - gpio_device_id: Device ID of the GPIO instance to use. 45 | // - dma_device_id: Device ID of the DMA instance to use. 46 | // - intc_device_id: Device ID of the Interrupt Controller instance to use. 47 | // - s2mm_intr_id: Interrupt ID for the AXI DMA S2MM channel. 48 | // - mm2s_intr_id: Interrupt ID for the AXI DMA MM2S channel. 49 | // - bytes_per_sample: Number of bytes per sample (i.e. tdata width). 50 | // 51 | // Return 52 | // - adc_t*: Non-NULL pointer to adc_t object on success. 53 | // - NULL: NULL if something failed. 54 | // 55 | adc_t* adc_create(int gpio_device_id, int dma_device_id, int intc_device_id, int s2mm_intr_id, 56 | int mm2s_intr_id, int bytes_per_sample); 57 | 58 | // 59 | // adc_destroy - Destroy ADC object. 60 | // 61 | // Arguments 62 | // - p_adc_inst: Pointer to adc_t object to be deallocated. 63 | // 64 | void adc_destroy(adc_t* p_adc_inst); 65 | 66 | // 67 | // adc_set_samples_per_frame - Set the number of samples per frame of data from the ADC. 68 | // 69 | // Arguments 70 | // - p_adc_inst: Pointer to adc_t object. 71 | // - samples_per_frame: Number of samples per frame of data from the ADC. 72 | // 73 | void adc_set_samples_per_frame(adc_t* p_adc_inst, int samples_per_frame); 74 | 75 | // 76 | // adc_get_samples_per_frame - Get the number of samples per frame of data from the ADC. 77 | // 78 | // Arguments 79 | // - p_adc_inst: Pointer to adc_t object. 80 | // 81 | // Return 82 | // - int: Number of samples per frame of data from the ADC. 83 | // 84 | int adc_get_samples_per_frame(adc_t* p_adc_inst); 85 | 86 | // 87 | // adc_set_bytes_per_sample - Set the number of bytes per sample in the data from the 88 | // ADC (i.e. tdata width). 89 | // 90 | // Arguments 91 | // - p_adc_inst: Pointer to adc_t object. 92 | // - samples_per_frame: Number of bytes per sample in the data from the ADC (i.e. 93 | // tdata width). 94 | // 95 | void adc_set_bytes_per_sample(adc_t* p_adc_inst, int bytes_per_sample); 96 | 97 | // 98 | // adc_get_bytes_per_sample - Get the number of bytes per sample in the data from the 99 | // ADC (i.e. tdata width). 100 | // 101 | // Arguments 102 | // - p_adc_inst: Pointer to adc_t object. 103 | // 104 | // Return 105 | // - int: Number of bytes per sample in the data from the ADC (i.e. tdata 106 | // width). 107 | // 108 | int adc_get_bytes_per_sample(adc_t* p_adc_inst); 109 | 110 | // 111 | // adc_enable - Enable the ADC to start streaming samples. 112 | // 113 | // Arguments 114 | // - p_adc_inst: Pointer to the adc_t object. 115 | // 116 | void adc_enable(adc_t* p_adc_inst); 117 | 118 | // 119 | // adc_get_frame - Get the next frame of data from the ADC. 120 | // 121 | // Arguments 122 | // - p_adc_inst: Pointer to the adc_t object. 123 | // - buf: Buffer containing the next frame of data from the ADC. 124 | // 125 | int adc_get_frame(adc_t* p_adc_inst, void* buf); 126 | 127 | #endif /* ADC_H_ */ 128 | 129 | -------------------------------------------------------------------------------- /SW/adc.c: -------------------------------------------------------------------------------- 1 | 2 | // Includes 3 | #include 4 | #include "adc.h" 5 | #include "xgpio.h" 6 | #include "dma_passthrough.h" 7 | 8 | // Private data 9 | typedef struct adc_periphs 10 | { 11 | dma_passthrough_t* p_dma_passthrough_inst; 12 | XGpio gpio_inst; 13 | } adc_periphs_t; 14 | 15 | // Object definition 16 | typedef struct adc 17 | { 18 | adc_periphs_t periphs; 19 | int samples_per_frame; 20 | int bytes_per_sample; 21 | } adc_t; 22 | 23 | // Private functions 24 | static int init_gpio(XGpio* p_gpio_inst, int gpio_device_id) 25 | { 26 | 27 | // Local variables 28 | int status = 0; 29 | 30 | // Initialize driver 31 | status = XGpio_Initialize(p_gpio_inst, gpio_device_id); 32 | if (status != XST_SUCCESS) 33 | { 34 | xil_printf("ERROR! Initialization of AXI GPIO instance failed.\n\r"); 35 | return ADC_GPIO_INIT_FAIL; 36 | } 37 | 38 | // Set value to 0 in case set some other way by previous run 39 | XGpio_DiscreteWrite(p_gpio_inst, 1, 0); 40 | 41 | return ADC_SUCCESS; 42 | 43 | } 44 | 45 | // Public functions 46 | adc_t* adc_create(int gpio_device_id, int dma_device_id, int intc_device_id, int s2mm_intr_id, 47 | int mm2s_intr_id, int bytes_per_sample) 48 | { 49 | 50 | // Local variables 51 | int status; 52 | adc_t* p_obj; 53 | 54 | // Allocate memory for ADC object 55 | p_obj = (adc_t*) malloc(sizeof(adc_t)); 56 | if (p_obj == NULL) 57 | { 58 | xil_printf("ERROR! Failed to allocate memory for ADC object.\n\r"); 59 | return NULL; 60 | } 61 | 62 | // Create DMA Passthrough object to be used by the ADC 63 | p_obj->periphs.p_dma_passthrough_inst = dma_passthrough_create 64 | ( 65 | dma_device_id, 66 | intc_device_id, 67 | s2mm_intr_id, 68 | mm2s_intr_id, 69 | bytes_per_sample 70 | ); 71 | if (p_obj->periphs.p_dma_passthrough_inst == NULL) 72 | { 73 | xil_printf("ERROR! Failed to create DMA Passthrough object for use by the ADC.\n\r"); 74 | return NULL; 75 | } 76 | 77 | // Register and initialize peripherals 78 | status = init_gpio(&p_obj->periphs.gpio_inst, gpio_device_id); 79 | if (status != XST_SUCCESS) 80 | { 81 | xil_printf("ERROR! Failed to initialize GPIO.\n\r"); 82 | adc_destroy(p_obj); 83 | return NULL; 84 | } 85 | 86 | // Initialize ADC parameters 87 | adc_set_samples_per_frame(p_obj, 1024); 88 | adc_set_bytes_per_sample(p_obj, bytes_per_sample); 89 | 90 | return p_obj; 91 | 92 | } 93 | 94 | void adc_destroy(adc_t* p_adc_inst) 95 | { 96 | dma_passthrough_destroy(p_adc_inst->periphs.p_dma_passthrough_inst); 97 | free(p_adc_inst); 98 | } 99 | 100 | void adc_set_samples_per_frame(adc_t* p_adc_inst, int samples_per_frame) 101 | { 102 | p_adc_inst->samples_per_frame = samples_per_frame; 103 | dma_passthrough_set_buf_length(p_adc_inst->periphs.p_dma_passthrough_inst, samples_per_frame); 104 | } 105 | 106 | int adc_get_samples_per_frame(adc_t* p_adc_inst) 107 | { 108 | return (p_adc_inst->samples_per_frame); 109 | } 110 | 111 | void adc_set_bytes_per_sample(adc_t* p_adc_inst, int bytes_per_sample) 112 | { 113 | p_adc_inst->bytes_per_sample = bytes_per_sample; 114 | dma_passthrough_set_sample_size_bytes(p_adc_inst->periphs.p_dma_passthrough_inst, bytes_per_sample); 115 | } 116 | 117 | int adc_get_bytes_per_sample(adc_t* p_adc_inst) 118 | { 119 | return (p_adc_inst->bytes_per_sample); 120 | } 121 | 122 | void adc_enable(adc_t* p_adc_inst) 123 | // The implementation of this function is specific to this hardware where a GPIO 124 | // is used to emulate a data source. This function would obviously be implemented 125 | // completely differently if there were an actual ADC in the system. 126 | { 127 | dma_passthrough_reset(p_adc_inst->periphs.p_dma_passthrough_inst); // Reset DMA to flush those 4 extra samples that are accepted before DMA configuration 128 | XGpio_DiscreteSet(&p_adc_inst->periphs.gpio_inst, 1, adc_get_samples_per_frame(p_adc_inst)); // Assert the reset on the hardware counter 129 | XGpio_DiscreteSet(&p_adc_inst->periphs.gpio_inst, 1, 0x80000000); // Release the reset on the hardware counter 130 | } 131 | 132 | int adc_get_frame(adc_t* p_adc_inst, void* buf) 133 | { 134 | 135 | // Local variables 136 | int status; 137 | 138 | dma_passthrough_set_rcv_buf(p_adc_inst->periphs.p_dma_passthrough_inst, buf); 139 | status = dma_passthrough_rcv(p_adc_inst->periphs.p_dma_passthrough_inst); 140 | if (status != DMA_PASSTHROUGH_SUCCESS) 141 | { 142 | xil_printf("ERROR! DMA Passthrough error occurred when trying to get data.\n\r"); 143 | return ADC_DMA_FAIL; 144 | } 145 | 146 | return ADC_SUCCESS; 147 | 148 | } 149 | 150 | -------------------------------------------------------------------------------- /RO/ro_pair.v: -------------------------------------------------------------------------------- 1 | // Copyright [2017] [Secure Computation Lab at UConn]. All rights reserved. 2 | // Use of this source code is governed by a MIT-style 3 | // license that can be found in the LICENSE file. 4 | // 5 | // Author: Chenglu Jin at 6 | // 7 | // This is the file which contains 450 RO pairs. 8 | 9 | module inv_cell 10 | (input a, 11 | output q); 12 | 13 | LUT1 #( 14 | .INIT(2'h1)) 15 | inv 16 | (.I0(a), 17 | .O(q)); 18 | endmodule // inv_cell 19 | 20 | module nand_cell 21 | (input a, 22 | input b, 23 | output q); 24 | 25 | LUT2 #( 26 | .INIT(4'h7)) 27 | nand_gate 28 | (.I0(a), 29 | .I1(b), 30 | .O(q)); 31 | endmodule // nand_cell 32 | 33 | module single_ro_pair 34 | #( parameter WIDTH = 5, 35 | parameter ACC = 5)( 36 | input resetn, 37 | input clk, 38 | input en, 39 | 40 | output e, 41 | output r 42 | ); 43 | 44 | (* keep = "true" *) wire [WIDTH - 1:0] ro_1, ro_2; 45 | (* keep = "true" *) reg [ACC -1 :0] cnt1, cnt2; 46 | wire [ACC-1:0] co; 47 | wire r_w; 48 | reg [ACC-1:0] syn_cnt1; 49 | reg [ACC-1:0] syn_cnt2; 50 | 51 | nand_cell nand_cell1 (en, ro_1[4], ro_1[0]); 52 | inv_cell inv1_0 (ro_1[0], ro_1[1]); 53 | inv_cell inv1_1 (ro_1[1], ro_1[2]); 54 | inv_cell inv1_2 (ro_1[2], ro_1[3]); 55 | inv_cell inv1_3 (ro_1[3], ro_1[4]); 56 | 57 | nand_cell nand_cell2 (en, ro_2[4], ro_2[0]); 58 | inv_cell inv2_0 (ro_2[0], ro_2[1]); 59 | inv_cell inv2_1 (ro_2[1], ro_2[2]); 60 | inv_cell inv2_2 (ro_2[2], ro_2[3]); 61 | inv_cell inv2_3 (ro_2[3], ro_2[4]); 62 | 63 | always @ (posedge ro_1[WIDTH-1] or negedge resetn) 64 | if (!resetn) 65 | cnt1 <= {ACC{1'b0}}; 66 | else 67 | cnt1 <= cnt1 + {{(ACC-1){1'b0}},1'b1}; 68 | 69 | always @ (posedge ro_2[WIDTH-1] or negedge resetn) 70 | if (!resetn) 71 | cnt2 <= {ACC{1'b0}}; 72 | else 73 | cnt2 <= cnt2 + {{(ACC-1){1'b0}},1'b1}; 74 | 75 | always @ (posedge clk) 76 | if (!resetn) 77 | syn_cnt1 <= {ACC{1'b0}}; 78 | else if (en == 1'b1) 79 | syn_cnt1 <= cnt1; 80 | else 81 | syn_cnt1 <= syn_cnt1; 82 | 83 | always @ (posedge clk) 84 | if (!resetn) 85 | syn_cnt2 <= {ACC{1'b0}}; 86 | else if (en == 1'b1) 87 | syn_cnt2 <= cnt2; 88 | else 89 | syn_cnt2 <= syn_cnt2; 90 | 91 | assign e = (syn_cnt1 > syn_cnt2)? 1'b1: 1'b0; 92 | assign co = e? (syn_cnt1 - syn_cnt2) : (syn_cnt2 - syn_cnt1); 93 | assign r = ((co > 5'd6)) ? 1'b1 : 1'b0; 94 | endmodule 95 | 96 | module ro_pair_wrapper 97 | #(parameter NUM_RO = 450) 98 | (clk, resetn, e, r, done); 99 | input clk; 100 | input resetn; 101 | output reg [NUM_RO - 1 : 0] e; 102 | output reg [NUM_RO - 1 : 0] r; 103 | output done; 104 | 105 | reg [5:0] clk_cnt; 106 | wire resetn_ro, en; 107 | reg [1:0] state; 108 | wire [NUM_RO-1:0] e_v; 109 | wire [NUM_RO-1:0] r_v; 110 | 111 | always @ (posedge clk or negedge resetn) 112 | if (!resetn) 113 | state <= 2'b0; //Idle 114 | else if (state == 2'b0) 115 | state <= 2'b01; //run 116 | else if (state == 2'b01 && clk_cnt == 6'h2c) 117 | state <= 2'b10; //read data 118 | else 119 | state <= state; 120 | 121 | always @ (posedge clk or negedge resetn) 122 | if (!resetn) 123 | clk_cnt <= 6'b00; 124 | else if (state == 2'b01) 125 | clk_cnt <= clk_cnt + 6'h1; 126 | else 127 | clk_cnt <= clk_cnt; 128 | 129 | assign resetn_ro = (clk_cnt == 6'b01) ? 1'b0 : 1'b1; 130 | assign en = (state == 2'b1 && clk_cnt < 6'h18)? 1'b1 : 1'b0; 131 | assign done = (state == 2'b10) ? 1'b1 : 1'b0; 132 | 133 | always @ (posedge clk) 134 | if (!resetn) 135 | e <= {NUM_RO{1'b0}}; 136 | else if (clk_cnt == 6'h25) 137 | e <= e_v; 138 | else 139 | e <= e; 140 | 141 | always @ (posedge clk) 142 | if (!resetn) 143 | r <= {NUM_RO{1'b0}}; 144 | else if (clk_cnt == 6'h25) 145 | r <= r_v; 146 | else 147 | r <= r; 148 | 149 | generate 150 | genvar i; 151 | for (i=0; i 6 | // 7 | // This modules serves as a centralized communication hub to communicate 8 | // between the AXI stream interface with the local bus that is either 9 | // 128 bit wide or 450 bit wide. 10 | // All the internal modules that need to communicate with the processor 11 | // connect with this module. 12 | 13 | `define AXI_REC 2'b00 14 | `define AXI_SEN 2'b01 15 | `define LOC_RD 2'b10 16 | `define LOC_WR 2'b11 17 | 18 | module comm_buf (clk, resetn, data_in_TDATA, data_in_TVALID, data_in_TREADY, data_in_TLAST, data_out_TDATA, data_out_TVALID, data_out_TREADY, data_out_TLAST, read_en, read_data, read2_en, read2_data, write_en, write_data, write2_en, write2_data, data_received, data_sent, op_mode); 19 | input clk; 20 | input resetn; 21 | input [127:0] data_in_TDATA; 22 | input data_in_TVALID; 23 | output data_in_TREADY; 24 | input data_in_TLAST; 25 | output [127:0] data_out_TDATA; 26 | output data_out_TVALID; 27 | input data_out_TREADY; 28 | output data_out_TLAST; 29 | input read_en; //first mode of read, used to read matrix 30 | output [127:0] read_data; 31 | input read2_en; //second mode of reading, used to read index vector and b vector 32 | output [449:0] read2_data; 33 | input write_en; 34 | input [127:0] write_data; 35 | input write2_en; 36 | input [449:0] write2_data; 37 | output data_received; 38 | output data_sent; 39 | input [1:0] op_mode; 40 | 41 | reg data_in_TREADY; 42 | reg data_out_TVALID; 43 | reg data_out_TLAST; 44 | reg [511:0] data_buf; 45 | reg [2:0] package_cnt; 46 | reg data_received; 47 | reg data_sent; 48 | reg [5:0] backoff_cnt; 49 | wire axi_enable; 50 | 51 | always @ (posedge clk or negedge resetn) 52 | if(!resetn) 53 | backoff_cnt <= 6'h0; 54 | else if (package_cnt == 3'h3 && op_mode == `AXI_SEN) 55 | backoff_cnt <= 6'h0; 56 | else if (backoff_cnt < 6'h3f) 57 | backoff_cnt <= backoff_cnt + 1'b1; 58 | else 59 | backoff_cnt <= backoff_cnt; 60 | 61 | assign axi_enable = (backoff_cnt == 6'h3f) ? 1'b1 : 1'b0; 62 | 63 | always @(posedge clk or negedge resetn) 64 | if (!resetn) 65 | data_buf <= 512'h0; 66 | else if (op_mode == `AXI_REC && data_in_TREADY && data_in_TVALID && axi_enable) 67 | data_buf <= {data_buf[383:0], data_in_TDATA}; 68 | else if (op_mode == `AXI_SEN && data_out_TREADY && data_out_TVALID && axi_enable) 69 | data_buf <= {data_buf[383:0], 128'b0}; 70 | else if (op_mode == `LOC_RD && read_en) 71 | data_buf <= {data_buf[383:0], 128'b0}; 72 | else if (op_mode == `LOC_WR && write_en) 73 | data_buf <= {data_buf[383:0], write_data}; 74 | else if (op_mode == `LOC_WR && write2_en) 75 | data_buf <= {write2_data, 62'h0}; 76 | else 77 | data_buf <= data_buf; 78 | 79 | always @ (posedge clk or negedge resetn) 80 | if (!resetn) 81 | data_in_TREADY <= 1'b0; 82 | else if (op_mode == `AXI_REC && package_cnt <3'h4 && axi_enable) 83 | data_in_TREADY <= 1'b1; 84 | else 85 | data_in_TREADY <= 1'b0; 86 | 87 | always @ (posedge clk or negedge resetn) 88 | if (!resetn) 89 | package_cnt <= 3'b0; 90 | else if (op_mode == `AXI_REC && data_in_TVALID == 1 && data_in_TREADY == 1 && axi_enable) 91 | package_cnt <= package_cnt + 1'b1; 92 | else if (op_mode == `AXI_REC && data_received == 1 && axi_enable) 93 | package_cnt <= package_cnt; 94 | else if (op_mode == `AXI_REC && data_in_TVALID == 0 && axi_enable) 95 | package_cnt <= 3'b0; 96 | else if (op_mode == `AXI_SEN && data_out_TVALID == 1 && axi_enable) 97 | package_cnt <= package_cnt + 1'b1; 98 | else if (op_mode == `AXI_SEN && data_sent == 1 && axi_enable) 99 | package_cnt <= package_cnt; 100 | else if (op_mode == `AXI_SEN && data_out_TVALID == 0 && axi_enable) 101 | package_cnt <= 3'b0; 102 | else 103 | package_cnt <= package_cnt; 104 | 105 | always @ (posedge clk or negedge resetn) 106 | if (!resetn) 107 | data_out_TVALID <= 1'b0; 108 | else if (op_mode == `AXI_SEN && data_out_TREADY == 1 && package_cnt <3'h3 && axi_enable) 109 | data_out_TVALID <= 1'b1; 110 | else 111 | data_out_TVALID <= 1'b0; 112 | 113 | always @ (posedge clk or negedge resetn) 114 | if (!resetn) 115 | data_out_TLAST <= 1'b0; 116 | else if (op_mode == `AXI_SEN && data_out_TVALID == 1 && package_cnt == 3'h2 && axi_enable) 117 | data_out_TLAST <= 1'b1; 118 | else 119 | data_out_TLAST <= 1'b0; 120 | 121 | always @ (posedge clk or negedge resetn) 122 | if (!resetn) 123 | data_received <= 1'b0; 124 | else if (op_mode == `AXI_REC && data_in_TLAST == 1'b1 && axi_enable) 125 | data_received <= 1'b1; 126 | else if (op_mode == `AXI_REC && axi_enable) 127 | data_received <= data_received; 128 | else 129 | data_received <= 1'b0; 130 | 131 | always @ (posedge clk or negedge resetn) 132 | if (!resetn) 133 | data_sent <= 1'b0; 134 | else if (op_mode == `AXI_SEN && data_out_TLAST == 1'b1 && axi_enable) 135 | data_sent <= 1'b1; 136 | else if (op_mode == `AXI_SEN && axi_enable) 137 | data_sent <= data_sent; 138 | else 139 | data_sent <= 1'b0; 140 | 141 | assign data_out_TDATA = data_buf[511:384]; 142 | assign read_data = data_buf[511:384]; 143 | assign read2_data = data_buf[511:62]; 144 | 145 | endmodule 146 | -------------------------------------------------------------------------------- /system/matrix_mul.v: -------------------------------------------------------------------------------- 1 | // Copyright [2017] [Secure Computation Lab at UConn]. All rights reserved. 2 | // Use of this source code is governed by a MIT-style 3 | // license that can be found in the LICENSE file. 4 | // 5 | // Author: Chenglu Jin at 6 | // 7 | // This is a pipelined 128*128 matrix and 128 bit vector multiplier. 8 | 9 | module matrix_mul(clk, resetn, a, b, e, o); 10 | 11 | input clk; 12 | input resetn; 13 | input [16383:0] a; 14 | input [127:0] b; 15 | input [127:0] e; 16 | output [127:0] o; 17 | 18 | wire [127:0] int_val; 19 | reg [127:0] int_val_reg; 20 | reg [63:0] temp_b; 21 | 22 | 23 | always @ (posedge clk or negedge resetn) 24 | if (!resetn) 25 | int_val_reg <= 128'h0; 26 | else 27 | int_val_reg <= int_val; 28 | always @ (posedge clk or negedge resetn) 29 | if (!resetn) 30 | temp_b <= 63'h0; 31 | else 32 | temp_b <= b[63:0]; 33 | 34 | genvar genvar_i; 35 | 36 | generate 37 | for (genvar_i = 0; genvar_i < 128; genvar_i= genvar_i+1) 38 | begin: mul_level1 39 | assign o[genvar_i] = int_val_reg[genvar_i] ^ (a[genvar_i * 128 +0] & temp_b[0]) ^ (a[genvar_i * 128 +1] & temp_b[1]) ^ (a[genvar_i * 128 +2] & temp_b[2]) ^ (a[genvar_i * 128 +3] & temp_b[3]) ^ (a[genvar_i * 128 +4] & temp_b[4]) ^ (a[genvar_i * 128 +5] & temp_b[5]) ^ (a[genvar_i * 128 +6] & temp_b[6]) ^ (a[genvar_i * 128 +7] & temp_b[7]) ^ (a[genvar_i * 128 +8] & temp_b[8]) ^ (a[genvar_i * 128 +9] & temp_b[9]) ^ (a[genvar_i * 128 +10] & temp_b[10]) ^ (a[genvar_i * 128 +11] & temp_b[11]) ^ (a[genvar_i * 128 +12] & temp_b[12]) ^ (a[genvar_i * 128 +13] & temp_b[13]) ^ (a[genvar_i * 128 +14] & temp_b[14]) ^ (a[genvar_i * 128 +15] & temp_b[15]) ^ (a[genvar_i * 128 +16] & temp_b[16]) ^ (a[genvar_i * 128 +17] & temp_b[17]) ^ (a[genvar_i * 128 +18] & temp_b[18]) ^ (a[genvar_i * 128 +19] & temp_b[19]) ^ (a[genvar_i * 128 +20] & temp_b[20]) ^ (a[genvar_i * 128 +21] & temp_b[21]) ^ (a[genvar_i * 128 +22] & temp_b[22]) ^ (a[genvar_i * 128 +23] & temp_b[23]) ^ (a[genvar_i * 128 +24] & temp_b[24]) ^ (a[genvar_i * 128 +25] & temp_b[25]) ^ (a[genvar_i * 128 +26] & temp_b[26]) ^ (a[genvar_i * 128 +27] & temp_b[27]) ^ (a[genvar_i * 128 +28] & temp_b[28]) ^ (a[genvar_i * 128 +29] & temp_b[29]) ^ (a[genvar_i * 128 +30] & temp_b[30]) ^ (a[genvar_i * 128 +31] & temp_b[31]) ^ (a[genvar_i * 128 +32] & temp_b[32]) ^ (a[genvar_i * 128 +33] & temp_b[33]) ^ (a[genvar_i * 128 +34] & temp_b[34]) ^ (a[genvar_i * 128 +35] & temp_b[35]) ^ (a[genvar_i * 128 +36] & temp_b[36]) ^ (a[genvar_i * 128 +37] & temp_b[37]) ^ (a[genvar_i * 128 +38] & temp_b[38]) ^ (a[genvar_i * 128 +39] & temp_b[39]) ^ (a[genvar_i * 128 +40] & temp_b[40]) ^ (a[genvar_i * 128 +41] & temp_b[41]) ^ (a[genvar_i * 128 +42] & temp_b[42]) ^ (a[genvar_i * 128 +43] & temp_b[43]) ^ (a[genvar_i * 128 +44] & temp_b[44]) ^ (a[genvar_i * 128 +45] & temp_b[45]) ^ (a[genvar_i * 128 +46] & temp_b[46]) ^ (a[genvar_i * 128 +47] & temp_b[47]) ^ (a[genvar_i * 128 +48] & temp_b[48]) ^ (a[genvar_i * 128 +49] & temp_b[49]) ^ (a[genvar_i * 128 +50] & temp_b[50]) ^ (a[genvar_i * 128 +51] & temp_b[51]) ^ (a[genvar_i * 128 +52] & temp_b[52]) ^ (a[genvar_i * 128 +53] & temp_b[53]) ^ (a[genvar_i * 128 +54] & temp_b[54]) ^ (a[genvar_i * 128 +55] & temp_b[55]) ^ (a[genvar_i * 128 +56] & temp_b[56]) ^ (a[genvar_i * 128 +57] & temp_b[57]) ^ (a[genvar_i * 128 +58] & temp_b[58]) ^ (a[genvar_i * 128 +59] & temp_b[59]) ^ (a[genvar_i * 128 +60] & temp_b[60]) ^ (a[genvar_i * 128 +61] & temp_b[61]) ^ (a[genvar_i * 128 +62] & temp_b[62]) ^ (a[genvar_i * 128 +63] & temp_b[63]); 40 | assign int_val[genvar_i] = (a[genvar_i * 128 +64] & b[64]) ^ (a[genvar_i * 128 +65] & b[65]) ^ (a[genvar_i * 128 +66] & b[66]) ^ (a[genvar_i * 128 +67] & b[67]) ^ (a[genvar_i * 128 +68] & b[68]) ^ (a[genvar_i * 128 +69] & b[69]) ^ (a[genvar_i * 128 +70] & b[70]) ^ (a[genvar_i * 128 +71] & b[71]) ^ (a[genvar_i * 128 +72] & b[72]) ^ (a[genvar_i * 128 +73] & b[73]) ^ (a[genvar_i * 128 +74] & b[74]) ^ (a[genvar_i * 128 +75] & b[75]) ^ (a[genvar_i * 128 +76] & b[76]) ^ (a[genvar_i * 128 +77] & b[77]) ^ (a[genvar_i * 128 +78] & b[78]) ^ (a[genvar_i * 128 +79] & b[79]) ^ (a[genvar_i * 128 +80] & b[80]) ^ (a[genvar_i * 128 +81] & b[81]) ^ (a[genvar_i * 128 +82] & b[82]) ^ (a[genvar_i * 128 +83] & b[83]) ^ (a[genvar_i * 128 +84] & b[84]) ^ (a[genvar_i * 128 +85] & b[85]) ^ (a[genvar_i * 128 +86] & b[86]) ^ (a[genvar_i * 128 +87] & b[87]) ^ (a[genvar_i * 128 +88] & b[88]) ^ (a[genvar_i * 128 +89] & b[89]) ^ (a[genvar_i * 128 +90] & b[90]) ^ (a[genvar_i * 128 +91] & b[91]) ^ (a[genvar_i * 128 +92] & b[92]) ^ (a[genvar_i * 128 +93] & b[93]) ^ (a[genvar_i * 128 +94] & b[94]) ^ (a[genvar_i * 128 +95] & b[95]) ^ (a[genvar_i * 128 +96] & b[96]) ^ (a[genvar_i * 128 +97] & b[97]) ^ (a[genvar_i * 128 +98] & b[98]) ^ (a[genvar_i * 128 +99] & b[99]) ^ (a[genvar_i * 128 +100] & b[100]) ^ (a[genvar_i * 128 +101] & b[101]) ^ (a[genvar_i * 128 +102] & b[102]) ^ (a[genvar_i * 128 +103] & b[103]) ^ (a[genvar_i * 128 +104] & b[104]) ^ (a[genvar_i * 128 +105] & b[105]) ^ (a[genvar_i * 128 +106] & b[106]) ^ (a[genvar_i * 128 +107] & b[107]) ^ (a[genvar_i * 128 +108] & b[108]) ^ (a[genvar_i * 128 +109] & b[109]) ^ (a[genvar_i * 128 +110] & b[110]) ^ (a[genvar_i * 128 +111] & b[111]) ^ (a[genvar_i * 128 +112] & b[112]) ^ (a[genvar_i * 128 +113] & b[113]) ^ (a[genvar_i * 128 +114] & b[114]) ^ (a[genvar_i * 128 +115] & b[115]) ^ (a[genvar_i * 128 +116] & b[116]) ^ (a[genvar_i * 128 +117] & b[117]) ^ (a[genvar_i * 128 +118] & b[118]) ^ (a[genvar_i * 128 +119] & b[119]) ^ (a[genvar_i * 128 +120] & b[120]) ^ (a[genvar_i * 128 +121] & b[121]) ^ (a[genvar_i * 128 +122] & b[122]) ^ (a[genvar_i * 128 +123] & b[123]) ^ (a[genvar_i * 128 +124] & b[124]) ^ (a[genvar_i * 128 +125] & b[125]) ^ (a[genvar_i * 128 +126] & b[126]) ^ (a[genvar_i * 128 +127] & b[127]) ^ e[genvar_i]; 41 | end 42 | endgenerate 43 | 44 | endmodule 45 | 46 | -------------------------------------------------------------------------------- /SW/lpn.c: -------------------------------------------------------------------------------- 1 | // Copyright [2017] [Secure Computation Lab at UConn]. All rights reserved. 2 | // Use of this source code is governed by a MIT-style 3 | // license that can be found in the LICENSE file. 4 | // 5 | // Author: Chenglu Jin at 6 | // 7 | // This file contains some functions that are required for constructing or 8 | // solving LPN problem. 9 | 10 | #include "lpn.h" 11 | 12 | int skip_row_sel (bool* selected_index, bool* index_before_sel, int sel_num) 13 | { 14 | int i, j; 15 | int cnt = 0; 16 | for (i = 0; i < 450; i++) 17 | { 18 | if (index_before_sel[i] == 1) 19 | { 20 | cnt++; 21 | } 22 | selected_index[i] = 0; 23 | } 24 | if (cnt < sel_num) 25 | { 26 | return DATA_INCORRECT; 27 | } 28 | else 29 | { 30 | i = 0; 31 | j = rand() % (cnt - sel_num); 32 | for (; j < 450 ; j++) 33 | { 34 | if (index_before_sel[j] == 1) 35 | { 36 | selected_index[j] = 1; 37 | i++; 38 | if (i == sel_num) 39 | break; 40 | } 41 | } 42 | return DATA_CORRECT; 43 | } 44 | } 45 | 46 | 47 | int index_intersect (bool* index1, bool* index2, bool* output_index, int NUM_RO, int selected_ro) 48 | { 49 | int i,j; 50 | 51 | j = 0; 52 | for (i = 0; i < NUM_RO; i ++) 53 | { 54 | output_index[i] = 0; 55 | } 56 | 57 | for ( i =0; i < NUM_RO; i++) 58 | { 59 | if (index1[i] & index2[i]) 60 | { 61 | output_index[i] = 1; 62 | j++; 63 | } 64 | } 65 | if (j >= selected_ro) 66 | { 67 | return 0; 68 | } 69 | else 70 | { 71 | return 1; 72 | } 73 | } 74 | 75 | int skip_select_e (bool * e_vector, bool* selected_e_vector, bool* index , bool* selected_index, int NUM_RO, int selected_ro, int skip_num) 76 | { 77 | int i,j; 78 | int skip_cnt = 0; 79 | 80 | for(i = 0; i < NUM_RO; i++) 81 | { 82 | selected_index[i] = 0; 83 | } 84 | 85 | j = 0; 86 | for ( i =0; i < NUM_RO; i++) 87 | { 88 | if (index[i] == 1) 89 | { 90 | skip_cnt++; 91 | if (skip_cnt > skip_num) 92 | { 93 | selected_e_vector[j] = e_vector[i]; 94 | j++; 95 | selected_index[i] = 1; 96 | } 97 | } 98 | if (j == selected_ro) 99 | { 100 | return DATA_CORRECT; 101 | } 102 | } 103 | return DATA_INCORRECT; 104 | } 105 | 106 | void select_matrix(int* a, int * selected_matrix, bool* index, int num_selection, int num_ro) 107 | { 108 | int i, j; 109 | int cnt = 0; 110 | for (i = 0; i < num_ro; i = i + 1) { 111 | if (index[i] == 1) 112 | { 113 | for (j = 0; j < 4; j++) { 114 | selected_matrix[cnt *4 + j] = a[i*4 + j]; 115 | } 116 | cnt ++; 117 | if (cnt == num_selection) 118 | { 119 | break; 120 | } 121 | } 122 | } 123 | } 124 | 125 | void clean_index_gen (bool* index) 126 | { 127 | int i, j; 128 | j = 0; 129 | int flag = 0; 130 | for (i = 0; i < 450; i++) 131 | { 132 | if (flag == 0 && index[i] == 1) 133 | { 134 | j++; 135 | } 136 | if (flag == 1) 137 | { 138 | index[i] = 0; 139 | } 140 | if (j == 256) 141 | { 142 | flag = 1; 143 | } 144 | } 145 | } 146 | 147 | //specific for converting 450 bits in 512 bit long message to 450 bool variables. 148 | void convert_integer_to_bool (int* input_array, bool* output_array) 149 | { 150 | int i, j, k, bound_j, bound_k; 151 | int temp_int; 152 | bool temp; 153 | for (i = 0; i < 4; i++) 154 | { 155 | if (i == 3) 156 | bound_j = 0; 157 | else 158 | bound_j = -1; 159 | for (j = 3; j > bound_j ; j--) 160 | { 161 | if (i == 3 && j == 1) 162 | bound_k = 2; 163 | else 164 | bound_k = 32; 165 | for (k = 0; k < bound_k; k++) 166 | { 167 | temp_int = input_array[4*i+j]; 168 | temp_int = temp_int & (0x80000000>>k); 169 | temp_int = temp_int >> (31-k); 170 | temp = (bool) temp_int; 171 | output_array[128*i+(3-j)*32+k] = temp; 172 | } 173 | } 174 | } 175 | return; 176 | } 177 | 178 | //specific for converting 450 bool variables to 450 bits in 512 bit long message . 179 | void convert_bool_to_integer (bool* input_array, int* output_array) 180 | { 181 | int i, j, bound_j; 182 | int temp_int; 183 | 184 | for (i = 0; i <15; i++) 185 | { 186 | if (i == 14) 187 | bound_j = 2; 188 | else 189 | bound_j = 32; 190 | 191 | temp_int = 0; 192 | for (j = 0; j > 3)); 144 | 145 | endmodule 146 | 147 | 148 | module sha256_s1 ( 149 | input wire [31:0] x, 150 | output wire [31:0] s1 151 | ); 152 | 153 | assign s1 = ({x[16:0], x[31:17]} ^ {x[18:0], x[31:19]} ^ (x >> 10)); 154 | 155 | endmodule 156 | 157 | 158 | // a machine that delivers round constants 159 | module sha256_K_machine ( 160 | input clk, 161 | input rst, 162 | input en, 163 | output [31:0] K 164 | ); 165 | 166 | reg [2047:0] rom_q; 167 | wire [2047:0] rom_d = { rom_q[2015:0], rom_q[2047:2016] }; 168 | assign K = rom_q[2047:2016]; 169 | 170 | always @(posedge clk) 171 | begin 172 | if (rst) begin 173 | rom_q <= { 174 | 32'h428a2f98, 32'h71374491, 32'hb5c0fbcf, 32'he9b5dba5, 175 | 32'h3956c25b, 32'h59f111f1, 32'h923f82a4, 32'hab1c5ed5, 176 | 32'hd807aa98, 32'h12835b01, 32'h243185be, 32'h550c7dc3, 177 | 32'h72be5d74, 32'h80deb1fe, 32'h9bdc06a7, 32'hc19bf174, 178 | 32'he49b69c1, 32'hefbe4786, 32'h0fc19dc6, 32'h240ca1cc, 179 | 32'h2de92c6f, 32'h4a7484aa, 32'h5cb0a9dc, 32'h76f988da, 180 | 32'h983e5152, 32'ha831c66d, 32'hb00327c8, 32'hbf597fc7, 181 | 32'hc6e00bf3, 32'hd5a79147, 32'h06ca6351, 32'h14292967, 182 | 32'h27b70a85, 32'h2e1b2138, 32'h4d2c6dfc, 32'h53380d13, 183 | 32'h650a7354, 32'h766a0abb, 32'h81c2c92e, 32'h92722c85, 184 | 32'ha2bfe8a1, 32'ha81a664b, 32'hc24b8b70, 32'hc76c51a3, 185 | 32'hd192e819, 32'hd6990624, 32'hf40e3585, 32'h106aa070, 186 | 32'h19a4c116, 32'h1e376c08, 32'h2748774c, 32'h34b0bcb5, 187 | 32'h391c0cb3, 32'h4ed8aa4a, 32'h5b9cca4f, 32'h682e6ff3, 188 | 32'h748f82ee, 32'h78a5636f, 32'h84c87814, 32'h8cc70208, 189 | 32'h90befffa, 32'ha4506ceb, 32'hbef9a3f7, 32'hc67178f2 190 | }; 191 | end 192 | else if (en == 0) 193 | begin 194 | rom_q <= rom_q; 195 | end 196 | else begin 197 | rom_q <= rom_d; 198 | end 199 | end 200 | 201 | endmodule 202 | 203 | 204 | // initial hash values 205 | module sha256_H_0( 206 | output [255:0] H_0 207 | ); 208 | 209 | assign H_0 = { 210 | 32'h6A09E667, 32'hBB67AE85, 32'h3C6EF372, 32'hA54FF53A, 211 | 32'h510E527F, 32'h9B05688C, 32'h1F83D9AB, 32'h5BE0CD19 212 | }; 213 | 214 | endmodule 215 | -------------------------------------------------------------------------------- /SW/dma_passthrough.h: -------------------------------------------------------------------------------- 1 | 2 | ////////////////////////////////////////////////////////////////////////////////// 3 | // 4 | // Company: Xilinx 5 | // Engineer: bwiec 6 | // Create Date: 06 July 2015, 11:52:22 PM 7 | // Library Name: AXI DMA Passthrough 8 | // File Name: dma_passthrough.h 9 | // Target Devices: Zynq 10 | // Tool Versions: 2015.1 11 | // Description: Middleware API for a DMA passthrough using the AXI DMA with 12 | // interrupts. 13 | // Dependencies: 14 | // - xaxidma.h - Driver version v8.1 15 | // - xscugic.h - Driver version v3.0 16 | // Revision History: 17 | // - v1.0 18 | // * Initial release 19 | // * Tested on ZC702 and Zedboard 20 | // Additional Comments: 21 | // - This library is intended to be used as a layer between the base xaxidma 22 | // driver and application software. The programming model is a buffer received 23 | // from the outside world which can be operated on by the CPU. When it's done, 24 | // it copies the data to a second buffer which is sent back out to the world. 25 | // - While this library is designed targeting Zynq, since it is a soft IP, it 26 | // could be easily extended to support Microblaze as well. 27 | // - Source and destination buffers must be contiguous. Scatter gather is not 28 | // supported. 29 | // - S2MM and MM2S tdata widths on the AXI DMA must be the same. 30 | // 31 | ////////////////////////////////////////////////////////////////////////////////// 32 | 33 | #ifndef DMA_PASSTHROUGH_H_ 34 | #define DMA_PASSTHROUGH_H_ 35 | 36 | // Hardware-specific parameters 37 | #define DMA_PASSTHROUGH_IS_CACHE_COHERENT 0 // Set to 1 to avoid overhead of software cache flushes if going through the ACP 38 | 39 | // Return types 40 | #define DMA_PASSTHROUGH_SUCCESS 0 41 | #define DMA_PASSTHROUGH_DMA_INIT_FAIL -1 42 | #define DMA_PASSTHROUGH_INTC_INIT_FAIL -2 43 | #define DMA_PASSTHROUGH_XFER_FAIL -3 44 | 45 | // Object forward declaration 46 | typedef struct dma_passthrough dma_passthrough_t; 47 | 48 | // Public functions 49 | 50 | // 51 | // dma_passthrough_create - Create a DMA Passthrough object. 52 | // 53 | // Arguments 54 | // - dma_device_id: Device ID of the DMA instance to use. 55 | // - intc_device_id: Device ID of the Interrupt Controller instance to use. 56 | // - s2mm_intr_id: Interrupt ID for the AXI DMA S2MM channel. 57 | // - mm2s_intr_id: Interrupt ID for the AXI DMA MM2S channel. 58 | // - sample_size_bytes: Number of bytes per sample (i.e. number of bytes in tdata bus). 59 | // 60 | // Return 61 | // - dma_passthrough_t*: Non-NULL pointer to dma_passthrough_t object on success. 62 | // - NULL: NULL if something failed. 63 | // 64 | dma_passthrough_t* dma_passthrough_create(int dma_device_id, int intc_device_id, int s2mm_intr_id, 65 | int mm2s_intr_id, int sample_size_bytes); 66 | 67 | // 68 | // dma_passthrough_destroy - Destroy DMA Passthrough object. 69 | // 70 | // Arguments 71 | // - p_dma_passthrough_inst: Pointer to dma_passthrough_t object to be deallocated. 72 | // 73 | void dma_passthrough_destroy(dma_passthrough_t* p_dma_passthrough_inst); 74 | 75 | // 76 | // dma_passthrough_reset - Reset the DMA engine. 77 | // 78 | // Arguments 79 | // - p_dma_passthrough_inst: Pointer to dma_passthrough_t object. 80 | // 81 | void dma_passthrough_reset(dma_passthrough_t* p_dma_passthrough_inst); 82 | 83 | // 84 | // dma_passthrough_set_rcv_buf - Set pointer to receive buffer to be used. 85 | // 86 | // Arguments 87 | // - p_dma_passthrough_inst: Pointer to dma_passthrough_t object. 88 | // - p_stim_buf: Pointer to receive buffer to be used by the DMA. 89 | // 90 | void dma_passthrough_set_rcv_buf(dma_passthrough_t* p_dma_passthrough_inst, void* p_rcv_buf); 91 | 92 | // 93 | // dma_passthrough_get_rcv_buf - Get a pointer to the receive buffer. 94 | //. 95 | // Arguments 96 | // - p_dma_passthrough_inst: Pointer to dma_passthrough_t object. 97 | // 98 | // Return 99 | // - void*: Pointer to the receive buffer to be used by the DMA. 100 | // 101 | void* dma_passthrough_get_rcv_buf(dma_passthrough_t* p_dma_passthrough_inst); 102 | 103 | // 104 | // dma_passthrough_set_snd_buf - Set pointer to send buffer to be used. 105 | // 106 | // Arguments 107 | // - p_dma_passthrough_inst: Pointer to dma_passthrough_t object. 108 | // - p_stim_buf: Pointer to send buffer to be used by the DMA. 109 | // 110 | void dma_passthrough_set_snd_buf(dma_passthrough_t* p_dma_passthrough_inst, void* p_snd_buf); 111 | 112 | // 113 | // dma_passthrough_get_snd_buf - Get a pointer to the send buffer. 114 | //. 115 | // Arguments 116 | // - p_dma_passthrough_inst: Pointer to dma_passthrough_t object. 117 | // 118 | // Return 119 | // - void*: Pointer to the send buffer to be used by the DMA. 120 | // 121 | void* dma_passthrough_get_snd_buf(dma_passthrough_t* p_dma_passthrough_inst); 122 | 123 | // 124 | // dma_passthrough_set_buf_length - Set the buffer length (in samples) to use for DMA transfers. 125 | // 126 | // - p_dma_passthrough_inst: Pointer to dma_passthrough_t object. 127 | // - buf_length: Buffer length (in samples) to use for DMA transfers. 128 | // 129 | void dma_passthrough_set_buf_length(dma_passthrough_t* p_dma_passthrough_inst, int buf_length); 130 | 131 | // 132 | // dma_passthrough_get_buf_length - Get the buffer length (in samples) to be used for DMA transfers. 133 | // 134 | // Arguments 135 | // - p_dma_passthrough_inst: Pointer to dma_passthrough_t object. 136 | // 137 | // Return 138 | // - int: Buffer length (in samples) to be transferred by the DMA. 139 | // 140 | int dma_passthrough_get_buf_length(dma_passthrough_t* p_dma_passthrough_inst); 141 | 142 | // 143 | // dma_passthrough_set_sample_size_bytes - Set the size (in bytes) of each sample (i.e. number 144 | // of bytes in tdata bus). 145 | // 146 | // Arguments 147 | // - p_dma_passthrough_inst: Pointer to dma_passthrough_t object. 148 | // - sample_size_bytes: Number of bytes per sample. 149 | // 150 | void dma_passthrough_set_sample_size_bytes(dma_passthrough_t* p_dma_passthrough_inst, int sample_size_bytes); 151 | 152 | // 153 | // dma_passthrough_get_sample_size_bytes - Get the size (in bytes) of each sample (i.e. number 154 | // of bytes in tdata bus). 155 | // 156 | // Arguments 157 | // - p_dma_passthrough_inst: Pointer to dma_passthrough_t object. 158 | // 159 | // Return 160 | // - int: Number of bytes per sample. 161 | // 162 | int dma_passthrough_get_sample_size_bytes(dma_passthrough_t* p_dma_passthrough_inst); 163 | 164 | // 165 | // dma_passthrough_rcv - Receive a data buffer via DMA. 166 | // 167 | // Arguments 168 | // - p_dma_passthrough_inst: Pointer to dma_passthrough_t object. 169 | // 170 | // Return 171 | // - DMA_SUCCESS: No errors occurred during any DMA transfers. 172 | // - DMA_PASSTHROUGH_XFER_FAIL: Some error occurred during one of the DMA transfers. 173 | // 174 | int dma_passthrough_rcv(dma_passthrough_t* p_dma_passthrough_inst); 175 | 176 | // 177 | // dma_passthrough_snd - Send a data buffer via DMA. 178 | // 179 | // Arguments 180 | // - p_dma_passthrough_inst: Pointer to dma_passthrough_t object. 181 | // 182 | // Return 183 | // - DMA_SUCCESS: No errors occurred during any DMA transfers. 184 | // - DMA_PASSTHROUGH_XFER_FAIL: Some error occurred during one of the DMA transfers. 185 | // 186 | int dma_passthrough_snd(dma_passthrough_t* p_dma_passthrough_inst); 187 | 188 | 189 | #endif /* DMA_PASSTHROUGH_H_ */ 190 | -------------------------------------------------------------------------------- /system/row_sel.v: -------------------------------------------------------------------------------- 1 | // Copyright [2017] [Secure Computation Lab at UConn]. All rights reserved. 2 | // Use of this source code is governed by a MIT-style 3 | // license that can be found in the LICENSE file. 4 | // 5 | // Author: Chenglu Jin at 6 | // 7 | // This module receives matrix A row by row and selects 128 rows to feed into 8 | // the multipler in the latter stage. 9 | // This module can be used both in Gen and Ver. 10 | 11 | module row_sel (clk, resetn, en, index_valid, read_in, row_input, index_w, number_select, selected_matrix, shift_en, shift_out, done, half_way_done); 12 | input clk; 13 | input resetn; 14 | input en; 15 | input index_valid; 16 | input read_in; 17 | input [127:0] row_input; 18 | input [449:0] index_w; 19 | input [8:0] number_select; 20 | output reg [16383:0] selected_matrix; 21 | input shift_en; 22 | output [127:0] shift_out; 23 | output done; 24 | output half_way_done; 25 | 26 | reg [449:0] index; 27 | reg [8:0] cnt; 28 | 29 | always @ (posedge clk or negedge resetn) 30 | if (!resetn) 31 | selected_matrix <= 16384'h0; 32 | else if (read_in == 1'b1) 33 | selected_matrix <= {selected_matrix[16255:0], row_input}; 34 | else if (en == 1 && index[449] == 1'b1 && cnt != number_select) 35 | selected_matrix <= {selected_matrix[16255:0], row_input}; 36 | else if (shift_en == 1) 37 | selected_matrix <= {1'b0, selected_matrix[16383:16257], 1'b0, selected_matrix[16255:16129], 1'b0, selected_matrix[16127:16001], 1'b0, selected_matrix[15999:15873], 1'b0, selected_matrix[15871:15745], 1'b0, selected_matrix[15743:15617], 1'b0, selected_matrix[15615:15489], 1'b0, selected_matrix[15487:15361], 1'b0, selected_matrix[15359:15233], 1'b0, selected_matrix[15231:15105], 1'b0, selected_matrix[15103:14977], 1'b0, selected_matrix[14975:14849], 1'b0, selected_matrix[14847:14721], 1'b0, selected_matrix[14719:14593], 1'b0, selected_matrix[14591:14465], 1'b0, selected_matrix[14463:14337], 1'b0, selected_matrix[14335:14209], 1'b0, selected_matrix[14207:14081], 1'b0, selected_matrix[14079:13953], 1'b0, selected_matrix[13951:13825], 1'b0, selected_matrix[13823:13697], 1'b0, selected_matrix[13695:13569], 1'b0, selected_matrix[13567:13441], 1'b0, selected_matrix[13439:13313], 1'b0, selected_matrix[13311:13185], 1'b0, selected_matrix[13183:13057], 1'b0, selected_matrix[13055:12929], 1'b0, selected_matrix[12927:12801], 1'b0, selected_matrix[12799:12673], 1'b0, selected_matrix[12671:12545], 1'b0, selected_matrix[12543:12417], 1'b0, selected_matrix[12415:12289], 1'b0, selected_matrix[12287:12161], 1'b0, selected_matrix[12159:12033], 1'b0, selected_matrix[12031:11905], 1'b0, selected_matrix[11903:11777], 1'b0, selected_matrix[11775:11649], 1'b0, selected_matrix[11647:11521], 1'b0, selected_matrix[11519:11393], 1'b0, selected_matrix[11391:11265], 1'b0, selected_matrix[11263:11137], 1'b0, selected_matrix[11135:11009], 1'b0, selected_matrix[11007:10881], 1'b0, selected_matrix[10879:10753], 1'b0, selected_matrix[10751:10625], 1'b0, selected_matrix[10623:10497], 1'b0, selected_matrix[10495:10369], 1'b0, selected_matrix[10367:10241], 1'b0, selected_matrix[10239:10113], 1'b0, selected_matrix[10111:9985], 1'b0, selected_matrix[9983:9857], 1'b0, selected_matrix[9855:9729], 1'b0, selected_matrix[9727:9601], 1'b0, selected_matrix[9599:9473], 1'b0, selected_matrix[9471:9345], 1'b0, selected_matrix[9343:9217], 1'b0, selected_matrix[9215:9089], 1'b0, selected_matrix[9087:8961], 1'b0, selected_matrix[8959:8833], 1'b0, selected_matrix[8831:8705], 1'b0, selected_matrix[8703:8577], 1'b0, selected_matrix[8575:8449], 1'b0, selected_matrix[8447:8321], 1'b0, selected_matrix[8319:8193], 1'b0, selected_matrix[8191:8065], 1'b0, selected_matrix[8063:7937], 1'b0, selected_matrix[7935:7809], 1'b0, selected_matrix[7807:7681], 1'b0, selected_matrix[7679:7553], 1'b0, selected_matrix[7551:7425], 1'b0, selected_matrix[7423:7297], 1'b0, selected_matrix[7295:7169], 1'b0, selected_matrix[7167:7041], 1'b0, selected_matrix[7039:6913], 1'b0, selected_matrix[6911:6785], 1'b0, selected_matrix[6783:6657], 1'b0, selected_matrix[6655:6529], 1'b0, selected_matrix[6527:6401], 1'b0, selected_matrix[6399:6273], 1'b0, selected_matrix[6271:6145], 1'b0, selected_matrix[6143:6017], 1'b0, selected_matrix[6015:5889], 1'b0, selected_matrix[5887:5761], 1'b0, selected_matrix[5759:5633], 1'b0, selected_matrix[5631:5505], 1'b0, selected_matrix[5503:5377], 1'b0, selected_matrix[5375:5249], 1'b0, selected_matrix[5247:5121], 1'b0, selected_matrix[5119:4993], 1'b0, selected_matrix[4991:4865], 1'b0, selected_matrix[4863:4737], 1'b0, selected_matrix[4735:4609], 1'b0, selected_matrix[4607:4481], 1'b0, selected_matrix[4479:4353], 1'b0, selected_matrix[4351:4225], 1'b0, selected_matrix[4223:4097], 1'b0, selected_matrix[4095:3969], 1'b0, selected_matrix[3967:3841], 1'b0, selected_matrix[3839:3713], 1'b0, selected_matrix[3711:3585], 1'b0, selected_matrix[3583:3457], 1'b0, selected_matrix[3455:3329], 1'b0, selected_matrix[3327:3201], 1'b0, selected_matrix[3199:3073], 1'b0, selected_matrix[3071:2945], 1'b0, selected_matrix[2943:2817], 1'b0, selected_matrix[2815:2689], 1'b0, selected_matrix[2687:2561], 1'b0, selected_matrix[2559:2433], 1'b0, selected_matrix[2431:2305], 1'b0, selected_matrix[2303:2177], 1'b0, selected_matrix[2175:2049], 1'b0, selected_matrix[2047:1921], 1'b0, selected_matrix[1919:1793], 1'b0, selected_matrix[1791:1665], 1'b0, selected_matrix[1663:1537], 1'b0, selected_matrix[1535:1409], 1'b0, selected_matrix[1407:1281], 1'b0, selected_matrix[1279:1153], 1'b0, selected_matrix[1151:1025], 1'b0, selected_matrix[1023:897], 1'b0, selected_matrix[895:769], 1'b0, selected_matrix[767:641], 1'b0, selected_matrix[639:513], 1'b0, selected_matrix[511:385], 1'b0, selected_matrix[383:257], 1'b0, selected_matrix[255:129], 1'b0, selected_matrix[127:1]}; 38 | else 39 | selected_matrix <= selected_matrix; 40 | 41 | always @ (posedge clk or negedge resetn) 42 | if (!resetn) 43 | index <= 450'b0; 44 | else if (index_valid == 1'b1) 45 | index <= index_w; 46 | else if (en) 47 | index <= {index[448:0],1'b0}; 48 | else 49 | index <= index; 50 | 51 | always @ (posedge clk or negedge resetn) 52 | if (!resetn) 53 | cnt <= 9'b0; 54 | else if (index_valid == 1'b1) 55 | cnt <= 9'b0; 56 | else if (en == 1 && index[449] == 1'b1 && cnt < number_select) 57 | cnt <= cnt + 1; 58 | else 59 | cnt <= cnt; 60 | 61 | assign done = (cnt == 9'd128 || cnt == 9'd256) ? 1'b1 : 1'b0; 62 | assign half_way_done = (cnt == 9'd127 && index[449] == 1'b1) ? 1'b1 : 1'b0; 63 | assign shift_out = {selected_matrix[16256], selected_matrix[16128], selected_matrix[16000], selected_matrix[15872], selected_matrix[15744], selected_matrix[15616], selected_matrix[15488], selected_matrix[15360], selected_matrix[15232], selected_matrix[15104], selected_matrix[14976], selected_matrix[14848], selected_matrix[14720], selected_matrix[14592], selected_matrix[14464], selected_matrix[14336], selected_matrix[14208], selected_matrix[14080], selected_matrix[13952], selected_matrix[13824], selected_matrix[13696], selected_matrix[13568], selected_matrix[13440], selected_matrix[13312], selected_matrix[13184], selected_matrix[13056], selected_matrix[12928], selected_matrix[12800], selected_matrix[12672], selected_matrix[12544], selected_matrix[12416], selected_matrix[12288], selected_matrix[12160], selected_matrix[12032], selected_matrix[11904], selected_matrix[11776], selected_matrix[11648], selected_matrix[11520], selected_matrix[11392], selected_matrix[11264], selected_matrix[11136], selected_matrix[11008], selected_matrix[10880], selected_matrix[10752], selected_matrix[10624], selected_matrix[10496], selected_matrix[10368], selected_matrix[10240], selected_matrix[10112], selected_matrix[9984], selected_matrix[9856], selected_matrix[9728], selected_matrix[9600], selected_matrix[9472], selected_matrix[9344], selected_matrix[9216], selected_matrix[9088], selected_matrix[8960], selected_matrix[8832], selected_matrix[8704], selected_matrix[8576], selected_matrix[8448], selected_matrix[8320], selected_matrix[8192], selected_matrix[8064], selected_matrix[7936], selected_matrix[7808], selected_matrix[7680], selected_matrix[7552], selected_matrix[7424], selected_matrix[7296], selected_matrix[7168], selected_matrix[7040], selected_matrix[6912], selected_matrix[6784], selected_matrix[6656], selected_matrix[6528], selected_matrix[6400], selected_matrix[6272], selected_matrix[6144], selected_matrix[6016], selected_matrix[5888], selected_matrix[5760], selected_matrix[5632], selected_matrix[5504], selected_matrix[5376], selected_matrix[5248], selected_matrix[5120], selected_matrix[4992], selected_matrix[4864], selected_matrix[4736], selected_matrix[4608], selected_matrix[4480], selected_matrix[4352], selected_matrix[4224], selected_matrix[4096], selected_matrix[3968], selected_matrix[3840], selected_matrix[3712], selected_matrix[3584], selected_matrix[3456], selected_matrix[3328], selected_matrix[3200], selected_matrix[3072], selected_matrix[2944], selected_matrix[2816], selected_matrix[2688], selected_matrix[2560], selected_matrix[2432], selected_matrix[2304], selected_matrix[2176], selected_matrix[2048], selected_matrix[1920], selected_matrix[1792], selected_matrix[1664], selected_matrix[1536], selected_matrix[1408], selected_matrix[1280], selected_matrix[1152], selected_matrix[1024], selected_matrix[896], selected_matrix[768], selected_matrix[640], selected_matrix[512], selected_matrix[384], selected_matrix[256], selected_matrix[128], selected_matrix[0]}; 64 | 65 | endmodule 66 | 67 | -------------------------------------------------------------------------------- /SW/helloworld.c: -------------------------------------------------------------------------------- 1 | // Copyright [2017] [Secure Computation Lab at UConn]. All rights reserved. 2 | // Use of this source code is governed by a MIT-style 3 | // license that can be found in the LICENSE file. 4 | // 5 | // Contact: Chenglu Jin at 6 | // 7 | // This is the main file of the software computation in LPN-based PUF FPGA 8 | // implementation. 9 | // 10 | // Includes 11 | #include 12 | #include 13 | #include "platform.h" 14 | #include "xuartps_hw.h" 15 | #include "xil_cache.h" 16 | #include "adc.h" 17 | #include "dac.h" 18 | #include "matrix.h" 19 | #include "lpn.h" 20 | #include 21 | 22 | // Defines 23 | #define SAMPLES_PER_FRAME 16 24 | #define DATA_CORRECT 0 25 | #define DATA_INCORRECT -1 26 | #define matrix_size 1800 27 | #define selected_matrix_size 512 28 | #define NUM_RO 450 29 | #define selected_ro 128 30 | 31 | // Main entry point 32 | int main() 33 | { 34 | int status; 35 | // Local variables 36 | adc_t* p_adc_inst; 37 | dac_t* p_dac_inst; 38 | bool combined_index[NUM_RO]; 39 | bool index_gen[NUM_RO]; 40 | bool index_ver[NUM_RO]; 41 | int rcv_buf[SAMPLES_PER_FRAME]; 42 | int test_send_buf[SAMPLES_PER_FRAME]; 43 | int b_vector[SAMPLES_PER_FRAME]; 44 | int hash_vector[SAMPLES_PER_FRAME]; 45 | int matrix_a[matrix_size]; 46 | int selected_matrix[selected_matrix_size]; 47 | int inv_matrix[selected_matrix_size]; 48 | int i; 49 | int j; 50 | int k; 51 | int ii = 0; 52 | 53 | // Setup UART and caches 54 | init_platform(); 55 | xil_printf("\fHello World!\n\r"); 56 | 57 | // Create ADC object 58 | p_adc_inst = adc_create 59 | ( 60 | XPAR_GPIO_0_DEVICE_ID, 61 | XPAR_AXIDMA_0_DEVICE_ID, 62 | XPAR_PS7_SCUGIC_0_DEVICE_ID, 63 | XPAR_FABRIC_DATAPATH_AXI_DMA_1_S2MM_INTROUT_INTR, 64 | XPAR_FABRIC_DATAPATH_AXI_DMA_1_MM2S_INTROUT_INTR, 65 | sizeof(int) 66 | ); 67 | if (p_adc_inst == NULL) 68 | { 69 | xil_printf("ERROR! Failed to create ADC instance.\n\r"); 70 | return DATA_INCORRECT; 71 | } 72 | 73 | // Create DAC object 74 | p_dac_inst = dac_create 75 | ( 76 | XPAR_GPIO_0_DEVICE_ID, 77 | XPAR_AXIDMA_0_DEVICE_ID, 78 | XPAR_PS7_SCUGIC_0_DEVICE_ID, 79 | XPAR_FABRIC_DATAPATH_AXI_DMA_1_S2MM_INTROUT_INTR, 80 | XPAR_FABRIC_DATAPATH_AXI_DMA_1_MM2S_INTROUT_INTR, 81 | sizeof(int) 82 | ); 83 | if (p_dac_inst == NULL) 84 | { 85 | xil_printf("ERROR! Failed to create DAC instance.\n\r"); 86 | return DATA_INCORRECT; 87 | } 88 | 89 | // Set the desired parameters for the ADC/DAC objects 90 | adc_set_bytes_per_sample(p_adc_inst, sizeof(int)); 91 | dac_set_bytes_per_sample(p_dac_inst, sizeof(int)); 92 | adc_set_samples_per_frame(p_adc_inst, SAMPLES_PER_FRAME); 93 | dac_set_samples_per_frame(p_dac_inst, SAMPLES_PER_FRAME); 94 | 95 | // Make sure the buffers are clear before we populate it (generally don't need to do this, but for proving the DMA working, we do it anyway) 96 | memset(rcv_buf, 0, SAMPLES_PER_FRAME*sizeof(int)); 97 | memset(test_send_buf, 0, SAMPLES_PER_FRAME*sizeof(int)); 98 | 99 | // Enable/initialize and dac 100 | adc_enable(p_adc_inst); 101 | dac_enable(p_dac_inst); 102 | 103 | //Generate Random Matrix A with size of 128 columns and 450 rows, each row is stored in four words. 104 | generate_random_matrix(matrix_a, matrix_size); 105 | 106 | // Process data 107 | for (ii = 0; 1; ii++) 108 | { 109 | xil_printf("**********************************************************************\n\r"); 110 | xil_printf("Run %d started.\n\r", ii); 111 | xil_printf("**********************************************************************\n\r"); 112 | 113 | 114 | xil_printf("CRP Geneneration.\n\r"); 115 | 116 | // Get new frame from ADC 117 | status = adc_get_frame(p_adc_inst, rcv_buf); 118 | if (status != ADC_SUCCESS) 119 | { 120 | xil_printf("ERROR! Failed to get a new frame of data from the POK.\n\r"); 121 | return DATA_INCORRECT; 122 | } 123 | // xil_printf("Got index\n\r"); 124 | 125 | convert_integer_to_bool (rcv_buf, index_gen); 126 | 127 | 128 | clean_index_gen (index_gen); 129 | 130 | 131 | for (i = 0; i < 113; i++) 132 | { 133 | // Send processed data frame out to DAC 134 | status = dac_send_frame(p_dac_inst, &matrix_a[i*16]); 135 | if (status != DAC_SUCCESS) 136 | { 137 | xil_printf("ERROR! Failed to send the processed data frame out to the DAC.\n\r"); 138 | return DATA_INCORRECT; 139 | } 140 | } 141 | 142 | // xil_printf("Sent A\n\r"); 143 | 144 | 145 | // Get new frame from ADC 146 | status = adc_get_frame(p_adc_inst, hash_vector); 147 | if (status != ADC_SUCCESS) 148 | { 149 | xil_printf("ERROR! Failed to get a new frame of data from the HASH.\n\r"); 150 | return DATA_INCORRECT; 151 | } 152 | 153 | // xil_printf("Got Hash\n\r"); 154 | 155 | 156 | 157 | status = dac_send_frame(p_dac_inst, test_send_buf); 158 | 159 | 160 | // Get new frame from ADC 161 | status = adc_get_frame(p_adc_inst, b_vector); 162 | 163 | 164 | if (status != ADC_SUCCESS) 165 | { 166 | xil_printf("ERROR! Failed to get a new frame of data from the B.\n\r"); 167 | return DATA_INCORRECT; 168 | } 169 | 170 | // xil_printf("Got B\n\r"); 171 | 172 | 173 | 174 | xil_printf("h1:"); 175 | 176 | for (i = 0; i < 8; i++) 177 | { 178 | xil_printf("%x", hash_vector[i]); 179 | } 180 | 181 | xil_printf("\n\rh0:"); 182 | 183 | for (i = 8; i < 16; i++) 184 | { 185 | xil_printf("%x", hash_vector[i]); 186 | } 187 | 188 | xil_printf("\n\rB:"); 189 | for (j = 0; j < 16; j++) 190 | { 191 | xil_printf("%x", b_vector[j]); 192 | } 193 | 194 | 195 | xil_printf("\n\r**********************************************************************\n\r"); 196 | xil_printf("Gen of Run %d is completed. Press any key to conduct Ver.\n\r", ii); 197 | xil_printf("**********************************************************************\n\r"); 198 | XUartPs_RecvByte(XPAR_PS7_UART_1_BASEADDR); 199 | 200 | //VERIFICATION 201 | xil_printf("CRP Verification.\n\r"); 202 | 203 | status = adc_get_frame(p_adc_inst, rcv_buf); 204 | if (status != ADC_SUCCESS) 205 | { 206 | xil_printf("ERROR! Failed to get a new frame of data from the POK.\n\r"); 207 | return DATA_INCORRECT; 208 | } 209 | // xil_printf("Got index\n\r"); 210 | 211 | convert_integer_to_bool (rcv_buf, index_ver); 212 | 213 | index_intersect (index_ver, index_gen, combined_index, 450, 128); 214 | 215 | status = DATA_INCORRECT; 216 | while (status) 217 | { 218 | status = skip_row_sel (index_ver, combined_index, 128); 219 | if (status == DATA_INCORRECT) 220 | { 221 | return DATA_INCORRECT; 222 | } 223 | else 224 | { 225 | select_matrix( matrix_a, selected_matrix, index_ver, 128, 450); 226 | 227 | reorder_matrix(selected_matrix); 228 | status = find_inverse_matrix(selected_matrix, inv_matrix); 229 | } 230 | } 231 | // xil_printf("Inverse A\n\r"); 232 | reorder_matrix(inv_matrix); 233 | 234 | convert_bool_to_integer (index_ver, test_send_buf); 235 | 236 | //send index 237 | status = dac_send_frame(p_dac_inst, test_send_buf); 238 | if (status != DAC_SUCCESS) 239 | { 240 | xil_printf("ERROR! Failed to send the index out to the DAC.\n\r"); 241 | return DATA_INCORRECT; 242 | } 243 | 244 | //send B 245 | status = dac_send_frame(p_dac_inst, b_vector); 246 | if (status != DAC_SUCCESS) 247 | { 248 | xil_printf("ERROR! Failed to send B out to the DAC.\n\r"); 249 | return DATA_INCORRECT; 250 | } 251 | // xil_printf("Sent B\n\r"); 252 | 253 | //inverse matrix 254 | for (i = 0; i < 32; i++) 255 | { 256 | status = dac_send_frame(p_dac_inst, &inv_matrix[i*16]); 257 | if (status != DAC_SUCCESS) 258 | { 259 | xil_printf("ERROR! Failed to send the inverse matrix out to the DAC.\n\r"); 260 | return DATA_INCORRECT; 261 | } 262 | } 263 | 264 | // xil_printf("Sent inverse matrix\n\r"); 265 | 266 | 267 | for (i = 0; i < 113; i++) 268 | { 269 | status = dac_send_frame(p_dac_inst, &matrix_a[i*16]); 270 | 271 | 272 | if (status != DAC_SUCCESS) 273 | { 274 | xil_printf("ERROR! Failed to send matrix a out to the DAC.\n\r"); 275 | return DATA_INCORRECT; 276 | } 277 | 278 | } 279 | 280 | // xil_printf("Sent matrix A\n\r"); 281 | 282 | for (k = 0; k < 8; k++) 283 | { 284 | test_send_buf[k] = hash_vector[k]; 285 | test_send_buf[k+8] = 0; 286 | } 287 | 288 | status = dac_send_frame(p_dac_inst, test_send_buf); 289 | if (status != DAC_SUCCESS) 290 | { 291 | xil_printf("ERROR! Failed to send hash out to the DAC.\n\r"); 292 | return DATA_INCORRECT; 293 | } 294 | // xil_printf("Sent h1\n\r"); 295 | 296 | status = adc_get_frame(p_adc_inst, rcv_buf); 297 | if (status != ADC_SUCCESS) 298 | { 299 | xil_printf("ERROR! Failed to get a new frame of data from the POK.\n\r"); 300 | return DATA_INCORRECT; 301 | } 302 | // xil_printf("Got hash\n\r"); 303 | 304 | 305 | xil_printf("ref response: "); 306 | for (k = 8; k < 16; k++) 307 | { 308 | xil_printf("%x", hash_vector[k]); 309 | } 310 | 311 | xil_printf("\n\rnew response: "); 312 | 313 | for (k = 8; k < 16; k++) 314 | { 315 | xil_printf("%x", rcv_buf[k]); 316 | } 317 | 318 | xil_printf("\n\r"); 319 | 320 | xil_printf("\n\r**********************************************************************\n\r"); 321 | xil_printf("Ver of Run %d is completed. Press any key to conduct the next run.\n\r", ii); 322 | xil_printf("Run %d is completed. Press any key to conduct the next run.\n\r", ii); 323 | xil_printf("**********************************************************************\n\r"); 324 | XUartPs_RecvByte(XPAR_PS7_UART_1_BASEADDR); 325 | } 326 | 327 | adc_destroy(p_adc_inst); 328 | dac_destroy(p_dac_inst); 329 | 330 | return DATA_CORRECT; 331 | } 332 | -------------------------------------------------------------------------------- /system/system_test.v: -------------------------------------------------------------------------------- 1 | // Copyright [2017] [Secure Computation Lab at UConn]. All rights reserved. 2 | // Use of this source code is governed by a MIT-style 3 | // license that can be found in the LICENSE file. 4 | // 5 | // Author: Chenglu Jin at 6 | // 7 | // This is the testbench for LPN core of the LPN-based PUF. 8 | // Please uncomment different test cases to test the system module. 9 | // Each test case has a short description on the top. 10 | // To run this testbench in ModelSim. 11 | // 1. Open ModelSim and enter the current directory. 12 | // 2. source tb.tcl in the console of ModelSim 13 | 14 | `timescale 1ns/1ns 15 | 16 | module system_tb; 17 | 18 | reg clk; 19 | reg resetn; 20 | reg mode; 21 | reg [127:0] data_in_TDATA; 22 | reg data_in_TVALID; 23 | wire data_in_TREADY; 24 | reg data_in_TLAST; 25 | wire [127:0] data_out_TDATA; 26 | wire data_out_TVALID; 27 | reg data_out_TREADY; 28 | wire data_out_TLAST; 29 | wire fault; 30 | reg global_start; 31 | parameter CP = 10; 32 | parameter r_referecen = {150{3'b101}}; 33 | 34 | reg [449:0] e; 35 | reg [449:0] r; 36 | reg pok_done; 37 | wire pok_resetn; 38 | reg [127:0] s_w; 39 | reg [127:0] identity; 40 | wire check_result; 41 | wire hash_result; 42 | 43 | system uut (clk, resetn, mode, data_in_TDATA, data_in_TVALID, data_in_TREADY, data_in_TLAST, data_out_TDATA, data_out_TVALID, data_out_TREADY, data_out_TLAST, fault, global_start, e, r, pok_done, pok_resetn, s_w, check_result, hash_result); 44 | 45 | always #(CP/2) 46 | clk = ~clk; 47 | 48 | initial 49 | begin 50 | clk = 1; 51 | resetn = 1; 52 | mode = 0; 53 | data_in_TDATA = {16{16'h5050}}; 54 | data_in_TVALID = 0; 55 | data_in_TLAST = 0; 56 | data_out_TREADY = 1; 57 | pok_done = 0; 58 | s_w = {128{1'b1}}; 59 | global_start = 0; 60 | identity = {1'b1, 127'b0}; 61 | 62 | #(CP*2) 63 | resetn = 0; 64 | 65 | #(CP*3) 66 | resetn = 1; 67 | 68 | //////////////////////////////////////// 69 | //GEN 70 | //for testing bit sel, bit exp 71 | // 72 | // #(CP*2) 73 | // global_start = 1; 74 | // s_w = {{126{1'b1}}, 2'b00}; 75 | // 76 | // # (CP*80) 77 | // pok_done = 1; 78 | // e = {150{3'b101}}; 79 | // r = {150{3'b101}}; 80 | // global_start = 0; 81 | // 82 | // //Sending A 83 | // #(CP*80) 84 | // data_in_TVALID = 1; 85 | // data_in_TDATA = {128{1'b1}}; 86 | // 87 | // #(CP*3) 88 | // data_in_TLAST = 1; 89 | // 90 | // #CP 91 | // data_in_TLAST = 0; 92 | // data_in_TVALID = 0; 93 | // 94 | // repeat (112) 95 | // begin 96 | // #(CP*10) 97 | // data_in_TVALID = 1; 98 | // 99 | // #(CP*3) 100 | // data_in_TLAST = 1; 101 | // 102 | // #CP 103 | // data_in_TLAST = 0; 104 | // data_in_TVALID = 0; 105 | // end 106 | // 107 | // #(CP*680) 108 | // data_in_TVALID = 1; 109 | // 110 | // #(CP*3) 111 | // data_in_TLAST = 1; 112 | // 113 | // #CP 114 | // data_in_TLAST = 0; 115 | // data_in_TVALID = 0; 116 | ///////////////////////////////////// 117 | 118 | //////////////////////////////////////// 119 | //GEN 120 | //for testing multiplication 121 | // 122 | // #(CP*2) 123 | // global_start = 1; 124 | // s_w = {{127{1'b1}}, 1'b0}; 125 | // //s_w = {{64{1'b1}}, {64{1'b0}}}; 126 | // 127 | // # (CP*80) 128 | // pok_done = 1; 129 | // e = {450{1'b0}}; 130 | // //e = {{127{1'b1}}, {323'b0}}; 131 | // r = {450{1'b1}}; 132 | // global_start = 0; 133 | // 134 | // //Sending A 135 | // #(CP*80) 136 | // data_in_TVALID = 1; 137 | // //data_in_TDATA = {16{16'h5055}}; 138 | // data_in_TDATA = {128{1'b1}}; 139 | // //data_in_TDATA = {{15{16'h5055}}, 16'h5054}; 140 | // //data_in_TDATA = {16'h5054, {15{16'h5055}}}; 141 | // 142 | // #(CP*3) 143 | // data_in_TLAST = 1; 144 | // 145 | // #CP 146 | // data_in_TLAST = 0; 147 | // data_in_TVALID = 0; 148 | // 149 | // repeat (112) 150 | // begin 151 | // #(CP*10) 152 | // data_in_TVALID = 1; 153 | // 154 | // #(CP*3) 155 | // data_in_TLAST = 1; 156 | // 157 | // #CP 158 | // data_in_TLAST = 0; 159 | // data_in_TVALID = 0; 160 | // end 161 | // 162 | // #(CP*680) 163 | // data_in_TVALID = 1; 164 | // 165 | // #(CP*3) 166 | // data_in_TLAST = 1; 167 | // 168 | // #CP 169 | // data_in_TLAST = 0; 170 | // data_in_TVALID = 0; 171 | ///////////////////////////////////// 172 | 173 | //////////////////////////////////// 174 | //GEN 175 | //for testing row sel with a different senario.Pay attention to state MUL_CAL_FIRST 176 | // 177 | // #(CP*2) 178 | // global_start = 1; 179 | // //s_w = {{126{1'b1}}, 2'b00}; 180 | // s_w = {{127{1'b1}}, 1'b0}; 181 | // 182 | // # (CP*80) 183 | // pok_done = 1; 184 | // //e = {150{3'b101}}; 185 | // e = {450{1'b0}}; 186 | // r = {{127{1'b1}}, 1'b0, {129{1'b1}}, {193{1'b0}}}; 187 | // //r = {450{1'b1}}; 188 | // global_start = 0; 189 | // 190 | // # (CP * 80) 191 | // //Sending A 192 | // identity = {1'b1, 127'b0}; 193 | // 194 | // repeat (32) 195 | // begin 196 | // #(CP*10) 197 | // data_in_TDATA = identity; 198 | // data_in_TVALID = 1; 199 | // identity = {1'b0, identity[127:1]}; 200 | // 201 | // #CP 202 | // data_in_TDATA = identity; 203 | // identity = {1'b0, identity[127:1]}; 204 | // 205 | // #CP 206 | // data_in_TDATA = identity; 207 | // identity = {1'b0, identity[127:1]}; 208 | // 209 | // #CP 210 | // data_in_TDATA = identity; 211 | // identity = {1'b0, identity[127:1]}; 212 | // data_in_TLAST = 1; 213 | // 214 | // #CP 215 | // data_in_TLAST = 0; 216 | // data_in_TVALID = 0; 217 | // end 218 | // 219 | // //sending A for the second time 220 | // identity = {1'b1, 127'b0}; 221 | // 222 | // repeat (81) 223 | // begin 224 | // #(CP*12) 225 | // data_in_TDATA = identity; 226 | // data_in_TVALID = 1; 227 | // identity = {1'b0, identity[127:1]}; 228 | // 229 | // #CP 230 | // data_in_TDATA = identity; 231 | // identity = {1'b0, identity[127:1]}; 232 | // 233 | // #CP 234 | // data_in_TDATA = identity; 235 | // identity = {1'b0, identity[127:1]}; 236 | // 237 | // #CP 238 | // data_in_TDATA = identity; 239 | // identity = {1'b0, identity[127:1]}; 240 | // data_in_TLAST = 1; 241 | // 242 | // #CP 243 | // data_in_TLAST = 0; 244 | // data_in_TVALID = 0; 245 | // end 246 | // 247 | // #(CP*740) 248 | // data_in_TVALID = 1; 249 | // 250 | // #(CP*3) 251 | // data_in_TLAST = 1; 252 | // 253 | // #CP 254 | // data_in_TLAST = 0; 255 | // data_in_TVALID = 0; 256 | //////////////////////////////////// 257 | 258 | //////////////////////////////////// 259 | //GEN 260 | //for testing the hash result, and comparing with ver. It sends identity matrix as a 261 | 262 | #(CP*2) 263 | global_start = 1; 264 | mode = 0; 265 | s_w = {{127{1'b1}}, 1'b0}; 266 | 267 | # (CP*80) 268 | pok_done = 1; 269 | e = {450{1'b0}}; 270 | r = {450{1'b1}}; 271 | global_start = 0; 272 | 273 | # (CP * 80) 274 | //Sending A 275 | identity = {1'b1, 127'b0}; 276 | 277 | repeat (32) 278 | begin 279 | #(CP*10) 280 | data_in_TDATA = identity; 281 | data_in_TVALID = 1; 282 | identity = {1'b0, identity[127:1]}; 283 | 284 | #CP 285 | data_in_TDATA = identity; 286 | identity = {1'b0, identity[127:1]}; 287 | 288 | #CP 289 | data_in_TDATA = identity; 290 | identity = {1'b0, identity[127:1]}; 291 | 292 | #CP 293 | data_in_TDATA = identity; 294 | identity = {1'b0, identity[127:1]}; 295 | data_in_TLAST = 1; 296 | 297 | #CP 298 | data_in_TLAST = 0; 299 | data_in_TVALID = 0; 300 | end 301 | 302 | //sending the second half of A 303 | identity = {128{1'b1}}; 304 | 305 | repeat (81) 306 | begin 307 | #(CP*10) 308 | data_in_TDATA = identity; 309 | data_in_TVALID = 1; 310 | identity = {1'b0, identity[127:1]}; 311 | 312 | #CP 313 | data_in_TDATA = identity; 314 | identity = {1'b0, identity[127:1]}; 315 | 316 | #CP 317 | data_in_TDATA = identity; 318 | identity = {1'b0, identity[127:1]}; 319 | 320 | #CP 321 | data_in_TDATA = identity; 322 | identity = {1'b0, identity[127:1]}; 323 | data_in_TLAST = 1; 324 | 325 | #CP 326 | data_in_TLAST = 0; 327 | data_in_TVALID = 0; 328 | end 329 | 330 | #(CP*740) 331 | data_in_TVALID = 1; 332 | 333 | #(CP*3) 334 | data_in_TLAST = 1; 335 | 336 | #CP 337 | data_in_TLAST = 0; 338 | data_in_TVALID = 0; 339 | //////////////////////////// 340 | 341 | ///////////////////////////////////////// 342 | ////ver 343 | #(CP*300) 344 | mode = 1; 345 | 346 | #(CP*5) 347 | global_start = 1; 348 | 349 | # (CP*30) 350 | pok_done = 1; 351 | //no error 352 | e = {450{1'b0}}; 353 | //inject one bit error 354 | //e = {{127{1'b0}}, 1'b1, 322'b0}; 355 | r = {450{1'b1}}; 356 | global_start = 0; 357 | 358 | //Sending I 359 | #(CP*100) 360 | data_in_TVALID = 1; 361 | data_in_TDATA = {128{1'b1}}; 362 | 363 | #(CP * 3) 364 | data_in_TLAST = 1; 365 | 366 | #CP 367 | data_in_TLAST = 0; 368 | data_in_TVALID = 0; 369 | 370 | //Sending B 371 | #(CP*30) 372 | data_in_TVALID = 1; 373 | data_in_TDATA = {{127{1'b1}}, 1'b0}; 374 | 375 | 376 | #(CP) 377 | data_in_TDATA = {{127{1'b1}}, 1'b0}; 378 | 379 | #(CP) 380 | data_in_TDATA = 128'b0; 381 | 382 | #(CP) 383 | data_in_TDATA = 128'b0; 384 | data_in_TLAST = 1; 385 | 386 | #CP 387 | data_in_TLAST = 0; 388 | data_in_TVALID = 0; 389 | 390 | identity = {1'b1, 127'b0}; 391 | //Sending A inverse 392 | repeat (32) 393 | begin 394 | #(CP*10) 395 | data_in_TDATA = identity; 396 | data_in_TVALID = 1; 397 | identity = {1'b0, identity[127:1]}; 398 | 399 | #CP 400 | data_in_TDATA = identity; 401 | identity = {1'b0, identity[127:1]}; 402 | 403 | #CP 404 | data_in_TDATA = identity; 405 | identity = {1'b0, identity[127:1]}; 406 | 407 | #CP 408 | data_in_TDATA = identity; 409 | identity = {1'b0, identity[127:1]}; 410 | data_in_TLAST = 1; 411 | 412 | #CP 413 | data_in_TLAST = 0; 414 | data_in_TVALID = 0; 415 | end 416 | 417 | //Sending matrix A 418 | identity = {1'b1, 127'b0}; 419 | 420 | repeat (32) 421 | begin 422 | #(CP*10) 423 | data_in_TDATA = identity; 424 | data_in_TVALID = 1; 425 | identity = {1'b0, identity[127:1]}; 426 | 427 | #CP 428 | data_in_TDATA = identity; 429 | identity = {1'b0, identity[127:1]}; 430 | 431 | #CP 432 | data_in_TDATA = identity; 433 | identity = {1'b0, identity[127:1]}; 434 | 435 | #CP 436 | data_in_TDATA = identity; 437 | identity = {1'b0, identity[127:1]}; 438 | data_in_TLAST = 1; 439 | 440 | #CP 441 | data_in_TLAST = 0; 442 | data_in_TVALID = 0; 443 | end 444 | 445 | //sending the second half of A 446 | identity = {1'b1, 127'b0}; 447 | 448 | repeat (81) 449 | begin 450 | #(CP*10) 451 | data_in_TDATA = identity; 452 | data_in_TVALID = 1; 453 | identity = {1'b0, identity[127:1]}; 454 | 455 | #CP 456 | data_in_TDATA = identity; 457 | identity = {1'b0, identity[127:1]}; 458 | 459 | #CP 460 | data_in_TDATA = identity; 461 | identity = {1'b0, identity[127:1]}; 462 | 463 | #CP 464 | data_in_TDATA = identity; 465 | identity = {1'b0, identity[127:1]}; 466 | data_in_TLAST = 1; 467 | 468 | #CP 469 | data_in_TLAST = 0; 470 | data_in_TVALID = 0; 471 | end 472 | 473 | //Sending hash 474 | #(CP*10) 475 | data_in_TDATA = 128'h68948e1511491e5bb4db1805b8b383e2; 476 | data_in_TVALID = 1; 477 | 478 | #CP 479 | data_in_TDATA = 128'h3076cbb4ec431728d0c526be0aebe0c0; 480 | //Correct output h0 for this h1 is f4724c09405df7179e55b7500383847f,68d7a569d05ee5d629f21584ba4e741d; 481 | 482 | #(CP) 483 | data_in_TDATA = 128'b0; 484 | 485 | #CP 486 | data_in_TLAST = 1; 487 | 488 | #CP 489 | data_in_TLAST = 0; 490 | data_in_TVALID = 0; 491 | ///////////////////////////////// 492 | end 493 | endmodule 494 | 495 | -------------------------------------------------------------------------------- /SW/dma_passthrough.c: -------------------------------------------------------------------------------- 1 | 2 | // Includes 3 | #include 4 | #include "xaxidma.h" 5 | #include "xscugic.h" 6 | #include "dma_passthrough.h" 7 | 8 | // Defines 9 | #define RESET_TIMEOUT_COUNTER 10000 10 | 11 | // Private data 12 | typedef struct dma_passthrough_periphs 13 | { 14 | XAxiDma dma_inst; 15 | XScuGic intc_inst; 16 | } dma_passthrough_periphs_t; 17 | 18 | typedef struct dma_passthrough 19 | { 20 | dma_passthrough_periphs_t periphs; 21 | void* p_rcv_buf; 22 | void* p_snd_buf; 23 | int buf_length; 24 | int sample_size_bytes; 25 | } dma_passthrough_t; 26 | 27 | static int g_s2mm_done = 0; 28 | static int g_mm2s_done = 0; 29 | static int g_dma_err = 0; 30 | 31 | // Private functions 32 | static void s2mm_isr(void* CallbackRef) 33 | { 34 | 35 | // Local variables 36 | u32 irq_status; 37 | int time_out; 38 | XAxiDma* p_dma_inst = (XAxiDma*)CallbackRef; 39 | 40 | // Disable interrupts 41 | XAxiDma_IntrDisable(p_dma_inst, XAXIDMA_IRQ_ALL_MASK, XAXIDMA_DMA_TO_DEVICE); 42 | XAxiDma_IntrDisable(p_dma_inst, XAXIDMA_IRQ_ALL_MASK, XAXIDMA_DEVICE_TO_DMA); 43 | 44 | // Read pending interrupts 45 | irq_status = XAxiDma_IntrGetIrq(p_dma_inst, XAXIDMA_DEVICE_TO_DMA); 46 | 47 | // Acknowledge pending interrupts 48 | XAxiDma_IntrAckIrq(p_dma_inst, irq_status, XAXIDMA_DEVICE_TO_DMA); 49 | 50 | // If no interrupt is asserted, we do not do anything 51 | if (!(irq_status & XAXIDMA_IRQ_ALL_MASK)) 52 | return; 53 | 54 | // If error interrupt is asserted, raise error flag, reset the 55 | // hardware to recover from the error, and return with no further 56 | // processing. 57 | if ((irq_status & XAXIDMA_IRQ_ERROR_MASK)) 58 | { 59 | 60 | g_dma_err = 1; 61 | 62 | // Reset should never fail for transmit channel 63 | XAxiDma_Reset(p_dma_inst); 64 | 65 | time_out = RESET_TIMEOUT_COUNTER; 66 | while (time_out) 67 | { 68 | if (XAxiDma_ResetIsDone(p_dma_inst)) 69 | break; 70 | 71 | time_out -= 1; 72 | } 73 | 74 | return; 75 | } 76 | 77 | // Completion interrupt asserted 78 | if (irq_status & XAXIDMA_IRQ_IOC_MASK) 79 | g_s2mm_done = 1; 80 | 81 | // Re-enable interrupts 82 | XAxiDma_IntrEnable(p_dma_inst, (XAXIDMA_IRQ_IOC_MASK | XAXIDMA_IRQ_ERROR_MASK), XAXIDMA_DMA_TO_DEVICE); 83 | XAxiDma_IntrEnable(p_dma_inst, (XAXIDMA_IRQ_IOC_MASK | XAXIDMA_IRQ_ERROR_MASK), XAXIDMA_DEVICE_TO_DMA); 84 | 85 | } 86 | 87 | static void mm2s_isr(void* CallbackRef) 88 | { 89 | 90 | // Local variables 91 | u32 irq_status; 92 | int time_out; 93 | XAxiDma* p_dma_inst = (XAxiDma*)CallbackRef; 94 | 95 | // Disable interrupts 96 | XAxiDma_IntrDisable(p_dma_inst, XAXIDMA_IRQ_ALL_MASK, XAXIDMA_DMA_TO_DEVICE); 97 | XAxiDma_IntrDisable(p_dma_inst, XAXIDMA_IRQ_ALL_MASK, XAXIDMA_DEVICE_TO_DMA); 98 | 99 | // Read pending interrupts 100 | irq_status = XAxiDma_IntrGetIrq(p_dma_inst, XAXIDMA_DMA_TO_DEVICE); 101 | 102 | // Acknowledge pending interrupts 103 | XAxiDma_IntrAckIrq(p_dma_inst, irq_status, XAXIDMA_DMA_TO_DEVICE); 104 | 105 | // If no interrupt is asserted, we do not do anything 106 | if (!(irq_status & XAXIDMA_IRQ_ALL_MASK)) 107 | return; 108 | 109 | // If error interrupt is asserted, raise error flag, reset the 110 | // hardware to recover from the error, and return with no further 111 | // processing. 112 | if (irq_status & XAXIDMA_IRQ_ERROR_MASK) 113 | { 114 | 115 | g_dma_err = 1; 116 | 117 | // Reset could fail and hang 118 | XAxiDma_Reset(p_dma_inst); 119 | 120 | time_out = RESET_TIMEOUT_COUNTER; 121 | 122 | while (time_out) 123 | { 124 | if (XAxiDma_ResetIsDone(p_dma_inst)) 125 | break; 126 | 127 | time_out -= 1; 128 | } 129 | 130 | return; 131 | } 132 | 133 | // If completion interrupt is asserted, then set RxDone flag 134 | if (irq_status & XAXIDMA_IRQ_IOC_MASK) 135 | g_mm2s_done = 1; 136 | 137 | // Re-enable interrupts 138 | XAxiDma_IntrEnable(p_dma_inst, (XAXIDMA_IRQ_IOC_MASK | XAXIDMA_IRQ_ERROR_MASK), XAXIDMA_DMA_TO_DEVICE); 139 | XAxiDma_IntrEnable(p_dma_inst, (XAXIDMA_IRQ_IOC_MASK | XAXIDMA_IRQ_ERROR_MASK), XAXIDMA_DEVICE_TO_DMA); 140 | 141 | } 142 | 143 | static int init_intc(XScuGic* p_intc_inst, int intc_device_id, XAxiDma* p_dma_inst, int s2mm_intr_id, int mm2s_intr_id) 144 | { 145 | 146 | // Local variables 147 | int status = 0; 148 | XScuGic_Config* cfg_ptr; 149 | 150 | // Look up hardware configuration for device 151 | cfg_ptr = XScuGic_LookupConfig(intc_device_id); 152 | if (!cfg_ptr) 153 | { 154 | xil_printf("ERROR! No hardware configuration found for Interrupt Controller with device id %d.\r\n", intc_device_id); 155 | return DMA_PASSTHROUGH_INTC_INIT_FAIL; 156 | } 157 | 158 | // Initialize driver 159 | status = XScuGic_CfgInitialize(p_intc_inst, cfg_ptr, cfg_ptr->CpuBaseAddress); 160 | if (status != XST_SUCCESS) 161 | { 162 | xil_printf("ERROR! Initialization of Interrupt Controller failed with %d.\r\n", status); 163 | return DMA_PASSTHROUGH_INTC_INIT_FAIL; 164 | } 165 | 166 | // Set interrupt priorities and trigger type 167 | XScuGic_SetPriorityTriggerType(p_intc_inst, s2mm_intr_id, 0xA0, 0x3); 168 | XScuGic_SetPriorityTriggerType(p_intc_inst, mm2s_intr_id, 0xA8, 0x3); 169 | 170 | // Connect handlers 171 | status = XScuGic_Connect(p_intc_inst, s2mm_intr_id, (Xil_InterruptHandler)s2mm_isr, p_dma_inst); 172 | if (status != XST_SUCCESS) 173 | { 174 | xil_printf("ERROR! Failed to connect s2mm_isr to the interrupt controller.\r\n", status); 175 | return DMA_PASSTHROUGH_INTC_INIT_FAIL; 176 | } 177 | status = XScuGic_Connect(p_intc_inst, mm2s_intr_id, (Xil_InterruptHandler)mm2s_isr, p_dma_inst); 178 | if (status != XST_SUCCESS) 179 | { 180 | xil_printf("ERROR! Failed to connect mm2s_isr to the interrupt controller.\r\n", status); 181 | return DMA_PASSTHROUGH_INTC_INIT_FAIL; 182 | } 183 | 184 | // Enable all interrupts 185 | XScuGic_Enable(p_intc_inst, s2mm_intr_id); 186 | XScuGic_Enable(p_intc_inst, mm2s_intr_id); 187 | 188 | // Initialize exception table and register the interrupt controller handler with exception table 189 | Xil_ExceptionInit(); 190 | Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, (Xil_ExceptionHandler)XScuGic_InterruptHandler, p_intc_inst); 191 | 192 | // Enable non-critical exceptions 193 | Xil_ExceptionEnable(); 194 | 195 | return DMA_PASSTHROUGH_SUCCESS; 196 | 197 | } 198 | 199 | static int init_dma(XAxiDma* p_dma_inst, int dma_device_id) 200 | { 201 | 202 | // Local variables 203 | int status = 0; 204 | XAxiDma_Config* cfg_ptr; 205 | 206 | // Look up hardware configuration for device 207 | cfg_ptr = XAxiDma_LookupConfig(dma_device_id); 208 | if (!cfg_ptr) 209 | { 210 | xil_printf("ERROR! No hardware configuration found for AXI DMA with device id %d.\r\n", dma_device_id); 211 | return DMA_PASSTHROUGH_DMA_INIT_FAIL; 212 | } 213 | 214 | // Initialize driver 215 | status = XAxiDma_CfgInitialize(p_dma_inst, cfg_ptr); 216 | if (status != XST_SUCCESS) 217 | { 218 | xil_printf("ERROR! Initialization of AXI DMA failed with %d\r\n", status); 219 | return DMA_PASSTHROUGH_DMA_INIT_FAIL; 220 | } 221 | 222 | // Test for Scatter Gather 223 | if (XAxiDma_HasSg(p_dma_inst)) 224 | { 225 | xil_printf("ERROR! Device configured as SG mode.\r\n"); 226 | return DMA_PASSTHROUGH_DMA_INIT_FAIL; 227 | } 228 | 229 | // Reset DMA 230 | XAxiDma_Reset(p_dma_inst); 231 | while (!XAxiDma_ResetIsDone(p_dma_inst)) {} 232 | 233 | // Enable DMA interrupts 234 | XAxiDma_IntrEnable(p_dma_inst, (XAXIDMA_IRQ_IOC_MASK | XAXIDMA_IRQ_ERROR_MASK), XAXIDMA_DMA_TO_DEVICE); 235 | XAxiDma_IntrEnable(p_dma_inst, (XAXIDMA_IRQ_IOC_MASK | XAXIDMA_IRQ_ERROR_MASK), XAXIDMA_DEVICE_TO_DMA); 236 | 237 | return DMA_PASSTHROUGH_SUCCESS; 238 | 239 | } 240 | 241 | // Public functions 242 | dma_passthrough_t* dma_passthrough_create(int dma_device_id, int intc_device_id, int s2mm_intr_id, 243 | int mm2s_intr_id, int sample_size_bytes) 244 | { 245 | 246 | // Local variables 247 | dma_passthrough_t* p_obj; 248 | int status; 249 | 250 | // Allocate memory for DMA Accelerator object 251 | p_obj = (dma_passthrough_t*) malloc(sizeof(dma_passthrough_t)); 252 | if (p_obj == NULL) 253 | { 254 | xil_printf("ERROR! Failed to allocate memory for DMA Passthrough object.\n\r"); 255 | return NULL; 256 | } 257 | 258 | // Register and initialize peripherals 259 | status = init_dma(&p_obj->periphs.dma_inst, dma_device_id); 260 | if (status != DMA_PASSTHROUGH_SUCCESS) 261 | { 262 | xil_printf("ERROR! Failed to initialize AXI DMA.\n\r"); 263 | dma_passthrough_destroy(p_obj); 264 | return NULL; 265 | } 266 | 267 | status = init_intc 268 | ( 269 | &p_obj->periphs.intc_inst, 270 | intc_device_id, 271 | &p_obj->periphs.dma_inst, 272 | s2mm_intr_id, 273 | mm2s_intr_id 274 | ); 275 | if (status != DMA_PASSTHROUGH_SUCCESS) 276 | { 277 | xil_printf("ERROR! Failed to initialize Interrupt controller.\n\r"); 278 | dma_passthrough_destroy(p_obj); 279 | return NULL; 280 | } 281 | 282 | // Initialize buffer pointers 283 | dma_passthrough_set_rcv_buf(p_obj, NULL); 284 | dma_passthrough_set_snd_buf(p_obj, NULL); 285 | 286 | // Initialize buffer length 287 | dma_passthrough_set_buf_length(p_obj, 1024); 288 | 289 | // Initialize sample size 290 | dma_passthrough_set_sample_size_bytes(p_obj, sample_size_bytes); 291 | 292 | return p_obj; 293 | 294 | } 295 | 296 | void dma_passthrough_destroy(dma_passthrough_t* p_dma_passthrough_inst) 297 | { 298 | free(p_dma_passthrough_inst); 299 | } 300 | 301 | void dma_passthrough_reset(dma_passthrough_t* p_dma_passthrough_inst) 302 | { 303 | XAxiDma_Reset(&p_dma_passthrough_inst->periphs.dma_inst); 304 | } 305 | 306 | void dma_passthrough_set_rcv_buf(dma_passthrough_t* p_dma_passthrough_inst, void* p_rcv_buf) 307 | { 308 | p_dma_passthrough_inst->p_rcv_buf = p_rcv_buf; 309 | } 310 | 311 | void* dma_passthrough_get_rcv_buf(dma_passthrough_t* p_dma_passthrough_inst) 312 | { 313 | return (p_dma_passthrough_inst->p_rcv_buf); 314 | } 315 | 316 | void dma_passthrough_set_snd_buf(dma_passthrough_t* p_dma_passthrough_inst, void* p_snd_buf) 317 | { 318 | p_dma_passthrough_inst->p_snd_buf = p_snd_buf; 319 | } 320 | 321 | void* dma_passthrough_get_snd_buf(dma_passthrough_t* p_dma_passthrough_inst) 322 | { 323 | return (p_dma_passthrough_inst->p_snd_buf); 324 | } 325 | 326 | void dma_passthrough_set_buf_length(dma_passthrough_t* p_dma_passthrough_inst, int buf_length) 327 | { 328 | p_dma_passthrough_inst->buf_length = buf_length; 329 | } 330 | 331 | int dma_passthrough_get_buf_length(dma_passthrough_t* p_dma_passthrough_inst) 332 | { 333 | return (p_dma_passthrough_inst->buf_length); 334 | } 335 | 336 | void dma_passthrough_set_sample_size_bytes(dma_passthrough_t* p_dma_passthrough_inst, int sample_size_bytes) 337 | { 338 | p_dma_passthrough_inst->sample_size_bytes = sample_size_bytes; 339 | } 340 | 341 | int dma_passthrough_get_sample_size_bytes(dma_passthrough_t* p_dma_passthrough_inst) 342 | { 343 | return (p_dma_passthrough_inst->sample_size_bytes); 344 | } 345 | 346 | int dma_passthrough_rcv(dma_passthrough_t* p_dma_passthrough_inst) 347 | { 348 | 349 | // Local variables 350 | int status = 0; 351 | const int num_bytes = p_dma_passthrough_inst->buf_length*p_dma_passthrough_inst->sample_size_bytes; 352 | 353 | // Flush cache 354 | #if (!DMA_PASSTHROUGH_IS_CACHE_COHERENT) 355 | Xil_DCacheFlushRange((int)p_dma_passthrough_inst->p_rcv_buf, num_bytes); 356 | #endif 357 | 358 | // Initialize control flags which get set by ISR 359 | g_s2mm_done = 0; 360 | g_dma_err = 0; 361 | 362 | // Enable interrupts 363 | XAxiDma_IntrEnable(&p_dma_passthrough_inst->periphs.dma_inst, (XAXIDMA_IRQ_IOC_MASK | XAXIDMA_IRQ_ERROR_MASK), XAXIDMA_DEVICE_TO_DMA); 364 | 365 | // Kick off S2MM transfer 366 | status = XAxiDma_SimpleTransfer 367 | ( 368 | &p_dma_passthrough_inst->periphs.dma_inst, 369 | (int)p_dma_passthrough_inst->p_rcv_buf, 370 | num_bytes, 371 | XAXIDMA_DEVICE_TO_DMA 372 | ); 373 | if (status != XST_SUCCESS) 374 | { 375 | xil_printf("ERROR! Failed to kick off S2MM transfer!\n\r"); 376 | return DMA_PASSTHROUGH_XFER_FAIL; 377 | } 378 | 379 | // Wait for transfer to complete 380 | while (!g_s2mm_done && !g_dma_err) { /* The processor could be doing something else here while waiting for an IRQ. */ } 381 | 382 | // Check DMA for errors 383 | if (g_dma_err) 384 | { 385 | xil_printf("ERROR! AXI DMA returned an error during the S2MM transfer.\n\r"); 386 | return DMA_PASSTHROUGH_XFER_FAIL; 387 | } 388 | 389 | return DMA_PASSTHROUGH_SUCCESS; 390 | 391 | } 392 | 393 | int dma_passthrough_snd(dma_passthrough_t* p_dma_passthrough_inst) 394 | { 395 | 396 | // Local variables 397 | int status = 0; 398 | const int num_bytes = p_dma_passthrough_inst->buf_length*p_dma_passthrough_inst->sample_size_bytes; 399 | 400 | // Flush cache 401 | #if (!DMA_PASSTHROUGH_IS_CACHE_COHERENT) 402 | Xil_DCacheFlushRange((int)p_dma_passthrough_inst->p_snd_buf, num_bytes); 403 | #endif 404 | 405 | // Initialize control flags which get set by ISR 406 | g_mm2s_done = 0; 407 | g_dma_err = 0; 408 | 409 | // Enable interrupts 410 | XAxiDma_IntrEnable(&p_dma_passthrough_inst->periphs.dma_inst, (XAXIDMA_IRQ_IOC_MASK | XAXIDMA_IRQ_ERROR_MASK), XAXIDMA_DMA_TO_DEVICE); 411 | 412 | // Kick off MM2S transfer 413 | status = XAxiDma_SimpleTransfer 414 | ( 415 | &p_dma_passthrough_inst->periphs.dma_inst, 416 | (int)p_dma_passthrough_inst->p_snd_buf, 417 | num_bytes, 418 | XAXIDMA_DMA_TO_DEVICE 419 | ); 420 | if (status != XST_SUCCESS) 421 | { 422 | xil_printf("ERROR! Failed to kick off MM2S transfer!\n\r"); 423 | return DMA_PASSTHROUGH_XFER_FAIL; 424 | } 425 | 426 | // Wait for transfer to complete 427 | while (!g_mm2s_done && !g_dma_err) { /* Could do something else here while waiting for an IRQ. */ } 428 | 429 | // Check DMA for errors 430 | if (g_dma_err) 431 | { 432 | xil_printf("ERROR! AXI DMA returned an error during the MM2S transfer.\n\r"); 433 | return DMA_PASSTHROUGH_XFER_FAIL; 434 | } 435 | 436 | return DMA_PASSTHROUGH_SUCCESS; 437 | 438 | } 439 | 440 | -------------------------------------------------------------------------------- /LPN_PUF_complete_test/lib/xilinx.com_user_tlast_gen_1.0/component.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | xilinx.com 4 | user 5 | tlast_gen 6 | 1.0 7 | 8 | 9 | m_axis 10 | 11 | 12 | 13 | 14 | 15 | 16 | TDATA 17 | 18 | 19 | m_axis_tdata 20 | 21 | 22 | 23 | 24 | TLAST 25 | 26 | 27 | m_axis_tlast 28 | 29 | 30 | 31 | 32 | TVALID 33 | 34 | 35 | m_axis_tvalid 36 | 37 | 38 | 39 | 40 | TREADY 41 | 42 | 43 | m_axis_tready 44 | 45 | 46 | 47 | 48 | 49 | s_axis 50 | 51 | 52 | 53 | 54 | 55 | 56 | TDATA 57 | 58 | 59 | s_axis_tdata 60 | 61 | 62 | 63 | 64 | TVALID 65 | 66 | 67 | s_axis_tvalid 68 | 69 | 70 | 71 | 72 | TREADY 73 | 74 | 75 | s_axis_tready 76 | 77 | 78 | 79 | 80 | 81 | resetn 82 | 83 | 84 | 85 | 86 | 87 | 88 | RST 89 | 90 | 91 | resetn 92 | 93 | 94 | 95 | 96 | 97 | POLARITY 98 | ACTIVE_LOW 99 | 100 | 101 | 102 | 103 | aclk 104 | 105 | 106 | 107 | 108 | 109 | 110 | CLK 111 | 112 | 113 | aclk 114 | 115 | 116 | 117 | 118 | 119 | ASSOCIATED_BUSIF 120 | m_axis:s_axis 121 | 122 | 123 | ASSOCIATED_RESET 124 | resetn 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | xilinx_anylanguagesynthesis 133 | Synthesis 134 | :vivado.xilinx.com:synthesis 135 | tlast_gen 136 | 137 | xilinx_anylanguagesynthesis_view_fileset 138 | 139 | 140 | 141 | viewChecksum 142 | 539ac19f 143 | 144 | 145 | 146 | 147 | xilinx_anylanguagebehavioralsimulation 148 | Simulation 149 | :vivado.xilinx.com:simulation 150 | tlast_gen 151 | 152 | xilinx_anylanguagebehavioralsimulation_view_fileset 153 | 154 | 155 | 156 | viewChecksum 157 | 539ac19f 158 | 159 | 160 | 161 | 162 | xilinx_xpgui 163 | UI Layout 164 | :vivado.xilinx.com:xgui.ui 165 | 166 | xilinx_xpgui_view_fileset 167 | 168 | 169 | 170 | viewChecksum 171 | 914935cd 172 | 173 | 174 | 175 | 176 | 177 | 178 | aclk 179 | 180 | in 181 | 182 | 183 | std_logic 184 | xilinx_anylanguagesynthesis 185 | xilinx_anylanguagebehavioralsimulation 186 | 187 | 188 | 189 | 190 | 191 | resetn 192 | 193 | in 194 | 195 | 196 | std_logic 197 | xilinx_anylanguagesynthesis 198 | xilinx_anylanguagebehavioralsimulation 199 | 200 | 201 | 202 | 203 | 204 | pkt_length 205 | 206 | in 207 | 208 | 8 209 | 0 210 | 211 | 212 | 213 | std_logic_vector 214 | xilinx_anylanguagesynthesis 215 | xilinx_anylanguagebehavioralsimulation 216 | 217 | 218 | 219 | 220 | 221 | s_axis_tvalid 222 | 223 | in 224 | 225 | 226 | std_logic 227 | xilinx_anylanguagesynthesis 228 | xilinx_anylanguagebehavioralsimulation 229 | 230 | 231 | 232 | 233 | 234 | s_axis_tready 235 | 236 | out 237 | 238 | 239 | std_logic 240 | xilinx_anylanguagesynthesis 241 | xilinx_anylanguagebehavioralsimulation 242 | 243 | 244 | 245 | 246 | 247 | s_axis_tdata 248 | 249 | in 250 | 251 | 7 252 | 0 253 | 254 | 255 | 256 | std_logic_vector 257 | xilinx_anylanguagesynthesis 258 | xilinx_anylanguagebehavioralsimulation 259 | 260 | 261 | 262 | 263 | 264 | m_axis_tvalid 265 | 266 | out 267 | 268 | 269 | std_logic 270 | xilinx_anylanguagesynthesis 271 | xilinx_anylanguagebehavioralsimulation 272 | 273 | 274 | 275 | 276 | 277 | m_axis_tready 278 | 279 | in 280 | 281 | 282 | std_logic 283 | xilinx_anylanguagesynthesis 284 | xilinx_anylanguagebehavioralsimulation 285 | 286 | 287 | 288 | 289 | 290 | m_axis_tlast 291 | 292 | out 293 | 294 | 295 | std_logic 296 | xilinx_anylanguagesynthesis 297 | xilinx_anylanguagebehavioralsimulation 298 | 299 | 300 | 301 | 302 | 303 | m_axis_tdata 304 | 305 | out 306 | 307 | 7 308 | 0 309 | 310 | 311 | 312 | std_logic_vector 313 | xilinx_anylanguagesynthesis 314 | xilinx_anylanguagebehavioralsimulation 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | TDATA_WIDTH 323 | Tdata Width 324 | 8 325 | 326 | 327 | MAX_PKT_LENGTH 328 | Max Pkt Length 329 | 256 330 | 331 | 332 | 333 | 334 | 335 | choices_0 336 | ACTIVE_HIGH 337 | ACTIVE_LOW 338 | 339 | 340 | 341 | 342 | xilinx_anylanguagesynthesis_view_fileset 343 | 344 | tlast_gen.v 345 | verilogSource 346 | CHECKSUM_539ac19f 347 | 348 | 349 | 350 | xilinx_anylanguagebehavioralsimulation_view_fileset 351 | 352 | tlast_gen.v 353 | verilogSource 354 | 355 | 356 | 357 | xilinx_xpgui_view_fileset 358 | 359 | xgui/tlast_gen_v1_0.tcl 360 | tclSource 361 | XGUI_VERSION_2 362 | CHECKSUM_914935cd 363 | 364 | 365 | 366 | tlast_gen_v1_0 367 | 368 | 369 | TDATA_WIDTH 370 | Tdata Width 371 | 8 372 | 373 | 374 | MAX_PKT_LENGTH 375 | Max Pkt Length 376 | 256 377 | 378 | 379 | Component_Name 380 | tlast_gen_v1_0 381 | 382 | 383 | 384 | 385 | 386 | virtex7 387 | qvirtex7 388 | kintex7 389 | kintex7l 390 | qkintex7 391 | qkintex7l 392 | artix7 393 | artix7l 394 | aartix7 395 | qartix7 396 | zynq 397 | qzynq 398 | azynq 399 | virtexu 400 | kintexu 401 | 402 | 403 | /UserIP 404 | 405 | tlast_gen_v1_0 406 | 2 407 | 2015-07-01T16:41:54Z 408 | 409 | /group/bcapps/bwiec/tmp/dma_ex_updaters/new_ips/project_1/project_1.srcs/sources_1/imports/new_ips 410 | 411 | 412 | 413 | 2015.1 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | -------------------------------------------------------------------------------- /system/system.v: -------------------------------------------------------------------------------- 1 | // Copyright [2017] [Secure Computation Lab at UConn]. All rights reserved. 2 | // Use of this source code is governed by a MIT-style 3 | // license that can be found in the LICENSE file. 4 | // 5 | // Author: Chenglu Jin at 6 | // 7 | // This is the LPN core of the LPN-based PUF. 8 | // It contains the state machine, inverse matrix checker, hash checker and the 9 | // second register array for storing the 128*128 inverse matrix. 10 | 11 | `define AXI_REC 2'b00 12 | `define AXI_SEN 2'b01 13 | `define LOC_RD 2'b10 14 | `define LOC_WR 2'b11 15 | 16 | `define IDLE 5'h00 17 | `define RUN_POK 5'h01 18 | `define WR_POK_GEN 5'h02 19 | `define SEND_CO 5'h03 20 | `define REC_I 5'h04 21 | `define RD_I 5'h05 22 | `define REC_HASH 5'h06 23 | `define RD_HASH 5'h07 24 | `define REC_B 5'h08 25 | `define RD_B 5'h09 26 | `define REC_A1 5'h0A 27 | `define RD_A1 5'h0B 28 | `define REC_A 5'h0C 29 | `define RD_A 5'h0D 30 | `define BIT_SEL 5'h0E 31 | `define MUL_CAL 5'h10 32 | `define HASH1 5'h11 33 | `define HASH2 5'h12 34 | `define WR_HASH1 5'h13 35 | `define SEND_HASH 5'h14 36 | `define WR_POK_VER 5'h15 37 | `define BIT_EXP 5'h16 38 | `define WR_B 5'h17 39 | `define SEND_B 5'h18 40 | `define MUL_CAL_FIRST 5'h19 41 | `define WR_HASH2 5'h1A 42 | `define RED_RD 5'h1B 43 | 44 | `define GEN 1'b0 45 | `define VER 1'b1 46 | 47 | module system (clk, resetn, mode, data_in_TDATA, data_in_TVALID, data_in_TREADY, data_in_TLAST, data_out_TDATA, data_out_TVALID, data_out_TREADY, data_out_TLAST, fault, global_start ,e , r, pok_done, pok_resetn, s_w , check_result, hash_result); 48 | 49 | input clk; 50 | input resetn; 51 | input mode; 52 | input [127:0] data_in_TDATA; 53 | input data_in_TVALID; 54 | output data_in_TREADY; 55 | input data_in_TLAST; 56 | output [127:0] data_out_TDATA; 57 | output data_out_TVALID; 58 | input data_out_TREADY; 59 | output data_out_TLAST; 60 | output fault; 61 | input global_start; 62 | input [449:0] e; 63 | input [449:0] r; 64 | input pok_done; 65 | output reg pok_resetn; 66 | input [127:0] s_w; 67 | //debugging 68 | output check_result; 69 | output hash_result; 70 | 71 | //FSM 72 | reg [8:0] state; 73 | reg [8:0] cnt; 74 | reg [8:0] global_cnt; 75 | reg done_half; 76 | reg global_start_track; 77 | reg a_inverse_read; 78 | reg [1:0] mul_cnt; 79 | 80 | //Comm 81 | wire read_en; 82 | wire [127:0] comm_read_data; 83 | wire read_en_2; 84 | wire [449:0] comm_read_data_2; 85 | wire write_en; 86 | wire [127:0] comm_write_data; 87 | wire write_en_2; 88 | wire [449:0] comm_write_data_2; 89 | reg [1:0] op_mode; 90 | 91 | //bit sel for e 92 | reg bit_sel_e_en; 93 | wire bit_sel_e_start; 94 | wire [8:0] number_select; 95 | wire [255:0] selected_e; 96 | wire bit_sel_e_done; 97 | wire [449:0] bit_sel_index_w; 98 | 99 | //bit sel for b 100 | reg bit_sel_b_en; 101 | wire bit_sel_b_load_index; 102 | wire bit_sel_b_load_b; 103 | wire [449:0] received_b; 104 | wire [127:0] selected_b; 105 | wire bit_sel_b_done; 106 | 107 | //row sel 108 | wire row_sel_index_valid; 109 | wire [449:0] row_sel_index; 110 | wire row_sel_read_in; 111 | wire [16383:0] selected_matrix; 112 | wire matrix_shift_en; 113 | wire [127:0] matrix_shift_out; 114 | wire row_sel_done; 115 | wire row_sel_half_way_done; 116 | 117 | //hash function 118 | wire [255:0] H_0; 119 | reg [511:0] hash_msg; 120 | reg hash_input_valid; 121 | wire [255:0] hash_output; 122 | wire hash_done; 123 | wire hash_en; 124 | reg hash_reset; 125 | reg [449:0] full_b; 126 | 127 | //bit expansion 128 | wire bit_exp_done; 129 | wire [449:0] b; 130 | reg bit_exp_en; 131 | wire bit_exp_index_valid; 132 | wire bit_exp_read_short_b; 133 | wire [127:0] bit_exp_short_b; 134 | 135 | //matrix multiplier 136 | wire [16383:0] mul_matrix; 137 | reg [127:0] mul_vector; 138 | wire [127:0] noise_vector; 139 | wire [127:0] mul_output; 140 | reg [16383:0] a_inverse; 141 | 142 | //identity matrix checker 143 | reg [127:0] check_ref; 144 | reg [8:0] check_cnt; 145 | wire check_done; 146 | reg check_result; 147 | 148 | //hash checker 149 | reg [255:0] hash_ref; 150 | reg [127:0] possible_error; 151 | reg hash_result; 152 | reg [8:0] hash_check_cnt; 153 | wire hash_comp; 154 | 155 | assign fault = check_result | hash_result; 156 | 157 | //communication 158 | comm_buf comm_buf (.clk(clk), .resetn(resetn), .data_in_TDATA(data_in_TDATA), .data_in_TVALID(data_in_TVALID), .data_in_TREADY(data_in_TREADY), .data_in_TLAST(data_in_TLAST), .data_out_TDATA(data_out_TDATA), .data_out_TVALID(data_out_TVALID), .data_out_TREADY(data_out_TREADY), .data_out_TLAST(data_out_TLAST), .read_en(read_en), .read_data(comm_read_data), .read2_en(read_en_2), .read2_data(comm_read_data_2), .write_en(write_en), .write_data(comm_write_data), .write2_en(write_en_2), .write2_data(comm_write_data_2), .data_received(data_received), .data_sent(data_sent), .op_mode(op_mode)); 159 | 160 | always @ (*) 161 | begin 162 | case(state) 163 | `WR_POK_GEN: 164 | op_mode <= `LOC_WR; 165 | 166 | `SEND_CO: 167 | op_mode <= `AXI_SEN; 168 | 169 | `REC_I: 170 | op_mode <= `AXI_REC; 171 | 172 | `RD_I: 173 | op_mode <= `LOC_RD; 174 | 175 | `REC_HASH: 176 | op_mode <= `AXI_REC; 177 | 178 | `RD_HASH: 179 | op_mode <= `LOC_RD; 180 | 181 | `REC_B: 182 | op_mode <= `AXI_REC; 183 | 184 | `RD_B: 185 | op_mode <= `LOC_RD; 186 | 187 | `REC_A1: 188 | op_mode <= `AXI_REC; 189 | 190 | `RD_A1: 191 | op_mode <= `LOC_RD; 192 | 193 | `WR_HASH1: 194 | op_mode <= `LOC_WR; 195 | 196 | `WR_HASH2: 197 | op_mode <= `LOC_WR; 198 | 199 | `SEND_HASH: 200 | op_mode <= `AXI_SEN; 201 | 202 | `WR_POK_VER: 203 | op_mode <= `LOC_WR; 204 | 205 | `WR_B: 206 | op_mode <= `LOC_WR; 207 | 208 | `SEND_B: 209 | op_mode <= `AXI_SEN; 210 | 211 | `REC_A: 212 | op_mode <= `AXI_REC; 213 | 214 | `RD_A: 215 | op_mode <= `LOC_RD; 216 | 217 | `RED_RD: 218 | op_mode <= `AXI_REC; 219 | 220 | default: 221 | op_mode <= `LOC_RD; 222 | endcase 223 | end 224 | assign write_en_2 = (state == `WR_POK_GEN || state == `WR_POK_VER || state == `WR_B) ? 1'b1 : 1'b0; 225 | assign write_en = (state == `WR_HASH1 || state == `WR_HASH2) ? 1'b1 : 1'b0; 226 | assign comm_write_data_2 = (state == `WR_POK_GEN || state == `WR_POK_VER) ? r : b; 227 | assign read_en = ((state == `RD_A && row_sel_half_way_done == 1'b0 && mode == `GEN) || (state == `RD_A && mode == `VER)|| state == `RD_HASH || state == `RD_A1) ? 1'b1 : 1'b0; 228 | assign comm_write_data = (cnt == 0) ? hash_output[255:128] : hash_output[127:0]; 229 | assign read_en_2 = (state == `RD_I || state == `RD_B) ? 1'b1 : 1'b0; 230 | 231 | //bit_sel for e 232 | bit_sel bit_sel_e (.clk(clk), .resetn(resetn), .en(bit_sel_e_en), .number_select(number_select), .start(bit_sel_e_start), .e_w(e), .index_w(bit_sel_index_w), .selected_e(selected_e), .done(bit_sel_e_done)); 233 | assign bit_sel_e_start = (state == `WR_POK_GEN || state == `RD_I) ? 1'b1 : 1'b0; 234 | assign number_select = (mode == `GEN)? 9'd256 : 9'd128; 235 | assign bit_sel_index_w = (mode == `GEN) ? r : comm_read_data_2; 236 | 237 | //bit_sel for b 238 | bit_sel_b bit_sel_b (.clk(clk), .resetn(resetn), .en(bit_sel_b_en), .load_index(bit_sel_b_load_index), .load_b(bit_sel_b_load_b) , .b_w(received_b), .index_w(bit_sel_index_w), .selected_b(selected_b), .done(bit_sel_b_done)); 239 | assign bit_sel_b_load_index = (state == `RD_I) ? 1'b1 : 1'b0; 240 | assign bit_sel_b_load_b = (state == `RD_B) ? 1'b1 : 1'b0; 241 | assign received_b = comm_read_data_2; 242 | 243 | //row sel 244 | row_sel row_sel (.clk(clk), .resetn(resetn), .en(row_sel_en), .index_valid(row_sel_index_valid),.read_in(row_sel_read_in), .row_input(comm_read_data), .index_w(bit_sel_index_w), .number_select(number_select), .selected_matrix(selected_matrix), .shift_en(matrix_shift_en), .shift_out(matrix_shift_out), .done(row_sel_done), .half_way_done(row_sel_half_way_done)); 245 | assign row_sel_en = ((state == `RD_A) && (row_sel_done == 1'b0 || done_half == 1'b1)) ? 1'b1 : 1'b0; 246 | assign row_sel_index_valid = (state == `WR_POK_GEN || state == `RD_I)? 1'b1 : 1'b0; 247 | assign matrix_shift_en = (row_sel_done == 1'b1 && check_done == 1'b0 && mode == `VER)? 1'b1 : 1'b0; 248 | assign row_sel_read_in = (state == `RD_A1 && cnt <9'h4) ? 1'b1 : 1'b0; 249 | 250 | //matrix multiplier 251 | matrix_mul matrix_mul (.clk(clk), .resetn(resetn), .a(mul_matrix), .b(mul_vector), .e(noise_vector), .o(mul_output)); 252 | always @ (posedge clk or negedge resetn) 253 | if (!resetn) 254 | mul_vector <= 128'h0 ; 255 | else if (state == `IDLE) 256 | mul_vector <= 128'h0; 257 | else if (row_sel_done == 1'b1 && check_done == 1'b0 && mode == `VER) 258 | mul_vector <= matrix_shift_out; 259 | else if (state == `RD_A && mode == `GEN && global_cnt == 9'd30) 260 | mul_vector <= s_w; 261 | else if (mode == `VER && state == `RD_A) 262 | mul_vector <= selected_e[127:0] ^ selected_b ^ possible_error; 263 | else if (mode == `VER && state == `HASH1 && hash_done == 1'b1 && hash_comp == 1'b1) 264 | mul_vector <= selected_e[127:0] ^ selected_b ^ possible_error; 265 | else 266 | mul_vector <= mul_vector; 267 | 268 | assign noise_vector = (mode == `VER)? 128'b0: (state == `MUL_CAL_FIRST)? selected_e[255:128] : selected_e[127:0]; 269 | assign mul_matrix = a_inverse; 270 | 271 | always @ (posedge clk or negedge resetn) 272 | if (!resetn) 273 | a_inverse <= 16384'b0; 274 | else if (a_inverse_read) 275 | a_inverse <= selected_matrix; 276 | else 277 | a_inverse <= a_inverse; 278 | 279 | //identity matrix checker 280 | always @ (posedge clk or negedge resetn) 281 | if (!resetn) 282 | check_ref <= 128'b1; 283 | else if (state == `IDLE) 284 | check_ref <= 128'b1; 285 | else if (mode == `VER && row_sel_done && check_cnt > 2'h1 && (state == `RD_A || state == `REC_A || state == `MUL_CAL || state == `REC_HASH || state == `RD_HASH || state == `HASH1 || state == `WR_HASH1)) 286 | check_ref <= {check_ref[126:0], 1'b0}; 287 | else 288 | check_ref <= check_ref; 289 | 290 | always @ (posedge clk or negedge resetn) 291 | if (!resetn) 292 | check_cnt <= 9'b0; 293 | else if (state == `IDLE) 294 | check_cnt <= 9'b0; 295 | else if (check_cnt == 9'd129 && mode == `VER) 296 | check_cnt <= check_cnt; 297 | else if (mode == `VER && row_sel_done && (state == `RD_A || state == `REC_A || state == `MUL_CAL || state == `REC_HASH || state == `RD_HASH || state == `HASH1 || state == `WR_HASH1)) 298 | check_cnt <= check_cnt + 1'b1; 299 | else 300 | check_cnt <= check_cnt; 301 | 302 | assign check_done = (check_cnt == 9'd129) ? 1'b1 : 1'b0; 303 | 304 | always @ (posedge clk or negedge resetn) 305 | if (!resetn) 306 | check_result <= 1'b0; 307 | else if (state == `IDLE && global_start_track == 1'b0 && global_start == 1'b1) 308 | check_result <= 1'b0; 309 | else if (mode == `VER && row_sel_done && check_cnt > 1'b1 && mul_output != check_ref && check_done == 1'b0 && (state == `RD_A || state == `REC_A || state == `MUL_CAL || state == `REC_HASH || state == `RD_HASH || state == `HASH1 || state == `WR_HASH1)) 310 | check_result <= 1'b1; 311 | else 312 | check_result <= check_result; 313 | 314 | //hash checker 315 | always @ (posedge clk or negedge resetn) 316 | if (!resetn) 317 | hash_ref <= 256'b0; 318 | else if (state == `RD_HASH && cnt < 9'h2) 319 | hash_ref <= {hash_ref[127:0], comm_read_data}; 320 | else 321 | hash_ref <= hash_ref; 322 | 323 | always @ (posedge clk or negedge resetn) 324 | if (!resetn) 325 | hash_check_cnt <= 9'b0; 326 | else if (state == `IDLE) 327 | hash_check_cnt <= 9'b0; 328 | else if (hash_comp == 1'b1 && hash_done == 1'b1 && state == `HASH1 && mode == `VER) 329 | hash_check_cnt <= hash_check_cnt + 1'b1; 330 | else 331 | hash_check_cnt <= hash_check_cnt; 332 | 333 | assign hash_comp = (hash_output == hash_ref)? 1'b0 : 1'b1; 334 | 335 | always @ (posedge clk or negedge resetn) 336 | if (!resetn) 337 | hash_result <= 1'b0; 338 | else if (state == `IDLE && global_start_track == 1'b0 && global_start == 1'b1) 339 | hash_result <= 1'b0; 340 | else if (hash_comp == 1'b1 && hash_check_cnt == 9'd128) 341 | hash_result <= 1'b1; 342 | else 343 | hash_result <= hash_result; 344 | 345 | always @ (posedge clk or negedge resetn) 346 | if (!resetn) 347 | possible_error <= 128'b0; 348 | else if (state == `IDLE) 349 | possible_error <= 128'b0; 350 | else if (hash_check_cnt == 9'b0) 351 | possible_error <= 128'b0; 352 | else if (hash_check_cnt == 9'b1) 353 | possible_error <= 128'b1; 354 | else if (state == `HASH1 && cnt == 9'h0 && hash_comp == 1'b1 && mode == `VER && hash_done == 1'b1) 355 | possible_error <= {possible_error [126:0], 1'b0}; 356 | else 357 | possible_error <= possible_error; 358 | 359 | //bit expansion 360 | bit_expand bit_expand (.clk(clk), .resetn(resetn), .en(bit_exp_en), .index_valid(bit_exp_index_valid), .index(r), .read_short_b(bit_exp_read_short_b), .short_b(bit_exp_short_b), .expanded_b(b), .done(bit_exp_done)); 361 | assign bit_exp_index_valid = row_sel_index_valid; 362 | assign bit_exp_read_short_b = ((state == `MUL_CAL_FIRST || state ==`MUL_CAL) && (mul_cnt == 2'h2) && (mode == `GEN))? 1'b1 : 1'b0; 363 | assign bit_exp_short_b = mul_output; 364 | always @ (posedge clk or negedge resetn) 365 | if (!resetn) 366 | bit_exp_en <= 1'b0; 367 | else if (state == `BIT_EXP) 368 | bit_exp_en <= 1'b1; 369 | else if (state == `HASH1) 370 | bit_exp_en <= 1'b0; 371 | else 372 | bit_exp_en <= bit_exp_en; 373 | 374 | //hash 375 | sha256_block hash (.clk(clk), .rst(hash_reset), .H_in(H_0), .M_in(hash_msg), .input_valid(hash_input_valid), .en(hash_en), .H_out(hash_output), .output_valid(hash_done)); 376 | sha256_H_0 sha256_initial (.H_0(H_0)); 377 | assign hash_en = (state == `RD_A || state == `MUL_CAL || state == `HASH1 || state == `HASH2 || state == `BIT_EXP || state == `WR_HASH1) ? 1'b1 : 1'b0; 378 | always @ (*) 379 | case(state) 380 | `RD_A: 381 | hash_input_valid <= 1'b1; 382 | 383 | `HASH1: 384 | if (cnt < 9'h2) 385 | hash_input_valid <= 1'b1; 386 | else 387 | hash_input_valid <= 1'b0; 388 | 389 | `HASH2: 390 | if (cnt < 9'h2) 391 | hash_input_valid <= 1'b1; 392 | else 393 | hash_input_valid <= 1'b0; 394 | 395 | default : 396 | hash_input_valid <= 1'b0; 397 | endcase 398 | 399 | always @ (*) 400 | case(state) 401 | `RD_A: 402 | hash_msg <= {comm_read_data, 384'h0}; 403 | 404 | `HASH1: 405 | if (mode == `GEN && cnt == 9'h0) 406 | hash_msg <= {b, 62'h0}; 407 | else if (mode == `GEN && cnt == 9'h1) 408 | hash_msg <= {mul_vector, 384'h1}; 409 | else if (mode == `VER && cnt == 9'h0) 410 | hash_msg <= {full_b, 62'h0}; 411 | else 412 | hash_msg <= {mul_output, 384'h1}; 413 | 414 | `HASH2: 415 | if (mode == `GEN && cnt == 9'h0) 416 | hash_msg <= {b, 62'h0}; 417 | else if (mode == `GEN && cnt == 9'h1) 418 | hash_msg <= {mul_vector, 384'h0}; 419 | else if (mode == `VER && cnt == 9'h0) 420 | hash_msg <= {full_b, 62'h0}; 421 | else 422 | hash_msg <= {mul_output, 384'h0}; 423 | 424 | default: 425 | hash_msg <= {comm_read_data, 384'h0}; 426 | endcase 427 | 428 | always @ (posedge clk or negedge resetn) 429 | if (!resetn) 430 | full_b <= 450'b0; 431 | else if (state == `IDLE) 432 | full_b <= 450'b0; 433 | else if (state == `RD_B) 434 | full_b <= comm_read_data_2; 435 | else 436 | full_b <= full_b; 437 | 438 | always @ (posedge clk or negedge resetn) 439 | if (!resetn) 440 | global_start_track <= 1'b0; 441 | else 442 | global_start_track <= global_start; 443 | 444 | //FSM 445 | always @ (posedge clk or negedge resetn) 446 | begin 447 | if (!resetn) 448 | begin 449 | //reset all the registers here 450 | state <= `IDLE; 451 | cnt <= 9'h00; 452 | pok_resetn <= 1'b1; 453 | end 454 | else 455 | begin 456 | case (state) 457 | `IDLE: 458 | begin 459 | if (global_start_track == 1'b0 && global_start == 1'b1) // a rising edge of global_start 460 | begin 461 | cnt <= 9'h00; 462 | pok_resetn <= 1'b1; 463 | state <= `RUN_POK; 464 | bit_sel_e_en <= 1'b0; 465 | bit_sel_b_en <= 1'b0; 466 | global_cnt <= 9'h000; 467 | done_half <= 1'b0; 468 | hash_reset <= 1'b1; 469 | a_inverse_read <= 1'b0; 470 | mul_cnt <= 2'b0; 471 | end 472 | else 473 | state <= state; 474 | end 475 | 476 | `RUN_POK: 477 | begin 478 | if (cnt == 9'h00) 479 | pok_resetn <= 1'b0; 480 | else 481 | pok_resetn <= 1'b1; 482 | cnt <= cnt + 9'b1; 483 | if (pok_done && cnt > 9'h3) 484 | begin 485 | cnt <= 9'h00; 486 | if (mode == `GEN) 487 | state <= `WR_POK_GEN; 488 | else 489 | state <= `WR_POK_VER; 490 | end 491 | hash_reset <= 1'b0; 492 | end 493 | 494 | `WR_POK_VER: 495 | begin 496 | state <= `SEND_CO; 497 | cnt <= 9'h00; 498 | end 499 | 500 | `WR_POK_GEN: 501 | begin 502 | state <= `SEND_CO; 503 | cnt <= 9'h00; 504 | bit_sel_e_en <= 1'b1; 505 | end 506 | 507 | `SEND_CO: 508 | begin 509 | if (data_sent && mode == `GEN) 510 | begin 511 | state <= `REC_A; 512 | cnt <= 9'h0; 513 | end 514 | else if (data_sent && mode == `VER) 515 | begin 516 | state <= `REC_I; 517 | cnt <= 9'h0; 518 | end 519 | else 520 | state <= `SEND_CO; 521 | end 522 | 523 | `REC_I: 524 | begin 525 | if (data_received) 526 | state <= `RD_I; 527 | else 528 | state <= state; 529 | end 530 | 531 | `RD_I: 532 | begin 533 | state <= `REC_B; 534 | bit_sel_e_en <= 1'b1; 535 | end 536 | 537 | `REC_B: 538 | begin 539 | if (data_received) 540 | state <= `RD_B; 541 | else 542 | state <= state; 543 | end 544 | 545 | `RD_B: 546 | begin 547 | state <= `REC_A1; 548 | bit_sel_b_en <= 1'b1; 549 | global_cnt <= 9'h0; 550 | end 551 | 552 | `REC_A1: 553 | begin 554 | if (data_received) 555 | begin 556 | state <= `RD_A1; 557 | global_cnt <= global_cnt + 1'b1; 558 | cnt <= 9'h0; 559 | end 560 | else 561 | state <= state; 562 | end 563 | 564 | `RD_A1: 565 | begin 566 | if (global_cnt == 9'd32 && cnt == 9'h4) 567 | begin 568 | state <= `REC_A; 569 | global_cnt <= 9'h0; 570 | a_inverse_read <= 1'b1; 571 | end 572 | else if (cnt < 9'h4) 573 | state <= `RD_A1; 574 | else 575 | state <= `REC_A1; 576 | cnt <= cnt + 1'b1; 577 | end 578 | 579 | `REC_A: 580 | begin 581 | if (data_received == 1'b1 && row_sel_done == 1'b1 && mode == `GEN && done_half == 1'b0) 582 | begin 583 | state <= `MUL_CAL_FIRST; 584 | done_half <= 1'b1; 585 | global_cnt <= global_cnt + 1'b1; 586 | cnt <= 9'h0; 587 | a_inverse_read <= 1'b1; 588 | mul_cnt <= 2'b0; 589 | end 590 | else if (data_received) 591 | begin 592 | state <= `RD_A; 593 | global_cnt <= global_cnt + 1'b1; 594 | cnt <= 9'h0; 595 | a_inverse_read <= 1'b0; 596 | end 597 | else 598 | begin 599 | state <= state; 600 | a_inverse_read <= 1'b0; 601 | end 602 | 603 | end 604 | 605 | `RD_A: 606 | begin 607 | if (row_sel_done == 1'b1 && mode == `GEN && done_half == 1'b0) 608 | begin 609 | state <= `MUL_CAL_FIRST; 610 | done_half <= 1'b1; 611 | a_inverse_read <= 1'b1; 612 | mul_cnt <= 2'b0; 613 | end 614 | else if (cnt < 9'h3) 615 | state <= `RD_A; 616 | else if (global_cnt == 9'd113 && row_sel_done == 1'b1 && mode == `GEN) 617 | begin 618 | state <= `MUL_CAL; 619 | a_inverse_read <= 1'b1; 620 | mul_cnt <= 2'b0; 621 | end 622 | else if (row_sel_done == 1'b1 && mode == `VER && global_cnt == 9'd113) 623 | state <= `REC_HASH; 624 | else 625 | state <= `REC_A; 626 | 627 | if (row_sel_done == 1'b1 && mode == `GEN && done_half == 1'b0) 628 | cnt <= cnt; 629 | else 630 | cnt <= cnt + 1'b1; 631 | end 632 | 633 | `REC_HASH: 634 | begin 635 | if (data_received) 636 | begin 637 | state <= `RD_HASH; 638 | cnt <= 9'h0; 639 | end 640 | else 641 | begin 642 | state <= state; 643 | end 644 | end 645 | 646 | `RD_HASH: 647 | begin 648 | if (cnt > 9'h1 && check_done == 1'b1) 649 | begin 650 | state <= `MUL_CAL; 651 | mul_cnt <= 2'b0; 652 | cnt <= 9'h1; 653 | end 654 | else 655 | begin 656 | state <= state; 657 | cnt <= cnt + 1'b1; 658 | end 659 | end 660 | 661 | `MUL_CAL_FIRST: 662 | begin 663 | if (bit_sel_e_done == 1'b0) 664 | begin 665 | a_inverse_read <= 1'b0; 666 | mul_cnt <= 2'b0; 667 | state <= `MUL_CAL_FIRST; 668 | end 669 | else if (mul_cnt > 2'b1) 670 | begin 671 | state <= `RD_A; 672 | mul_cnt <= 2'b0; 673 | end 674 | else 675 | begin 676 | a_inverse_read <= 1'b0; 677 | mul_cnt <= mul_cnt + 1'b1; 678 | state <= state; 679 | end 680 | end 681 | 682 | `MUL_CAL: 683 | begin 684 | if (hash_done == 1'b0) 685 | begin 686 | state <= `MUL_CAL; 687 | mul_cnt <= 2'b0; 688 | a_inverse_read <= 1'b0; 689 | end 690 | else if (mul_cnt == 2'b0) 691 | begin 692 | a_inverse_read <= 1'b0; 693 | mul_cnt <= 2'b1; 694 | end 695 | else if (mode == `GEN && mul_cnt > 2'b1) 696 | begin 697 | state <= `BIT_EXP; 698 | mul_cnt <= 2'b0; 699 | end 700 | else if (mode == `VER && hash_done == 1'b1 && mul_cnt > 2'b1) 701 | begin 702 | state <= `HASH1; 703 | cnt <= 9'b0; 704 | mul_cnt <= 2'b0; 705 | end 706 | else 707 | begin 708 | state <= state; 709 | if (mul_cnt != 2'h3) 710 | mul_cnt <= mul_cnt + 1'b1; 711 | else 712 | mul_cnt <= mul_cnt; 713 | end 714 | end 715 | 716 | `BIT_EXP: 717 | begin 718 | if (bit_exp_done && hash_done) 719 | begin 720 | state <= `HASH1; 721 | cnt <= 9'h0; 722 | end 723 | else 724 | begin 725 | state <= state; 726 | cnt <= cnt + 1; 727 | end 728 | end 729 | 730 | `HASH1: 731 | begin 732 | if (hash_done && mode == `GEN && cnt > 9'h1) 733 | begin 734 | state <= `WR_HASH1; 735 | cnt <= 9'h0; 736 | end 737 | else if (fault == 1'b1 && mode == `VER) 738 | begin 739 | state <= `WR_HASH1; 740 | cnt <= 9'h0; 741 | end 742 | else if (hash_done && mode == `VER && hash_comp == 1'b1 && cnt > 9'h1) 743 | begin 744 | state <= `MUL_CAL; 745 | mul_cnt <= 1'b0; 746 | cnt <= 9'h0; 747 | end 748 | else if (hash_done && mode == `VER && hash_comp == 1'b0 && cnt > 9'h1) 749 | begin 750 | state <= `WR_HASH1; 751 | cnt <= 9'h0; 752 | end 753 | else 754 | begin 755 | state <= state; 756 | cnt <= cnt + 1; 757 | end 758 | end 759 | 760 | `HASH2: 761 | begin 762 | if (hash_done && cnt > 9'h1) 763 | begin 764 | state <= `WR_HASH2; 765 | cnt <= 9'h0; 766 | end 767 | else 768 | begin 769 | state <= state; 770 | cnt <= cnt + 1; 771 | end 772 | end 773 | 774 | `WR_B: 775 | begin 776 | state <= `SEND_B; 777 | end 778 | 779 | `WR_HASH1: 780 | begin 781 | if (cnt <9'h1) 782 | begin 783 | state <= state; 784 | cnt <= cnt + 9'b1; 785 | end 786 | else if (fault == 1'b1) 787 | begin 788 | state <= `SEND_HASH; 789 | cnt <= 9'h0; 790 | end 791 | else 792 | begin 793 | state <= `HASH2; 794 | cnt <= 9'b0; 795 | end 796 | end 797 | 798 | `WR_HASH2: 799 | begin 800 | if (cnt <9'h1) 801 | begin 802 | state <= state; 803 | cnt <= cnt + 9'b1; 804 | end 805 | else 806 | begin 807 | state <= `SEND_HASH; 808 | cnt <= 9'b0; 809 | end 810 | end 811 | 812 | `SEND_B: 813 | begin 814 | if (data_sent) 815 | state <= `IDLE; 816 | else 817 | state <= state; 818 | end 819 | 820 | `SEND_HASH: 821 | begin 822 | if (data_sent && mode == `GEN) 823 | begin 824 | state <= `RED_RD; 825 | cnt <= 9'h0; 826 | end 827 | else if (data_sent && mode == `VER) 828 | state <= `IDLE; 829 | else 830 | state <= state; 831 | end 832 | 833 | `RED_RD: 834 | begin 835 | if (data_received) 836 | state <= `WR_B; 837 | else 838 | state <= state; 839 | end 840 | 841 | default: 842 | state <= `IDLE; 843 | endcase 844 | end 845 | end 846 | 847 | endmodule 848 | -------------------------------------------------------------------------------- /LPN_PUF_complete_test/tcl/bd_zedboard.tcl: -------------------------------------------------------------------------------- 1 | 2 | ################################################################ 3 | # This is a generated script based on design: design_1 4 | # 5 | # Though there are limitations about the generated script, 6 | # the main purpose of this utility is to make learning 7 | # IP Integrator Tcl commands easier. 8 | ################################################################ 9 | 10 | ################################################################ 11 | # Check if script is running in correct Vivado version. 12 | ################################################################ 13 | set scripts_vivado_version 2016.2 14 | set current_vivado_version [version -short] 15 | 16 | if { [string first $scripts_vivado_version $current_vivado_version] == -1 } { 17 | puts "" 18 | puts "ERROR: This script was generated using Vivado <$scripts_vivado_version> and is being run in <$current_vivado_version> of Vivado. Please run the script in Vivado <$scripts_vivado_version> then open the design in Vivado <$current_vivado_version>. Upgrade the design by running \"Tools => Report => Report IP Status...\", then run write_bd_tcl to create an updated script." 19 | 20 | return 1 21 | } 22 | 23 | ################################################################ 24 | # START 25 | ################################################################ 26 | 27 | # To test this script, run the following commands from Vivado Tcl console: 28 | # source design_1_script.tcl 29 | 30 | # If you do not already have a project created, 31 | # you can create a project using the following command: 32 | # create_project project_1 myproj -part xc7z020clg484-1 33 | # set_property BOARD_PART em.avnet.com:zed:part0:1.3 [current_project] 34 | 35 | # CHECKING IF PROJECT EXISTS 36 | if { [get_projects -quiet] eq "" } { 37 | puts "ERROR: Please open or create a project!" 38 | return 1 39 | } 40 | 41 | 42 | 43 | # CHANGE DESIGN NAME HERE 44 | set design_name design_1 45 | 46 | # If you do not already have an existing IP Integrator design open, 47 | # you can create a design using the following command: 48 | # create_bd_design $design_name 49 | 50 | # Creating design if needed 51 | set errMsg "" 52 | set nRet 0 53 | 54 | set cur_design [current_bd_design -quiet] 55 | set list_cells [get_bd_cells -quiet] 56 | 57 | if { ${design_name} eq "" } { 58 | # USE CASES: 59 | # 1) Design_name not set 60 | 61 | set errMsg "ERROR: Please set the variable to a non-empty value." 62 | set nRet 1 63 | 64 | } elseif { ${cur_design} ne "" && ${list_cells} eq "" } { 65 | # USE CASES: 66 | # 2): Current design opened AND is empty AND names same. 67 | # 3): Current design opened AND is empty AND names diff; design_name NOT in project. 68 | # 4): Current design opened AND is empty AND names diff; design_name exists in project. 69 | 70 | if { $cur_design ne $design_name } { 71 | puts "INFO: Changing value of from <$design_name> to <$cur_design> since current design is empty." 72 | set design_name [get_property NAME $cur_design] 73 | } 74 | puts "INFO: Constructing design in IPI design <$cur_design>..." 75 | 76 | } elseif { ${cur_design} ne "" && $list_cells ne "" && $cur_design eq $design_name } { 77 | # USE CASES: 78 | # 5) Current design opened AND has components AND same names. 79 | 80 | set errMsg "ERROR: Design <$design_name> already exists in your project, please set the variable to another value." 81 | set nRet 1 82 | } elseif { [get_files -quiet ${design_name}.bd] ne "" } { 83 | # USE CASES: 84 | # 6) Current opened design, has components, but diff names, design_name exists in project. 85 | # 7) No opened design, design_name exists in project. 86 | 87 | set errMsg "ERROR: Design <$design_name> already exists in your project, please set the variable to another value." 88 | set nRet 2 89 | 90 | } else { 91 | # USE CASES: 92 | # 8) No opened design, design_name not in project. 93 | # 9) Current opened design, has components, but diff names, design_name not in project. 94 | 95 | puts "INFO: Currently there is no design <$design_name> in project, so creating one..." 96 | 97 | create_bd_design $design_name 98 | 99 | puts "INFO: Making design <$design_name> as current_bd_design." 100 | current_bd_design $design_name 101 | 102 | } 103 | 104 | puts "INFO: Currently the variable is equal to \"$design_name\"." 105 | 106 | if { $nRet != 0 } { 107 | puts $errMsg 108 | return $nRet 109 | } 110 | 111 | ################################################################## 112 | # DESIGN PROCs 113 | ################################################################## 114 | 115 | 116 | # Hierarchical cell: dac_model 117 | proc create_hier_cell_dac_model { parentCell nameHier } { 118 | 119 | if { $parentCell eq "" || $nameHier eq "" } { 120 | puts "ERROR: create_hier_cell_dac_model() - Empty argument(s)!" 121 | return 122 | } 123 | 124 | # Get object for parentCell 125 | set parentObj [get_bd_cells $parentCell] 126 | if { $parentObj == "" } { 127 | puts "ERROR: Unable to find parent cell <$parentCell>!" 128 | return 129 | } 130 | 131 | # Make sure parentObj is hier blk 132 | set parentType [get_property TYPE $parentObj] 133 | if { $parentType ne "hier" } { 134 | puts "ERROR: Parent <$parentObj> has TYPE = <$parentType>. Expected to be ." 135 | return 136 | } 137 | 138 | # Save current instance; Restore later 139 | set oldCurInst [current_bd_instance .] 140 | 141 | # Set parent object as current 142 | current_bd_instance $parentObj 143 | 144 | # Create cell and set as current instance 145 | set hier_obj [create_bd_cell -type hier $nameHier] 146 | current_bd_instance $hier_obj 147 | 148 | # Create interface pins 149 | create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:aximm_rtl:1.0 S_AXI 150 | create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:axis_rtl:1.0 S_AXIS_DATA 151 | 152 | # Create pins 153 | create_bd_pin -dir I -type clk s_axi_aclk 154 | create_bd_pin -dir I -from 0 -to 0 -type rst s_axi_aresetn 155 | 156 | # Create instance: axi_fifo_mm_s_1, and set properties 157 | set axi_fifo_mm_s_1 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_fifo_mm_s:4.1 axi_fifo_mm_s_1 ] 158 | 159 | # Create interface connections 160 | connect_bd_intf_net -intf_net axi_dma_1_m_axis_mm2s [get_bd_intf_pins S_AXIS_DATA] [get_bd_intf_pins axi_fifo_mm_s_1/AXI_STR_RXD] 161 | connect_bd_intf_net -intf_net axi_interconnect_1_m01_axi [get_bd_intf_pins S_AXI] [get_bd_intf_pins axi_fifo_mm_s_1/S_AXI] 162 | 163 | # Create port connections 164 | connect_bd_net -net proc_sys_reset_0_peripheral_aresetn [get_bd_pins s_axi_aresetn] [get_bd_pins axi_fifo_mm_s_1/s_axi_aresetn] 165 | connect_bd_net -net processing_system7_1_fclk_clk0 [get_bd_pins s_axi_aclk] [get_bd_pins axi_fifo_mm_s_1/s_axi_aclk] 166 | 167 | # Restore current instance 168 | current_bd_instance $oldCurInst 169 | } 170 | 171 | # Hierarchical cell: adc_model 172 | proc create_hier_cell_adc_model { parentCell nameHier } { 173 | 174 | if { $parentCell eq "" || $nameHier eq "" } { 175 | puts "ERROR: create_hier_cell_adc_model() - Empty argument(s)!" 176 | return 177 | } 178 | 179 | # Get object for parentCell 180 | set parentObj [get_bd_cells $parentCell] 181 | if { $parentObj == "" } { 182 | puts "ERROR: Unable to find parent cell <$parentCell>!" 183 | return 184 | } 185 | 186 | # Make sure parentObj is hier blk 187 | set parentType [get_property TYPE $parentObj] 188 | if { $parentType ne "hier" } { 189 | puts "ERROR: Parent <$parentObj> has TYPE = <$parentType>. Expected to be ." 190 | return 191 | } 192 | 193 | # Save current instance; Restore later 194 | set oldCurInst [current_bd_instance .] 195 | 196 | # Set parent object as current 197 | current_bd_instance $parentObj 198 | 199 | # Create cell and set as current instance 200 | set hier_obj [create_bd_cell -type hier $nameHier] 201 | current_bd_instance $hier_obj 202 | 203 | # Create interface pins 204 | 205 | # Create pins 206 | create_bd_pin -dir I -type clk aclk 207 | create_bd_pin -dir O -from 31 -to 0 dout 208 | create_bd_pin -dir I m_axis_data_tready 209 | create_bd_pin -dir I -from 0 -to 0 resetn 210 | 211 | # Create instance: c_counter_binary_0, and set properties 212 | set c_counter_binary_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:c_counter_binary:12.0 c_counter_binary_0 ] 213 | set_property -dict [ list CONFIG.CE {true} CONFIG.Output_Width {32} CONFIG.SCLR {true} ] $c_counter_binary_0 214 | 215 | # Create instance: util_vector_logic_0, and set properties 216 | set util_vector_logic_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:util_vector_logic:2.0 util_vector_logic_0 ] 217 | set_property -dict [ list CONFIG.C_OPERATION {not} CONFIG.C_SIZE {1} ] $util_vector_logic_0 218 | 219 | # Create port connections 220 | connect_bd_net -net Op1_1 [get_bd_pins resetn] [get_bd_pins util_vector_logic_0/Op1] 221 | connect_bd_net -net aclk_1 [get_bd_pins aclk] [get_bd_pins c_counter_binary_0/CLK] 222 | connect_bd_net -net c_counter_binary_0_Q [get_bd_pins dout] [get_bd_pins c_counter_binary_0/Q] 223 | connect_bd_net -net m_axis_data_tready_1 [get_bd_pins m_axis_data_tready] [get_bd_pins c_counter_binary_0/CE] 224 | connect_bd_net -net util_vector_logic_0_Res [get_bd_pins c_counter_binary_0/SCLR] [get_bd_pins util_vector_logic_0/Res] 225 | 226 | # Restore current instance 227 | current_bd_instance $oldCurInst 228 | } 229 | 230 | # Hierarchical cell: rst_gen 231 | proc create_hier_cell_rst_gen { parentCell nameHier } { 232 | 233 | if { $parentCell eq "" || $nameHier eq "" } { 234 | puts "ERROR: create_hier_cell_rst_gen() - Empty argument(s)!" 235 | return 236 | } 237 | 238 | # Get object for parentCell 239 | set parentObj [get_bd_cells $parentCell] 240 | if { $parentObj == "" } { 241 | puts "ERROR: Unable to find parent cell <$parentCell>!" 242 | return 243 | } 244 | 245 | # Make sure parentObj is hier blk 246 | set parentType [get_property TYPE $parentObj] 247 | if { $parentType ne "hier" } { 248 | puts "ERROR: Parent <$parentObj> has TYPE = <$parentType>. Expected to be ." 249 | return 250 | } 251 | 252 | # Save current instance; Restore later 253 | set oldCurInst [current_bd_instance .] 254 | 255 | # Set parent object as current 256 | current_bd_instance $parentObj 257 | 258 | # Create cell and set as current instance 259 | set hier_obj [create_bd_cell -type hier $nameHier] 260 | current_bd_instance $hier_obj 261 | 262 | # Create interface pins 263 | 264 | # Create pins 265 | create_bd_pin -dir I -from 0 -to 0 -type rst aux_reset_in 266 | create_bd_pin -dir I -type rst ext_reset_in 267 | create_bd_pin -dir O -from 0 -to 0 -type rst interconnect_aresetn 268 | create_bd_pin -dir O -from 0 -to 0 -type rst peripheral_aresetn 269 | create_bd_pin -dir I -type clk slowest_sync_clk 270 | create_bd_pin -dir O -from 0 -to 0 -type rst tlast_gen_resetn 271 | 272 | # Create instance: proc_sys_reset_0, and set properties 273 | set proc_sys_reset_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:proc_sys_reset:5.0 proc_sys_reset_0 ] 274 | 275 | # Create instance: proc_sys_reset_1, and set properties 276 | set proc_sys_reset_1 [ create_bd_cell -type ip -vlnv xilinx.com:ip:proc_sys_reset:5.0 proc_sys_reset_1 ] 277 | 278 | # Create port connections 279 | connect_bd_net -net proc_sys_reset_0_interconnect_aresetn [get_bd_pins interconnect_aresetn] [get_bd_pins proc_sys_reset_0/interconnect_aresetn] 280 | connect_bd_net -net proc_sys_reset_0_peripheral_aresetn [get_bd_pins peripheral_aresetn] [get_bd_pins proc_sys_reset_0/peripheral_aresetn] 281 | connect_bd_net -net proc_sys_reset_1_peripheral_aresetn [get_bd_pins tlast_gen_resetn] [get_bd_pins proc_sys_reset_1/peripheral_aresetn] 282 | connect_bd_net -net processing_system7_0_FCLK_RESET0_N [get_bd_pins ext_reset_in] [get_bd_pins proc_sys_reset_0/ext_reset_in] [get_bd_pins proc_sys_reset_1/ext_reset_in] 283 | connect_bd_net -net processing_system7_1_fclk_clk0 [get_bd_pins slowest_sync_clk] [get_bd_pins proc_sys_reset_0/slowest_sync_clk] [get_bd_pins proc_sys_reset_1/slowest_sync_clk] 284 | connect_bd_net -net xlslice_1_Dout [get_bd_pins aux_reset_in] [get_bd_pins proc_sys_reset_1/aux_reset_in] 285 | 286 | # Restore current instance 287 | current_bd_instance $oldCurInst 288 | } 289 | 290 | # Hierarchical cell: gpio 291 | proc create_hier_cell_gpio { parentCell nameHier } { 292 | 293 | if { $parentCell eq "" || $nameHier eq "" } { 294 | puts "ERROR: create_hier_cell_gpio() - Empty argument(s)!" 295 | return 296 | } 297 | 298 | # Get object for parentCell 299 | set parentObj [get_bd_cells $parentCell] 300 | if { $parentObj == "" } { 301 | puts "ERROR: Unable to find parent cell <$parentCell>!" 302 | return 303 | } 304 | 305 | # Make sure parentObj is hier blk 306 | set parentType [get_property TYPE $parentObj] 307 | if { $parentType ne "hier" } { 308 | puts "ERROR: Parent <$parentObj> has TYPE = <$parentType>. Expected to be ." 309 | return 310 | } 311 | 312 | # Save current instance; Restore later 313 | set oldCurInst [current_bd_instance .] 314 | 315 | # Set parent object as current 316 | current_bd_instance $parentObj 317 | 318 | # Create cell and set as current instance 319 | set hier_obj [create_bd_cell -type hier $nameHier] 320 | current_bd_instance $hier_obj 321 | 322 | # Create interface pins 323 | create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:aximm_rtl:1.0 S_AXI 324 | 325 | # Create pins 326 | create_bd_pin -dir O -from 9 -to 0 pkt_length 327 | create_bd_pin -dir I -type clk s_axi_aclk 328 | create_bd_pin -dir I -from 0 -to 0 -type rst s_axi_aresetn 329 | create_bd_pin -dir O -from 0 -to 0 tlast_gen_resetn 330 | 331 | # Create instance: axi_gpio_1, and set properties 332 | set axi_gpio_1 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_gpio:2.0 axi_gpio_1 ] 333 | set_property -dict [ list CONFIG.C_ALL_OUTPUTS {0} CONFIG.C_GPIO_WIDTH {32} ] $axi_gpio_1 334 | 335 | # Create instance: xlslice_0, and set properties 336 | set xlslice_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:xlslice:1.0 xlslice_0 ] 337 | set_property -dict [ list CONFIG.DIN_FROM {9} CONFIG.DOUT_WIDTH {10} ] $xlslice_0 338 | 339 | # Create instance: xlslice_1, and set properties 340 | set xlslice_1 [ create_bd_cell -type ip -vlnv xilinx.com:ip:xlslice:1.0 xlslice_1 ] 341 | set_property -dict [ list CONFIG.DIN_FROM {31} CONFIG.DIN_TO {31} CONFIG.DOUT_WIDTH {1} ] $xlslice_1 342 | 343 | # Create interface connections 344 | connect_bd_intf_net -intf_net axi_interconnect_1_m02_axi [get_bd_intf_pins S_AXI] [get_bd_intf_pins axi_gpio_1/S_AXI] 345 | 346 | # Create port connections 347 | connect_bd_net -net axi_gpio_1_gpio_io_o [get_bd_pins axi_gpio_1/gpio_io_i] [get_bd_pins axi_gpio_1/gpio_io_o] [get_bd_pins xlslice_0/Din] [get_bd_pins xlslice_1/Din] 348 | connect_bd_net -net proc_sys_reset_0_peripheral_aresetn [get_bd_pins s_axi_aresetn] [get_bd_pins axi_gpio_1/s_axi_aresetn] 349 | connect_bd_net -net processing_system7_1_fclk_clk0 [get_bd_pins s_axi_aclk] [get_bd_pins axi_gpio_1/s_axi_aclk] 350 | connect_bd_net -net xlslice_0_Dout [get_bd_pins pkt_length] [get_bd_pins xlslice_0/Dout] 351 | connect_bd_net -net xlslice_1_Dout [get_bd_pins tlast_gen_resetn] [get_bd_pins xlslice_1/Dout] 352 | 353 | # Restore current instance 354 | current_bd_instance $oldCurInst 355 | } 356 | 357 | # Hierarchical cell: datapath 358 | proc create_hier_cell_datapath { parentCell nameHier } { 359 | 360 | if { $parentCell eq "" || $nameHier eq "" } { 361 | puts "ERROR: create_hier_cell_datapath() - Empty argument(s)!" 362 | return 363 | } 364 | 365 | # Get object for parentCell 366 | set parentObj [get_bd_cells $parentCell] 367 | if { $parentObj == "" } { 368 | puts "ERROR: Unable to find parent cell <$parentCell>!" 369 | return 370 | } 371 | 372 | # Make sure parentObj is hier blk 373 | set parentType [get_property TYPE $parentObj] 374 | if { $parentType ne "hier" } { 375 | puts "ERROR: Parent <$parentObj> has TYPE = <$parentType>. Expected to be ." 376 | return 377 | } 378 | 379 | # Save current instance; Restore later 380 | set oldCurInst [current_bd_instance .] 381 | 382 | # Set parent object as current 383 | current_bd_instance $parentObj 384 | 385 | # Create cell and set as current instance 386 | set hier_obj [create_bd_cell -type hier $nameHier] 387 | current_bd_instance $hier_obj 388 | 389 | # Create interface pins 390 | create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:aximm_rtl:1.0 M_AXI_MM2S 391 | create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:aximm_rtl:1.0 M_AXI_S2MM 392 | create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:aximm_rtl:1.0 S_AXI_DAC 393 | create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:aximm_rtl:1.0 S_AXI_DMA 394 | 395 | # Create pins 396 | create_bd_pin -dir I -type clk data_aclk 397 | create_bd_pin -dir I -from 0 -to 0 -type rst data_resetn 398 | create_bd_pin -dir O -from 0 -to 0 mm2s_introut 399 | create_bd_pin -dir I -from 9 -to 0 pkt_length 400 | create_bd_pin -dir O -from 0 -to 0 s2mm_introut 401 | create_bd_pin -dir I -from 0 -to 0 -type rst tlast_gen_resetn 402 | 403 | # Create instance: adc_model 404 | create_hier_cell_adc_model $hier_obj adc_model 405 | 406 | # Create instance: axi_dma_1, and set properties 407 | set axi_dma_1 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_dma:7.1 axi_dma_1 ] 408 | set_property -dict [ list CONFIG.c_include_mm2s_dre {1} CONFIG.c_include_s2mm_dre {1} CONFIG.c_include_sg {0} CONFIG.c_m_axi_mm2s_data_width {64} CONFIG.c_m_axi_s2mm_data_width {64} CONFIG.c_sg_length_width {23} ] $axi_dma_1 409 | 410 | # Create instance: dac_model 411 | create_hier_cell_dac_model $hier_obj dac_model 412 | 413 | # Create instance: tlast_gen_0, and set properties 414 | set tlast_gen_0 [ create_bd_cell -type ip -vlnv xilinx.com:user:tlast_gen:1.0 tlast_gen_0 ] 415 | set_property -dict [ list CONFIG.MAX_PKT_LENGTH {1023} CONFIG.TDATA_WIDTH {32} ] $tlast_gen_0 416 | 417 | # Create interface connections 418 | connect_bd_intf_net -intf_net axi_dma_1_m_axis_mm2s [get_bd_intf_pins axi_dma_1/M_AXIS_MM2S] [get_bd_intf_pins dac_model/S_AXIS_DATA] 419 | connect_bd_intf_net -intf_net axi_interconnect_1_m00_axi [get_bd_intf_pins S_AXI_DMA] [get_bd_intf_pins axi_dma_1/S_AXI_LITE] 420 | connect_bd_intf_net -intf_net axi_interconnect_1_m01_axi [get_bd_intf_pins S_AXI_DAC] [get_bd_intf_pins dac_model/S_AXI] 421 | connect_bd_intf_net -intf_net s00_axi_1 [get_bd_intf_pins M_AXI_S2MM] [get_bd_intf_pins axi_dma_1/M_AXI_S2MM] 422 | connect_bd_intf_net -intf_net s01_axi_1 [get_bd_intf_pins M_AXI_MM2S] [get_bd_intf_pins axi_dma_1/M_AXI_MM2S] 423 | connect_bd_intf_net -intf_net tlast_gen_0_m_axis [get_bd_intf_pins axi_dma_1/S_AXIS_S2MM] [get_bd_intf_pins tlast_gen_0/m_axis] 424 | 425 | # Create port connections 426 | connect_bd_net -net adc_model_dout [get_bd_pins adc_model/dout] [get_bd_pins tlast_gen_0/s_axis_tdata] 427 | connect_bd_net -net axi_dma_1_mm2s_introut [get_bd_pins mm2s_introut] [get_bd_pins axi_dma_1/mm2s_introut] 428 | connect_bd_net -net axi_dma_1_s2mm_introut [get_bd_pins s2mm_introut] [get_bd_pins axi_dma_1/s2mm_introut] 429 | connect_bd_net -net ctrl_Dout [get_bd_pins pkt_length] [get_bd_pins tlast_gen_0/pkt_length] 430 | connect_bd_net -net ctrl_peripheral_aresetn [get_bd_pins tlast_gen_resetn] [get_bd_pins adc_model/resetn] [get_bd_pins tlast_gen_0/resetn] [get_bd_pins tlast_gen_0/s_axis_tvalid] 431 | connect_bd_net -net proc_sys_reset_0_peripheral_aresetn [get_bd_pins data_resetn] [get_bd_pins axi_dma_1/axi_resetn] [get_bd_pins dac_model/s_axi_aresetn] 432 | connect_bd_net -net processing_system7_1_fclk_clk0 [get_bd_pins data_aclk] [get_bd_pins adc_model/aclk] [get_bd_pins axi_dma_1/m_axi_mm2s_aclk] [get_bd_pins axi_dma_1/m_axi_s2mm_aclk] [get_bd_pins axi_dma_1/s_axi_lite_aclk] [get_bd_pins dac_model/s_axi_aclk] [get_bd_pins tlast_gen_0/aclk] 433 | connect_bd_net -net tlast_gen_0_s_axis_tready [get_bd_pins adc_model/m_axis_data_tready] [get_bd_pins tlast_gen_0/s_axis_tready] 434 | 435 | # Restore current instance 436 | current_bd_instance $oldCurInst 437 | } 438 | 439 | # Hierarchical cell: ctrl 440 | proc create_hier_cell_ctrl { parentCell nameHier } { 441 | 442 | if { $parentCell eq "" || $nameHier eq "" } { 443 | puts "ERROR: create_hier_cell_ctrl() - Empty argument(s)!" 444 | return 445 | } 446 | 447 | # Get object for parentCell 448 | set parentObj [get_bd_cells $parentCell] 449 | if { $parentObj == "" } { 450 | puts "ERROR: Unable to find parent cell <$parentCell>!" 451 | return 452 | } 453 | 454 | # Make sure parentObj is hier blk 455 | set parentType [get_property TYPE $parentObj] 456 | if { $parentType ne "hier" } { 457 | puts "ERROR: Parent <$parentObj> has TYPE = <$parentType>. Expected to be ." 458 | return 459 | } 460 | 461 | # Save current instance; Restore later 462 | set oldCurInst [current_bd_instance .] 463 | 464 | # Set parent object as current 465 | current_bd_instance $parentObj 466 | 467 | # Create cell and set as current instance 468 | set hier_obj [create_bd_cell -type hier $nameHier] 469 | current_bd_instance $hier_obj 470 | 471 | # Create interface pins 472 | create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:ddrx_rtl:1.0 DDR 473 | create_bd_intf_pin -mode Master -vlnv xilinx.com:display_processing_system7:fixedio_rtl:1.0 FIXED_IO 474 | create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:aximm_rtl:1.0 M_AXI_DAC 475 | create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:aximm_rtl:1.0 M_AXI_DMA 476 | create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:aximm_rtl:1.0 S_AXI_DMA_MM2S 477 | create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:aximm_rtl:1.0 S_AXI_DMA_S2MM 478 | 479 | # Create pins 480 | create_bd_pin -dir O -type clk ctrl_aclk 481 | create_bd_pin -dir O -from 0 -to 0 -type rst ctrl_resetn 482 | create_bd_pin -dir I -from 0 -to 0 dma_mm2s_irq 483 | create_bd_pin -dir I -from 0 -to 0 dma_s2mm_irq 484 | create_bd_pin -dir O -from 9 -to 0 pkt_length 485 | create_bd_pin -dir O -from 0 -to 0 -type rst tlast_gen_resetn 486 | 487 | # Create instance: axi_interconnect_1, and set properties 488 | set axi_interconnect_1 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_interconnect:2.1 axi_interconnect_1 ] 489 | set_property -dict [ list CONFIG.NUM_MI {3} ] $axi_interconnect_1 490 | 491 | # Create instance: axi_interconnect_2, and set properties 492 | set axi_interconnect_2 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_interconnect:2.1 axi_interconnect_2 ] 493 | set_property -dict [ list CONFIG.NUM_MI {1} CONFIG.NUM_SI {2} ] $axi_interconnect_2 494 | 495 | # Create instance: gpio 496 | create_hier_cell_gpio $hier_obj gpio 497 | 498 | # Create instance: processing_system7_0, and set properties 499 | set processing_system7_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:processing_system7:5.5 processing_system7_0 ] 500 | set_property -dict [ list CONFIG.PCW_FPGA0_PERIPHERAL_FREQMHZ {100.000000} CONFIG.PCW_IRQ_F2P_INTR {1} CONFIG.PCW_USE_FABRIC_INTERRUPT {1} CONFIG.PCW_USE_S_AXI_HP0 {1} CONFIG.preset {ZedBoard} ] $processing_system7_0 501 | 502 | # Create instance: rst_gen 503 | create_hier_cell_rst_gen $hier_obj rst_gen 504 | 505 | # Create instance: xlconcat_0, and set properties 506 | set xlconcat_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:xlconcat:2.1 xlconcat_0 ] 507 | 508 | # Create interface connections 509 | connect_bd_intf_net -intf_net axi_interconnect_1_m00_axi [get_bd_intf_pins M_AXI_DMA] [get_bd_intf_pins axi_interconnect_1/M00_AXI] 510 | connect_bd_intf_net -intf_net axi_interconnect_1_m01_axi [get_bd_intf_pins M_AXI_DAC] [get_bd_intf_pins axi_interconnect_1/M01_AXI] 511 | connect_bd_intf_net -intf_net axi_interconnect_1_m02_axi [get_bd_intf_pins axi_interconnect_1/M02_AXI] [get_bd_intf_pins gpio/S_AXI] 512 | connect_bd_intf_net -intf_net axi_interconnect_2_M00_AXI [get_bd_intf_pins axi_interconnect_2/M00_AXI] [get_bd_intf_pins processing_system7_0/S_AXI_HP0] 513 | connect_bd_intf_net -intf_net processing_system7_0_DDR [get_bd_intf_pins DDR] [get_bd_intf_pins processing_system7_0/DDR] 514 | connect_bd_intf_net -intf_net processing_system7_0_FIXED_IO [get_bd_intf_pins FIXED_IO] [get_bd_intf_pins processing_system7_0/FIXED_IO] 515 | connect_bd_intf_net -intf_net processing_system7_0_M_AXI_GP0 [get_bd_intf_pins axi_interconnect_1/S00_AXI] [get_bd_intf_pins processing_system7_0/M_AXI_GP0] 516 | connect_bd_intf_net -intf_net s00_axi_1 [get_bd_intf_pins S_AXI_DMA_S2MM] [get_bd_intf_pins axi_interconnect_2/S00_AXI] 517 | connect_bd_intf_net -intf_net s01_axi_1 [get_bd_intf_pins S_AXI_DMA_MM2S] [get_bd_intf_pins axi_interconnect_2/S01_AXI] 518 | 519 | # Create port connections 520 | connect_bd_net -net In0_1 [get_bd_pins dma_mm2s_irq] [get_bd_pins xlconcat_0/In0] 521 | connect_bd_net -net In1_1 [get_bd_pins dma_s2mm_irq] [get_bd_pins xlconcat_0/In1] 522 | connect_bd_net -net proc_sys_reset_0_interconnect_aresetn [get_bd_pins axi_interconnect_1/ARESETN] [get_bd_pins axi_interconnect_1/M00_ARESETN] [get_bd_pins axi_interconnect_1/M01_ARESETN] [get_bd_pins axi_interconnect_1/M02_ARESETN] [get_bd_pins axi_interconnect_1/S00_ARESETN] [get_bd_pins axi_interconnect_2/ARESETN] [get_bd_pins axi_interconnect_2/M00_ARESETN] [get_bd_pins axi_interconnect_2/S00_ARESETN] [get_bd_pins axi_interconnect_2/S01_ARESETN] [get_bd_pins rst_gen/interconnect_aresetn] 523 | connect_bd_net -net proc_sys_reset_0_peripheral_aresetn [get_bd_pins ctrl_resetn] [get_bd_pins gpio/s_axi_aresetn] [get_bd_pins rst_gen/peripheral_aresetn] 524 | connect_bd_net -net proc_sys_reset_1_peripheral_aresetn [get_bd_pins tlast_gen_resetn] [get_bd_pins rst_gen/tlast_gen_resetn] 525 | connect_bd_net -net processing_system7_0_FCLK_RESET0_N [get_bd_pins processing_system7_0/FCLK_RESET0_N] [get_bd_pins rst_gen/ext_reset_in] 526 | connect_bd_net -net processing_system7_1_fclk_clk0 [get_bd_pins ctrl_aclk] [get_bd_pins axi_interconnect_1/ACLK] [get_bd_pins axi_interconnect_1/M00_ACLK] [get_bd_pins axi_interconnect_1/M01_ACLK] [get_bd_pins axi_interconnect_1/M02_ACLK] [get_bd_pins axi_interconnect_1/S00_ACLK] [get_bd_pins axi_interconnect_2/ACLK] [get_bd_pins axi_interconnect_2/M00_ACLK] [get_bd_pins axi_interconnect_2/S00_ACLK] [get_bd_pins axi_interconnect_2/S01_ACLK] [get_bd_pins gpio/s_axi_aclk] [get_bd_pins processing_system7_0/FCLK_CLK0] [get_bd_pins processing_system7_0/M_AXI_GP0_ACLK] [get_bd_pins processing_system7_0/S_AXI_HP0_ACLK] [get_bd_pins rst_gen/slowest_sync_clk] 527 | connect_bd_net -net xlconcat_0_dout [get_bd_pins processing_system7_0/IRQ_F2P] [get_bd_pins xlconcat_0/dout] 528 | connect_bd_net -net xlslice_0_Dout [get_bd_pins pkt_length] [get_bd_pins gpio/pkt_length] 529 | connect_bd_net -net xlslice_1_Dout [get_bd_pins gpio/tlast_gen_resetn] [get_bd_pins rst_gen/aux_reset_in] 530 | 531 | # Restore current instance 532 | current_bd_instance $oldCurInst 533 | } 534 | 535 | 536 | # Procedure to create entire design; Provide argument to make 537 | # procedure reusable. If parentCell is "", will use root. 538 | proc create_root_design { parentCell } { 539 | 540 | if { $parentCell eq "" } { 541 | set parentCell [get_bd_cells /] 542 | } 543 | 544 | # Get object for parentCell 545 | set parentObj [get_bd_cells $parentCell] 546 | if { $parentObj == "" } { 547 | puts "ERROR: Unable to find parent cell <$parentCell>!" 548 | return 549 | } 550 | 551 | # Make sure parentObj is hier blk 552 | set parentType [get_property TYPE $parentObj] 553 | if { $parentType ne "hier" } { 554 | puts "ERROR: Parent <$parentObj> has TYPE = <$parentType>. Expected to be ." 555 | return 556 | } 557 | 558 | # Save current instance; Restore later 559 | set oldCurInst [current_bd_instance .] 560 | 561 | # Set parent object as current 562 | current_bd_instance $parentObj 563 | 564 | 565 | # Create interface ports 566 | set DDR [ create_bd_intf_port -mode Master -vlnv xilinx.com:interface:ddrx_rtl:1.0 DDR ] 567 | set FIXED_IO [ create_bd_intf_port -mode Master -vlnv xilinx.com:display_processing_system7:fixedio_rtl:1.0 FIXED_IO ] 568 | 569 | # Create ports 570 | 571 | # Create instance: ctrl 572 | create_hier_cell_ctrl [current_bd_instance .] ctrl 573 | 574 | # Create instance: datapath 575 | create_hier_cell_datapath [current_bd_instance .] datapath 576 | 577 | # Create interface connections 578 | connect_bd_intf_net -intf_net axi_interconnect_1_m00_axi [get_bd_intf_pins ctrl/M_AXI_DMA] [get_bd_intf_pins datapath/S_AXI_DMA] 579 | connect_bd_intf_net -intf_net axi_interconnect_1_m01_axi [get_bd_intf_pins ctrl/M_AXI_DAC] [get_bd_intf_pins datapath/S_AXI_DAC] 580 | connect_bd_intf_net -intf_net processing_system7_0_DDR [get_bd_intf_ports DDR] [get_bd_intf_pins ctrl/DDR] 581 | connect_bd_intf_net -intf_net processing_system7_0_FIXED_IO [get_bd_intf_ports FIXED_IO] [get_bd_intf_pins ctrl/FIXED_IO] 582 | connect_bd_intf_net -intf_net s00_axi_1 [get_bd_intf_pins ctrl/S_AXI_DMA_S2MM] [get_bd_intf_pins datapath/M_AXI_S2MM] 583 | connect_bd_intf_net -intf_net s01_axi_1 [get_bd_intf_pins ctrl/S_AXI_DMA_MM2S] [get_bd_intf_pins datapath/M_AXI_MM2S] 584 | 585 | 586 | ################################################# 587 | #Added by CJ 588 | 589 | 590 | #delete old blocks 591 | delete_bd_objs [get_bd_intf_nets datapath/tlast_gen_0_m_axis] [get_bd_nets datapath/ctrl_Dout] [get_bd_nets datapath/tlast_gen_0_s_axis_tready] [get_bd_nets datapath/adc_model_dout] [get_bd_cells datapath/tlast_gen_0] 592 | delete_bd_objs [get_bd_intf_nets datapath/axi_interconnect_1_m01_axi] [get_bd_intf_nets datapath/axi_dma_1_m_axis_mm2s] [get_bd_cells datapath/dac_model] 593 | delete_bd_objs [get_bd_nets datapath/ctrl_peripheral_aresetn] [get_bd_cells datapath/adc_model] 594 | 595 | #add repos 596 | #Notice: PLEASE MODIFY THE FOLLOWING DIRECTORIES ACCORDINGLY 597 | set_property ip_repo_paths {d:/GitHub/LPN_PUF_open_source/LPN_PUF_complete_test/lib d:/GitHub/LPN_PUF_open_source/RO d:/GitHub/LPN_PUF_open_source/system D:/GitHub/LPN_PUF_open_source/TRNG} [current_project] 598 | update_ip_catalog 599 | 600 | #add blocks 601 | startgroup 602 | create_bd_cell -type ip -vlnv xilinx.com:user:system:1.0 datapath/system_0 603 | create_bd_cell -type ip -vlnv xilinx.com:user:trng_wrapper:1.0 datapath/trng_wrapper_0 604 | create_bd_cell -type ip -vlnv xilinx.com:user:ro_pair_wrapper:1.0 datapath/ro_pair_wrapper_0 605 | endgroup 606 | 607 | #make connection 608 | connect_bd_net [get_bd_pins datapath/data_aclk] [get_bd_pins datapath/trng_wrapper_0/clk] 609 | connect_bd_net [get_bd_pins datapath/data_aclk] [get_bd_pins datapath/system_0/clk] 610 | connect_bd_net [get_bd_pins datapath/data_aclk] [get_bd_pins datapath/ro_pair_wrapper_0/clk] 611 | connect_bd_net [get_bd_pins datapath/data_resetn] [get_bd_pins datapath/trng_wrapper_0/resetn] 612 | connect_bd_net [get_bd_pins datapath/data_resetn] [get_bd_pins datapath/system_0/resetn] 613 | connect_bd_net [get_bd_pins datapath/system_0/pok_resetn] [get_bd_pins datapath/ro_pair_wrapper_0/resetn] 614 | connect_bd_net [get_bd_pins datapath/ro_pair_wrapper_0/e] [get_bd_pins datapath/system_0/e] 615 | connect_bd_net [get_bd_pins datapath/ro_pair_wrapper_0/r] [get_bd_pins datapath/system_0/r] 616 | connect_bd_net [get_bd_pins datapath/ro_pair_wrapper_0/done] [get_bd_pins datapath/system_0/pok_done] 617 | connect_bd_net [get_bd_pins datapath/trng_wrapper_0/random_num] [get_bd_pins datapath/system_0/s_w] 618 | connect_bd_intf_net [get_bd_intf_pins datapath/axi_dma_1/M_AXIS_MM2S] [get_bd_intf_pins datapath/system_0/data_in] 619 | connect_bd_intf_net [get_bd_intf_pins datapath/system_0/data_out] [get_bd_intf_pins datapath/axi_dma_1/S_AXIS_S2MM] 620 | 621 | create_bd_port -dir I mode 622 | create_bd_port -dir I global_start 623 | create_bd_port -dir O check_result 624 | create_bd_port -dir O hash_result 625 | connect_bd_net [get_bd_ports global_start] [get_bd_pins datapath/system_0/global_start] 626 | connect_bd_net [get_bd_ports mode] [get_bd_pins datapath/system_0/mode] 627 | connect_bd_net [get_bd_ports check_result] [get_bd_pins datapath/system_0/check_result] 628 | connect_bd_net [get_bd_ports hash_result] [get_bd_pins datapath/system_0/hash_result] 629 | 630 | startgroup 631 | set_property -dict [list CONFIG.c_m_axi_mm2s_data_width {128} CONFIG.c_m_axis_mm2s_tdata_width {128} CONFIG.c_m_axi_s2mm_data_width {128} CONFIG.c_s2mm_burst_size {4} CONFIG.c_addr_width {32} CONFIG.c_include_mm2s_dre {0} CONFIG.c_mm2s_burst_size {4}] [get_bd_cells datapath/axi_dma_1] 632 | endgroup 633 | 634 | 635 | ################################################# 636 | 637 | # Create port connections 638 | connect_bd_net -net In0_1 [get_bd_pins ctrl/dma_mm2s_irq] [get_bd_pins datapath/mm2s_introut] 639 | connect_bd_net -net In1_1 [get_bd_pins ctrl/dma_s2mm_irq] [get_bd_pins datapath/s2mm_introut] 640 | connect_bd_net -net ctrl_Dout [get_bd_pins ctrl/pkt_length] [get_bd_pins datapath/pkt_length] 641 | connect_bd_net -net ctrl_peripheral_aresetn [get_bd_pins ctrl/tlast_gen_resetn] [get_bd_pins datapath/tlast_gen_resetn] 642 | connect_bd_net -net proc_sys_reset_0_peripheral_aresetn [get_bd_pins ctrl/ctrl_resetn] [get_bd_pins datapath/data_resetn] 643 | connect_bd_net -net processing_system7_1_fclk_clk0 [get_bd_pins ctrl/ctrl_aclk] [get_bd_pins datapath/data_aclk] 644 | 645 | # Create address segments 646 | create_bd_addr_seg -range 0x10000 -offset 0x40400000 [get_bd_addr_spaces ctrl/processing_system7_0/Data] [get_bd_addr_segs datapath/axi_dma_1/S_AXI_LITE/Reg] SEG_axi_dma_1_Reg 647 | create_bd_addr_seg -range 0x10000 -offset 0x41200000 [get_bd_addr_spaces ctrl/processing_system7_0/Data] [get_bd_addr_segs ctrl/gpio/axi_gpio_1/S_AXI/Reg] SEG_axi_gpio_1_Reg 648 | create_bd_addr_seg -range 0x40000000 -offset 0x0 [get_bd_addr_spaces datapath/axi_dma_1/Data_MM2S] [get_bd_addr_segs ctrl/processing_system7_0/S_AXI_HP0/HP0_DDR_LOWOCM] SEG_processing_system7_0_HP0_DDR_LOWOCM 649 | create_bd_addr_seg -range 0x40000000 -offset 0x0 [get_bd_addr_spaces datapath/axi_dma_1/Data_S2MM] [get_bd_addr_segs ctrl/processing_system7_0/S_AXI_HP0/HP0_DDR_LOWOCM] SEG_processing_system7_0_HP0_DDR_LOWOCM 650 | 651 | # Restore current instance 652 | current_bd_instance $oldCurInst 653 | 654 | ####################################################### 655 | #Added by CJ 656 | add_files -fileset constrs_1 -norecurse my_xdc.xdc 657 | add_files -fileset constrs_1 -norecurse ro_450_LUT.xdc 658 | ###################################################### 659 | 660 | save_bd_design 661 | } 662 | # End of create_root_design() 663 | 664 | 665 | ################################################################## 666 | # MAIN FLOW 667 | ################################################################## 668 | 669 | create_root_design "" 670 | --------------------------------------------------------------------------------