From 55bc90e271599d29d6bf3bf5770f8205492362f1 Mon Sep 17 00:00:00 2001
From: Yaman Umuroglu <maltanar@gmail.com>
Date: Sat, 10 Oct 2020 17:29:34 +0200
Subject: [PATCH] [Resource] add example adder verilog generated by HLS

---
 src/finn/qnn-data/verilog/myadd/myadd_myadd.v | 118 ++++++
 .../verilog/myadd/myadd_myadd_control_s_axi.v | 357 ++++++++++++++++++
 2 files changed, 475 insertions(+)
 create mode 100644 src/finn/qnn-data/verilog/myadd/myadd_myadd.v
 create mode 100644 src/finn/qnn-data/verilog/myadd/myadd_myadd_control_s_axi.v

diff --git a/src/finn/qnn-data/verilog/myadd/myadd_myadd.v b/src/finn/qnn-data/verilog/myadd/myadd_myadd.v
new file mode 100644
index 000000000..0b18b5c30
--- /dev/null
+++ b/src/finn/qnn-data/verilog/myadd/myadd_myadd.v
@@ -0,0 +1,118 @@
+// ==============================================================
+// RTL generated by Vivado(TM) HLS - High-Level Synthesis from C, C++ and SystemC
+// Version: 2019.1
+// Copyright (C) 1986-2019 Xilinx, Inc. All Rights Reserved.
+//
+// ===========================================================
+
+`timescale 1 ns / 1 ps
+
+(* CORE_GENERATION_INFO="myadd_myadd,hls_ip_2019_1,{HLS_INPUT_TYPE=cxx,HLS_INPUT_FLOAT=0,HLS_INPUT_FIXED=1,HLS_INPUT_PART=xc7z020-clg400-1,HLS_INPUT_CLOCK=5.000000,HLS_INPUT_ARCH=others,HLS_SYN_CLOCK=3.552000,HLS_SYN_LAT=0,HLS_SYN_TPT=none,HLS_SYN_MEM=0,HLS_SYN_DSP=0,HLS_SYN_FF=144,HLS_SYN_LUT=271,HLS_VERSION=2019_1}" *)
+
+module myadd_myadd (
+        s_axi_control_AWVALID,
+        s_axi_control_AWREADY,
+        s_axi_control_AWADDR,
+        s_axi_control_WVALID,
+        s_axi_control_WREADY,
+        s_axi_control_WDATA,
+        s_axi_control_WSTRB,
+        s_axi_control_ARVALID,
+        s_axi_control_ARREADY,
+        s_axi_control_ARADDR,
+        s_axi_control_RVALID,
+        s_axi_control_RREADY,
+        s_axi_control_RDATA,
+        s_axi_control_RRESP,
+        s_axi_control_BVALID,
+        s_axi_control_BREADY,
+        s_axi_control_BRESP,
+        ap_clk,
+        ap_rst_n,
+        interrupt
+);
+
+parameter    C_S_AXI_CONTROL_DATA_WIDTH = 32;
+parameter    C_S_AXI_CONTROL_ADDR_WIDTH = 6;
+parameter    C_S_AXI_DATA_WIDTH = 32;
+
+parameter C_S_AXI_CONTROL_WSTRB_WIDTH = (32 / 8);
+parameter C_S_AXI_WSTRB_WIDTH = (32 / 8);
+
+input   s_axi_control_AWVALID;
+output   s_axi_control_AWREADY;
+input  [C_S_AXI_CONTROL_ADDR_WIDTH - 1:0] s_axi_control_AWADDR;
+input   s_axi_control_WVALID;
+output   s_axi_control_WREADY;
+input  [C_S_AXI_CONTROL_DATA_WIDTH - 1:0] s_axi_control_WDATA;
+input  [C_S_AXI_CONTROL_WSTRB_WIDTH - 1:0] s_axi_control_WSTRB;
+input   s_axi_control_ARVALID;
+output   s_axi_control_ARREADY;
+input  [C_S_AXI_CONTROL_ADDR_WIDTH - 1:0] s_axi_control_ARADDR;
+output   s_axi_control_RVALID;
+input   s_axi_control_RREADY;
+output  [C_S_AXI_CONTROL_DATA_WIDTH - 1:0] s_axi_control_RDATA;
+output  [1:0] s_axi_control_RRESP;
+output   s_axi_control_BVALID;
+input   s_axi_control_BREADY;
+output  [1:0] s_axi_control_BRESP;
+input   ap_clk;
+input   ap_rst_n;
+output   interrupt;
+
+wire    ap_start;
+wire    ap_done;
+wire    ap_idle;
+wire    ap_ready;
+wire   [31:0] a_V;
+wire   [31:0] b_V;
+wire   [31:0] ap_return;
+ reg    ap_rst_n_inv;
+
+myadd_myadd_control_s_axi #(
+    .C_S_AXI_ADDR_WIDTH( C_S_AXI_CONTROL_ADDR_WIDTH ),
+    .C_S_AXI_DATA_WIDTH( C_S_AXI_CONTROL_DATA_WIDTH ))
+myadd_control_s_axi_U(
+    .AWVALID(s_axi_control_AWVALID),
+    .AWREADY(s_axi_control_AWREADY),
+    .AWADDR(s_axi_control_AWADDR),
+    .WVALID(s_axi_control_WVALID),
+    .WREADY(s_axi_control_WREADY),
+    .WDATA(s_axi_control_WDATA),
+    .WSTRB(s_axi_control_WSTRB),
+    .ARVALID(s_axi_control_ARVALID),
+    .ARREADY(s_axi_control_ARREADY),
+    .ARADDR(s_axi_control_ARADDR),
+    .RVALID(s_axi_control_RVALID),
+    .RREADY(s_axi_control_RREADY),
+    .RDATA(s_axi_control_RDATA),
+    .RRESP(s_axi_control_RRESP),
+    .BVALID(s_axi_control_BVALID),
+    .BREADY(s_axi_control_BREADY),
+    .BRESP(s_axi_control_BRESP),
+    .ACLK(ap_clk),
+    .ARESET(ap_rst_n_inv),
+    .ACLK_EN(1'b1),
+    .ap_start(ap_start),
+    .interrupt(interrupt),
+    .ap_ready(ap_ready),
+    .ap_done(ap_done),
+    .ap_idle(ap_idle),
+    .ap_return(ap_return),
+    .a_V(a_V),
+    .b_V(b_V)
+);
+
+assign ap_done = ap_start;
+
+assign ap_idle = 1'b1;
+
+assign ap_ready = ap_start;
+
+assign ap_return = (b_V + a_V);
+
+always @ (*) begin
+    ap_rst_n_inv = ~ap_rst_n;
+end
+
+endmodule //myadd_myadd
diff --git a/src/finn/qnn-data/verilog/myadd/myadd_myadd_control_s_axi.v b/src/finn/qnn-data/verilog/myadd/myadd_myadd_control_s_axi.v
new file mode 100644
index 000000000..40260ca93
--- /dev/null
+++ b/src/finn/qnn-data/verilog/myadd/myadd_myadd_control_s_axi.v
@@ -0,0 +1,357 @@
+// ==============================================================
+// Vivado(TM) HLS - High-Level Synthesis from C, C++ and SystemC v2019.1 (64-bit)
+// Copyright 1986-2019 Xilinx, Inc. All Rights Reserved.
+// ==============================================================
+`timescale 1ns/1ps
+module myadd_myadd_control_s_axi
+#(parameter
+    C_S_AXI_ADDR_WIDTH = 6,
+    C_S_AXI_DATA_WIDTH = 32
+)(
+    input  wire                          ACLK,
+    input  wire                          ARESET,
+    input  wire                          ACLK_EN,
+    input  wire [C_S_AXI_ADDR_WIDTH-1:0] AWADDR,
+    input  wire                          AWVALID,
+    output wire                          AWREADY,
+    input  wire [C_S_AXI_DATA_WIDTH-1:0] WDATA,
+    input  wire [C_S_AXI_DATA_WIDTH/8-1:0] WSTRB,
+    input  wire                          WVALID,
+    output wire                          WREADY,
+    output wire [1:0]                    BRESP,
+    output wire                          BVALID,
+    input  wire                          BREADY,
+    input  wire [C_S_AXI_ADDR_WIDTH-1:0] ARADDR,
+    input  wire                          ARVALID,
+    output wire                          ARREADY,
+    output wire [C_S_AXI_DATA_WIDTH-1:0] RDATA,
+    output wire [1:0]                    RRESP,
+    output wire                          RVALID,
+    input  wire                          RREADY,
+    output wire                          interrupt,
+    output wire                          ap_start,
+    input  wire                          ap_done,
+    input  wire                          ap_ready,
+    input  wire                          ap_idle,
+    input  wire [31:0]                   ap_return,
+    output wire [31:0]                   a_V,
+    output wire [31:0]                   b_V
+);
+//------------------------Address Info-------------------
+// 0x00 : Control signals
+//        bit 0  - ap_start (Read/Write/SC)
+//        bit 1  - ap_done (Read/COR)
+//        bit 2  - ap_idle (Read)
+//        bit 3  - ap_ready (Read)
+//        bit 7  - auto_restart (Read/Write)
+//        others - reserved
+// 0x04 : Global Interrupt Enable Register
+//        bit 0  - Global Interrupt Enable (Read/Write)
+//        others - reserved
+// 0x08 : IP Interrupt Enable Register (Read/Write)
+//        bit 0  - Channel 0 (ap_done)
+//        others - reserved
+// 0x0c : IP Interrupt Status Register (Read/TOW)
+//        bit 0  - Channel 0 (ap_done)
+//        others - reserved
+// 0x10 : Data signal of ap_return
+//        bit 31~0 - ap_return[31:0] (Read)
+// 0x18 : Data signal of a_V
+//        bit 31~0 - a_V[31:0] (Read/Write)
+// 0x1c : reserved
+// 0x20 : Data signal of b_V
+//        bit 31~0 - b_V[31:0] (Read/Write)
+// 0x24 : reserved
+// (SC = Self Clear, COR = Clear on Read, TOW = Toggle on Write, COH = Clear on Handshake)
+
+//------------------------Parameter----------------------
+localparam
+    ADDR_AP_CTRL     = 6'h00,
+    ADDR_GIE         = 6'h04,
+    ADDR_IER         = 6'h08,
+    ADDR_ISR         = 6'h0c,
+    ADDR_AP_RETURN_0 = 6'h10,
+    ADDR_A_V_DATA_0  = 6'h18,
+    ADDR_A_V_CTRL    = 6'h1c,
+    ADDR_B_V_DATA_0  = 6'h20,
+    ADDR_B_V_CTRL    = 6'h24,
+    WRIDLE           = 2'd0,
+    WRDATA           = 2'd1,
+    WRRESP           = 2'd2,
+    WRRESET          = 2'd3,
+    RDIDLE           = 2'd0,
+    RDDATA           = 2'd1,
+    RDRESET          = 2'd2,
+    ADDR_BITS         = 6;
+
+//------------------------Local signal-------------------
+    reg  [1:0]                    wstate = WRRESET;
+    reg  [1:0]                    wnext;
+    reg  [ADDR_BITS-1:0]          waddr;
+    wire [31:0]                   wmask;
+    wire                          aw_hs;
+    wire                          w_hs;
+    reg  [1:0]                    rstate = RDRESET;
+    reg  [1:0]                    rnext;
+    reg  [31:0]                   rdata;
+    wire                          ar_hs;
+    wire [ADDR_BITS-1:0]          raddr;
+    // internal registers
+    reg                           int_ap_idle;
+    reg                           int_ap_ready;
+    reg                           int_ap_done = 1'b0;
+    reg                           int_ap_start = 1'b0;
+    reg                           int_auto_restart = 1'b0;
+    reg                           int_gie = 1'b0;
+    reg                           int_ier = 1'b0;
+    reg                           int_isr = 1'b0;
+    reg  [31:0]                   int_ap_return;
+    reg  [31:0]                   int_a_V = 'b0;
+    reg  [31:0]                   int_b_V = 'b0;
+
+//------------------------Instantiation------------------
+
+//------------------------AXI write fsm------------------
+assign AWREADY = (wstate == WRIDLE);
+assign WREADY  = (wstate == WRDATA);
+assign BRESP   = 2'b00;  // OKAY
+assign BVALID  = (wstate == WRRESP);
+assign wmask   = { {8{WSTRB[3]}}, {8{WSTRB[2]}}, {8{WSTRB[1]}}, {8{WSTRB[0]}} };
+assign aw_hs   = AWVALID & AWREADY;
+assign w_hs    = WVALID & WREADY;
+
+// wstate
+always @(posedge ACLK) begin
+    if (ARESET)
+        wstate <= WRRESET;
+    else if (ACLK_EN)
+        wstate <= wnext;
+end
+
+// wnext
+always @(*) begin
+    case (wstate)
+        WRIDLE:
+            if (AWVALID)
+                wnext = WRDATA;
+            else
+                wnext = WRIDLE;
+        WRDATA:
+            if (WVALID)
+                wnext = WRRESP;
+            else
+                wnext = WRDATA;
+        WRRESP:
+            if (BREADY)
+                wnext = WRIDLE;
+            else
+                wnext = WRRESP;
+        default:
+            wnext = WRIDLE;
+    endcase
+end
+
+// waddr
+always @(posedge ACLK) begin
+    if (ACLK_EN) begin
+        if (aw_hs)
+            waddr <= AWADDR[ADDR_BITS-1:0];
+    end
+end
+
+//------------------------AXI read fsm-------------------
+assign ARREADY = (rstate == RDIDLE);
+assign RDATA   = rdata;
+assign RRESP   = 2'b00;  // OKAY
+assign RVALID  = (rstate == RDDATA);
+assign ar_hs   = ARVALID & ARREADY;
+assign raddr   = ARADDR[ADDR_BITS-1:0];
+
+// rstate
+always @(posedge ACLK) begin
+    if (ARESET)
+        rstate <= RDRESET;
+    else if (ACLK_EN)
+        rstate <= rnext;
+end
+
+// rnext
+always @(*) begin
+    case (rstate)
+        RDIDLE:
+            if (ARVALID)
+                rnext = RDDATA;
+            else
+                rnext = RDIDLE;
+        RDDATA:
+            if (RREADY & RVALID)
+                rnext = RDIDLE;
+            else
+                rnext = RDDATA;
+        default:
+            rnext = RDIDLE;
+    endcase
+end
+
+// rdata
+always @(posedge ACLK) begin
+    if (ACLK_EN) begin
+        if (ar_hs) begin
+            rdata <= 1'b0;
+            case (raddr)
+                ADDR_AP_CTRL: begin
+                    rdata[0] <= int_ap_start;
+                    rdata[1] <= int_ap_done;
+                    rdata[2] <= int_ap_idle;
+                    rdata[3] <= int_ap_ready;
+                    rdata[7] <= int_auto_restart;
+                end
+                ADDR_GIE: begin
+                    rdata <= int_gie;
+                end
+                ADDR_IER: begin
+                    rdata <= int_ier;
+                end
+                ADDR_ISR: begin
+                    rdata <= int_isr;
+                end
+                ADDR_AP_RETURN_0: begin
+                    rdata <= int_ap_return[31:0];
+                end
+                ADDR_A_V_DATA_0: begin
+                    rdata <= int_a_V[31:0];
+                end
+                ADDR_B_V_DATA_0: begin
+                    rdata <= int_b_V[31:0];
+                end
+            endcase
+        end
+    end
+end
+
+
+//------------------------Register logic-----------------
+assign interrupt = int_gie & (|int_isr);
+assign ap_start  = int_ap_start;
+assign a_V       = int_a_V;
+assign b_V       = int_b_V;
+// int_ap_start
+always @(posedge ACLK) begin
+    if (ARESET)
+        int_ap_start <= 1'b0;
+    else if (ACLK_EN) begin
+        if (w_hs && waddr == ADDR_AP_CTRL && WSTRB[0] && WDATA[0])
+            int_ap_start <= 1'b1;
+        else if (ap_done & int_auto_restart)
+            int_ap_start <= 1'b1; // auto restart
+        else
+            int_ap_start <= 1'b0; // self clear
+    end
+end
+
+// int_ap_done
+always @(posedge ACLK) begin
+    if (ARESET)
+        int_ap_done <= 1'b0;
+    else if (ACLK_EN) begin
+        if (ap_done)
+            int_ap_done <= 1'b1;
+        else if (ar_hs && raddr == ADDR_AP_CTRL)
+            int_ap_done <= 1'b0; // clear on read
+    end
+end
+
+// int_ap_idle
+always @(posedge ACLK) begin
+    if (ARESET)
+        int_ap_idle <= 1'b0;
+    else if (ACLK_EN) begin
+            int_ap_idle <= ap_idle;
+    end
+end
+
+// int_ap_ready
+always @(posedge ACLK) begin
+    if (ARESET)
+        int_ap_ready <= 1'b0;
+    else if (ACLK_EN) begin
+            int_ap_ready <= ap_ready;
+    end
+end
+
+// int_auto_restart
+always @(posedge ACLK) begin
+    if (ARESET)
+        int_auto_restart <= 1'b0;
+    else if (ACLK_EN) begin
+        if (w_hs && waddr == ADDR_AP_CTRL && WSTRB[0])
+            int_auto_restart <=  WDATA[7];
+    end
+end
+
+// int_gie
+always @(posedge ACLK) begin
+    if (ARESET)
+        int_gie <= 1'b0;
+    else if (ACLK_EN) begin
+        if (w_hs && waddr == ADDR_GIE && WSTRB[0])
+            int_gie <= WDATA[0];
+    end
+end
+
+// int_ier
+always @(posedge ACLK) begin
+    if (ARESET)
+        int_ier <= 1'b0;
+    else if (ACLK_EN) begin
+        if (w_hs && waddr == ADDR_IER && WSTRB[0])
+            int_ier <= WDATA[0];
+    end
+end
+
+// int_isr
+always @(posedge ACLK) begin
+    if (ARESET)
+        int_isr <= 1'b0;
+    else if (ACLK_EN) begin
+        if (int_ier & ap_done)
+            int_isr <= 1'b1;
+        else if (w_hs && waddr == ADDR_ISR && WSTRB[0])
+            int_isr <= int_isr ^ WDATA[0]; // toggle on write
+    end
+end
+
+// int_ap_return
+always @(posedge ACLK) begin
+    if (ARESET)
+        int_ap_return <= 0;
+    else if (ACLK_EN) begin
+        if (ap_done)
+            int_ap_return <= ap_return;
+    end
+end
+
+// int_a_V[31:0]
+always @(posedge ACLK) begin
+    if (ARESET)
+        int_a_V[31:0] <= 0;
+    else if (ACLK_EN) begin
+        if (w_hs && waddr == ADDR_A_V_DATA_0)
+            int_a_V[31:0] <= (WDATA[31:0] & wmask) | (int_a_V[31:0] & ~wmask);
+    end
+end
+
+// int_b_V[31:0]
+always @(posedge ACLK) begin
+    if (ARESET)
+        int_b_V[31:0] <= 0;
+    else if (ACLK_EN) begin
+        if (w_hs && waddr == ADDR_B_V_DATA_0)
+            int_b_V[31:0] <= (WDATA[31:0] & wmask) | (int_b_V[31:0] & ~wmask);
+    end
+end
+
+
+//------------------------Memory logic-------------------
+
+endmodule
-- 
GitLab