updates for AWS build and to help timing
This commit is contained in:
parent
957e47e7ca
commit
3ac213ee3b
|
@ -1,3 +1,3 @@
|
|||
# AWS FPGA Top level and Simulation
|
||||
|
||||
This "zcash_fpga" folder should be linked into the /hdk/cl/developer_designs/ on your AWS instance.
|
||||
# AWS FPGA Top level and Simulation
|
||||
|
||||
This "cl_zcash" folder should be linked into the /hdk/cl/developer_designs/ on your AWS instance.
|
|
@ -1,73 +0,0 @@
|
|||
# Hello World CL Example
|
||||
|
||||
|
||||
## :exclamation: NOTE: If this is your first time using F1, you should read [How To Create an Amazon FPGA Image (AFI) From One of The CL Examples: Step-by-Step Guide](./../../../README.md) first!!
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [Overview](#overview)
|
||||
2. [Functional Description](#description)
|
||||
3. [Hello World Example Metadata](#metadata)
|
||||
|
||||
|
||||
<a name="overview"></a>
|
||||
## Overview
|
||||
|
||||
This simple *hello_world* example builds a Custom Logic (CL) that will enable the instance to "peek" and "poke" registers in the Custom Logic (CL).
|
||||
These registers will be in the memory space behind AppPF BAR0, which is the ocl\_cl\_ AXI-lite bus on the Shell to CL interface.
|
||||
|
||||
This example demonstrate a basic use-case of the Virtual LED and Virtual DIP switches.
|
||||
|
||||
All of the unused interfaces between AWS Shell and the CL are tied to fixed values, and it is recommended that the developer use similar values for every unused interface in the developer's CL.
|
||||
|
||||
|
||||
<a name="description"></a>
|
||||
## Functional Description
|
||||
|
||||
The cl_hello_world example demonstrates basic Shell-to-CL connectivity, memory-mapped register instantiations and the use of the Virtual LED and DIP switches. The cl_hello_world example implements two registers in the FPGA AppPF BAR0 memory space connected to the OCL AXI-L interface. The two registers are:
|
||||
|
||||
1. Hello World Register (offset 0x500)
|
||||
2. Virtual LED Register (offset 0x504)
|
||||
|
||||
Please refer to the [FPGA PCIe memory space overview](../../../docs/AWS_Fpga_Pcie_Memory_Map.md)
|
||||
|
||||
The Hello World Register is a 32-bit read/write register. However, in order to demonstrate that the register is being accessed correctly, the read data returned for the register will be byte swapped.
|
||||
|
||||
The Virtual LED register is a 16-bit read-only register that shadows the lower 16 bits of the Hello World Register such that it will hold the same value as bits 15:0 of the Hello World Register.
|
||||
|
||||
The cl_hello_world design utilizes the Virtual LED and DIP switch interface which consistes of two signals described in the [cl_ports.vh] (./../../../common/shell_stable/design/interfaces/cl_ports.vh) file:
|
||||
|
||||
|
||||
```
|
||||
input[15:0] sh_cl_status_vdip, //Virtual DIP switches. Controlled through FPGA management PF and tools.
|
||||
output logic[15:0] cl_sh_status_vled, //Virtual LEDs, monitored through FPGA management PF and tools
|
||||
```
|
||||
|
||||
In this example the Virtual LED Register is used to drive the Virtual LED signal, cl_sh_status_vled. In addition, the Virtual DIP switch, sh_cl_status_vdip, is used to gate the Virtual LED Register value sent to the Virtual LEDs. So, for example, if the sh_cl_status_vdip is set to 16'h00FF, then only the lower 8 bits of the Virtual LED Register will be signaled on the Virtual LED signal cl_sh_status_vled.
|
||||
|
||||
While running on F1, the developer can use the FPGA tools `fpga-get-virtual-led` to read the LED values on the CL-to-Shell interface. While `fpga-set-virtual-dip-switch` tool is used to set the DIP switch values on the Shell-to-CL interface.
|
||||
|
||||
|
||||
### Unused interfaces
|
||||
|
||||
The Hello World example does not use most of AWS Shell interface, hence the unused signals are tied off.
|
||||
At the end of `cl_hello_world.sv` file, there is a specific `include` command for an interface-specific `.inc` file, to handle the tie-off\'s for every unused interface.
|
||||
|
||||
|
||||
<a name="metadata"></a>
|
||||
## Hello World Example Metadata
|
||||
|
||||
The following table displays information about the CL that is required to register it as an AFI with AWS.
|
||||
Alternatively, you can directly use a pre-generated AFI for this CL.
|
||||
|
||||
|
||||
| Key | Value |
|
||||
|-----------|------|
|
||||
| Shell Version | 0x04261818 |
|
||||
| PCI Device ID | 0xF000 |
|
||||
| PCI Vendor ID | 0x1D0F (Amazon) |
|
||||
| PCI Subsystem ID | 0x1D51 |
|
||||
| PCI Subsystem Vendor ID | 0xFEDD |
|
||||
| Pre-generated AFI ID | afi-03d11a4ea66e883ef |
|
||||
| Pre-generated AGFI ID | agfi-0fcf87119b8e97bf3 |
|
||||
|
|
@ -58,51 +58,51 @@ always_ff @ (posedge i_clk) begin
|
|||
end
|
||||
|
||||
// Map the AXI-lite signals
|
||||
logic wr_active;
|
||||
logic wr_active, rd_active;
|
||||
logic [31:0] wr_addr, araddr;
|
||||
|
||||
logic axi_fifo_dec;
|
||||
logic zcash_dec;
|
||||
|
||||
always_comb begin
|
||||
zcash_dec = (wr_addr >= `ZCASH_OFFSET && wr_addr < (`ZCASH_OFFSET + `AXI_MEMORY_SIZE)) ||
|
||||
(araddr >= `ZCASH_OFFSET && araddr < (`ZCASH_OFFSET + `AXI_MEMORY_SIZE));
|
||||
zcash_dec = (wr_active && wr_addr >= `ZCASH_OFFSET && wr_addr < (`ZCASH_OFFSET + `AXI_MEMORY_SIZE)) ||
|
||||
(rd_active && araddr >= `ZCASH_OFFSET && araddr < (`ZCASH_OFFSET + `AXI_MEMORY_SIZE));
|
||||
|
||||
axi_fifo_dec = (wr_addr >= `AXI_FIFO_OFFSET && wr_addr < (`AXI_FIFO_OFFSET + `AXI_MEMORY_SIZE)) ||
|
||||
(araddr >= `AXI_FIFO_OFFSET && araddr < (`AXI_FIFO_OFFSET + `AXI_MEMORY_SIZE));
|
||||
axi_fifo_dec = (wr_active && wr_addr >= `AXI_FIFO_OFFSET && wr_addr < (`AXI_FIFO_OFFSET + `AXI_MEMORY_SIZE)) ||
|
||||
(rd_active && araddr >= `AXI_FIFO_OFFSET && araddr < (`AXI_FIFO_OFFSET + `AXI_MEMORY_SIZE));
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
zcash_axi_lite_if.awvalid = rx_axi_lite_if.awvalid && zcash_dec;
|
||||
zcash_axi_lite_if.awaddr = rx_axi_lite_if.awaddr;
|
||||
zcash_axi_lite_if.wvalid = rx_axi_lite_if.wvalid;
|
||||
zcash_axi_lite_if.awaddr = rx_axi_lite_if.awaddr - `ZCASH_OFFSET;
|
||||
zcash_axi_lite_if.wvalid = rx_axi_lite_if.wvalid && zcash_dec;
|
||||
zcash_axi_lite_if.wdata = rx_axi_lite_if.wdata;
|
||||
zcash_axi_lite_if.wstrb = rx_axi_lite_if.wstrb;
|
||||
zcash_axi_lite_if.bready = rx_axi_lite_if.bready;
|
||||
zcash_axi_lite_if.arvalid = rx_axi_lite_if.arvalid;
|
||||
zcash_axi_lite_if.arvalid = rx_axi_lite_if.arvalid && zcash_dec;
|
||||
zcash_axi_lite_if.rready = rx_axi_lite_if.rready;
|
||||
zcash_axi_lite_if.araddr = rx_axi_lite_if.araddr;
|
||||
zcash_axi_lite_if.arvalid = rx_axi_lite_if.arvalid;
|
||||
zcash_axi_lite_if.araddr = rx_axi_lite_if.araddr - `ZCASH_OFFSET;
|
||||
zcash_axi_lite_if.arvalid = rx_axi_lite_if.arvalid && zcash_dec;
|
||||
|
||||
axi_fifo_if.awvalid = rx_axi_lite_if.awvalid && axi_fifo_dec;
|
||||
axi_fifo_if.awaddr = rx_axi_lite_if.awaddr;
|
||||
axi_fifo_if.wvalid = rx_axi_lite_if.wvalid;
|
||||
axi_fifo_if.awaddr = rx_axi_lite_if.awaddr - `AXI_FIFO_OFFSET;
|
||||
axi_fifo_if.wvalid = rx_axi_lite_if.wvalid && axi_fifo_dec;
|
||||
axi_fifo_if.wdata = rx_axi_lite_if.wdata;
|
||||
axi_fifo_if.wstrb = rx_axi_lite_if.wstrb;
|
||||
axi_fifo_if.bready = rx_axi_lite_if.bready;
|
||||
axi_fifo_if.arvalid = rx_axi_lite_if.arvalid;
|
||||
axi_fifo_if.arvalid = rx_axi_lite_if.arvalid && axi_fifo_dec;
|
||||
axi_fifo_if.rready = rx_axi_lite_if.rready;
|
||||
axi_fifo_if.araddr = rx_axi_lite_if.araddr;
|
||||
axi_fifo_if.arvalid = rx_axi_lite_if.arvalid;
|
||||
axi_fifo_if.araddr = rx_axi_lite_if.araddr - `AXI_FIFO_OFFSET;
|
||||
axi_fifo_if.arvalid = rx_axi_lite_if.arvalid && axi_fifo_dec;
|
||||
|
||||
|
||||
rx_axi_lite_if.awready = zcash_dec ? zcash_axi_lite_if.awready : axi_fifo_if.awready;
|
||||
rx_axi_lite_if.wready = zcash_dec ? zcash_axi_lite_if.wready : axi_fifo_if.wready;
|
||||
rx_axi_lite_if.bvalid = zcash_dec ? zcash_axi_lite_if.bvalid : axi_fifo_if.bvalid;
|
||||
rx_axi_lite_if.awready = zcash_dec ? zcash_axi_lite_if.awready : axi_fifo_dec ? axi_fifo_if.awready : 0;
|
||||
rx_axi_lite_if.wready = zcash_dec ? zcash_axi_lite_if.wready : axi_fifo_dec ? axi_fifo_if.wready : 0;
|
||||
rx_axi_lite_if.bvalid = zcash_dec ? zcash_axi_lite_if.bvalid : axi_fifo_dec ? axi_fifo_if.bvalid : 0;
|
||||
rx_axi_lite_if.bresp = 0;
|
||||
rx_axi_lite_if.arready = zcash_dec ? zcash_axi_lite_if.arready : axi_fifo_if.arready;
|
||||
rx_axi_lite_if.rvalid = zcash_dec ? zcash_axi_lite_if.rvalid : axi_fifo_if.rvalid;
|
||||
rx_axi_lite_if.rdata = zcash_dec ? zcash_axi_lite_if.rdata : axi_fifo_if.rdata;
|
||||
rx_axi_lite_if.arready = zcash_dec ? zcash_axi_lite_if.arready : axi_fifo_dec ? axi_fifo_if.arready : 0;
|
||||
rx_axi_lite_if.rvalid = zcash_dec ? zcash_axi_lite_if.rvalid : axi_fifo_dec ? axi_fifo_if.rvalid : 0;
|
||||
rx_axi_lite_if.rdata = zcash_dec ? zcash_axi_lite_if.rdata : axi_fifo_dec ? axi_fifo_if.rdata : 32'h0;
|
||||
rx_axi_lite_if.rresp = 0;
|
||||
end
|
||||
|
||||
|
@ -112,10 +112,11 @@ always_ff @(posedge i_clk) begin
|
|||
wr_active <= 0;
|
||||
wr_addr <= 0;
|
||||
end else begin
|
||||
wr_active <= wr_active && rx_axi_lite_if.bvalid && rx_axi_lite_if.bready ? 1'b0 :
|
||||
~wr_active && rx_axi_lite_if.awvalid ? 1'b1 :
|
||||
wr_active;
|
||||
wr_addr <= rx_axi_lite_if.awvalid && ~wr_active ? rx_axi_lite_if.awaddr : wr_addr;
|
||||
|
||||
if (rx_axi_lite_if.bvalid && rx_axi_lite_if.bready) wr_active <= 0;
|
||||
if (rx_axi_lite_if.awvalid) wr_active <= 1;
|
||||
if (rx_axi_lite_if.awvalid && ~wr_active) wr_addr <= rx_axi_lite_if.awaddr;
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -123,8 +124,13 @@ end
|
|||
always_ff @(posedge i_clk) begin
|
||||
if (i_rst) begin
|
||||
araddr <= 0;
|
||||
rd_active <= 0;
|
||||
end else begin
|
||||
araddr <= rx_axi_lite_if.arvalid ? rx_axi_lite_if.araddr : araddr;
|
||||
|
||||
if (rx_axi_lite_if.rvalid && rx_axi_lite_if.rready) rd_active <= 0;
|
||||
if (rx_axi_lite_if.arvalid) rd_active <= 1;
|
||||
if (rx_axi_lite_if.arvalid && ~rd_active ) araddr <= rx_axi_lite_if.araddr;
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -214,7 +220,7 @@ axi_fifo_mm_s_0 axi_fifo_mm_s_0 (
|
|||
.s_axi4_arprot ( rx_axi4_if.arprot ),
|
||||
.s_axi4_arvalid( rx_axi4_if.arvalid ),
|
||||
.s_axi4_arready( rx_axi4_if.arready ),
|
||||
.s_axi4_rid ( rx_axi4_if.rid ),
|
||||
.s_axi4_rid ( ),
|
||||
.s_axi4_rdata ( rx_axi4_if.rdata ),
|
||||
.s_axi4_rresp ( rx_axi4_if.rresp ),
|
||||
.s_axi4_rlast ( rx_axi4_if.rlast ),
|
||||
|
@ -233,4 +239,9 @@ axi_fifo_mm_s_0 axi_fifo_mm_s_0 (
|
|||
.axi_str_rxd_tlast ( tx_aws_if.eop ),
|
||||
.axi_str_rxd_tdata ( tx_aws_if.dat )
|
||||
);
|
||||
endmodule
|
||||
|
||||
always_comb begin
|
||||
rx_axi4_if.rid = 0;
|
||||
end
|
||||
|
||||
endmodule
|
|
@ -13,6 +13,10 @@
|
|||
// implied. See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// This runs several tests for the Zcash FPGA:
|
||||
// Status message (AXI stream interface)
|
||||
// AXI-lite interface
|
||||
// BLS12_381 coprocessor
|
||||
|
||||
module test_zcash();
|
||||
|
||||
|
@ -23,6 +27,9 @@ import tb_type_defines_pkg::*;
|
|||
parameter [5:0] AXI_ID = 6'h0;
|
||||
|
||||
import zcash_fpga_pkg::*;
|
||||
import secp256k1_pkg::*;
|
||||
import equihash_pkg::*;
|
||||
import common_pkg::*;
|
||||
|
||||
zcash_fpga_pkg::header_t header;
|
||||
zcash_fpga_pkg::fpga_status_rpl_t fpga_status_rpl;
|
||||
|
@ -30,56 +37,30 @@ zcash_fpga_pkg::fpga_status_rpl_t fpga_status_rpl;
|
|||
logic [31:0] rdata;
|
||||
logic [1024*8-1:0] stream_data;
|
||||
integer stream_len;
|
||||
logic [15:0] vdip_value;
|
||||
logic [15:0] vled_value;
|
||||
|
||||
|
||||
initial begin
|
||||
initial begin
|
||||
|
||||
tb.power_up();
|
||||
|
||||
|
||||
read_ocl_reg(.addr(`AXI_FIFO_OFFSET), .exp_data(32'h01D00000), .rdata(rdata)); //ISR
|
||||
write_ocl_reg(.addr(`AXI_FIFO_OFFSET), .data(32'hFFFFFFFF)); // Reset ISR
|
||||
read_ocl_reg(.addr(`AXI_FIFO_OFFSET+32'hC), .exp_data(32'h000001FC), .rdata(rdata)); //TDFV
|
||||
read_ocl_reg(.addr(`AXI_FIFO_OFFSET+32'h1C), .exp_data(32'h00000000), .rdata(rdata)); //RDFO
|
||||
tb.power_up();
|
||||
|
||||
write_ocl_reg(.addr(`AXI_FIFO_OFFSET+32'h4), .data(32'h0C000000)); //IER
|
||||
// Setup the AXI streaming interface
|
||||
read_ocl_reg(.addr(`AXI_FIFO_OFFSET), .exp_data(32'h01D00000), .rdata(rdata)); //ISR
|
||||
write_ocl_reg(.addr(`AXI_FIFO_OFFSET), .data(32'hFFFFFFFF)); // Reset ISR
|
||||
read_ocl_reg(.addr(`AXI_FIFO_OFFSET+32'hC), .exp_data(32'h000001FC), .rdata(rdata)); //TDFV
|
||||
read_ocl_reg(.addr(`AXI_FIFO_OFFSET+32'h1C), .exp_data(32'h00000000), .rdata(rdata)); //RDFO
|
||||
write_ocl_reg(.addr(`AXI_FIFO_OFFSET+32'h4), .data(32'h0C000000)); //IER
|
||||
|
||||
// Build a status message and send it
|
||||
header.cmd = zcash_fpga_pkg::FPGA_STATUS;
|
||||
header.len = $bits(header_t)/8;
|
||||
// Run our test cases
|
||||
test_status_message();
|
||||
test_block_secp256k1();
|
||||
|
||||
write_stream(.data(header), .len(header.len));
|
||||
stream_len = 0;
|
||||
fork
|
||||
begin
|
||||
while(stream_len == 0) read_stream(.data(stream_data), .len(stream_len));
|
||||
end
|
||||
begin
|
||||
while(10000) @(posedge tb.card.fpga.clk_main_a0);
|
||||
$fatal(1, "ERROR: No reply received from status_request");
|
||||
end
|
||||
join_any
|
||||
disable fork;
|
||||
$display("INFO: All tests passed");
|
||||
tb.kernel_reset();
|
||||
|
||||
fpga_status_rpl = stream_data;
|
||||
tb.power_down();
|
||||
|
||||
$display("INFO: Received status reply");
|
||||
$display("%p", fpga_status_rpl);
|
||||
$display("Version: 0x%x", fpga_status_rpl.version);
|
||||
|
||||
if (fpga_status_rpl.version != zcash_fpga_pkg::FPGA_VERSION)
|
||||
$fatal(1, "FPGA Version was wrong");
|
||||
|
||||
|
||||
$display("INFO: Test passed");
|
||||
tb.kernel_reset();
|
||||
|
||||
tb.power_down();
|
||||
|
||||
$finish;
|
||||
end
|
||||
$finish;
|
||||
end
|
||||
|
||||
task read_ocl_reg(input logic [31:0] addr, output logic [31:0] rdata, input logic [31:0] exp_data = 32'hXXXXXXXX);
|
||||
|
||||
|
@ -121,7 +102,7 @@ task write_stream(input logic [1024*8-1:0] data, input integer len);
|
|||
endtask
|
||||
|
||||
task read_stream(output logic [1024*8-1:0] data, integer len);
|
||||
|
||||
|
||||
logic [31:0] rdata;
|
||||
logic [511:0] pcis_data;
|
||||
len = 0;
|
||||
|
@ -138,9 +119,88 @@ task read_stream(output logic [1024*8-1:0] data, integer len);
|
|||
tb.peek_pcis(.addr(32'h1000), .data(pcis_data));
|
||||
data[len*8 +: 512] = pcis_data;
|
||||
len = len + rdata > (512/8) ? 512/8 : rdata/8;
|
||||
rdata = rdata < 512/8 ? 0 : rdata - 512/8;
|
||||
rdata = rdata < 512/8 ? 0 : rdata - 512/8;
|
||||
end
|
||||
|
||||
endtask
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Various test cases below
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Build a status message and send it
|
||||
task test_status_message();
|
||||
|
||||
header.cmd = zcash_fpga_pkg::FPGA_STATUS;
|
||||
header.len = $bits(header_t)/8;
|
||||
|
||||
write_stream(.data(header), .len(header.len));
|
||||
stream_len = 0;
|
||||
fork
|
||||
begin
|
||||
while(stream_len == 0) read_stream(.data(stream_data), .len(stream_len));
|
||||
end
|
||||
begin
|
||||
while(10000) @(posedge tb.card.fpga.clk_main_a0);
|
||||
$fatal(1, "ERROR: No reply received from status_request");
|
||||
end
|
||||
join_any
|
||||
disable fork;
|
||||
|
||||
fpga_status_rpl = stream_data;
|
||||
|
||||
$display("INFO: Received status reply");
|
||||
$display("%p", fpga_status_rpl);
|
||||
$display("INFO: FPGA Version: 0x%x", fpga_status_rpl.version);
|
||||
|
||||
if (fpga_status_rpl.version != zcash_fpga_pkg::FPGA_VERSION)
|
||||
$fatal(1, "ERROR: FPGA Version was wrong");
|
||||
|
||||
$display("INFO: test_status_message() PASSED");
|
||||
|
||||
endtask
|
||||
|
||||
// Test secp256k1 signature verification
|
||||
task test_block_secp256k1();
|
||||
begin
|
||||
logic fail = 0;
|
||||
verify_secp256k1_sig_t verify_secp256k1_sig;
|
||||
verify_secp256k1_sig_rpl_t verify_secp256k1_sig_rpl;
|
||||
|
||||
$display("Running test_block_secp256k1...");
|
||||
verify_secp256k1_sig.hdr.cmd = VERIFY_SECP256K1_SIG;
|
||||
verify_secp256k1_sig.hdr.len = $bits(verify_secp256k1_sig_t)/8;
|
||||
verify_secp256k1_sig.index = 1;
|
||||
verify_secp256k1_sig.hash = 256'h4c7dbc46486ad9569442d69b558db99a2612c4f003e6631b593942f531e67fd4;
|
||||
verify_secp256k1_sig.r = 256'h1375af664ef2b74079687956fd9042e4e547d57c4438f1fc439cbfcb4c9ba8b;
|
||||
verify_secp256k1_sig.s = 256'hde0f72e442f7b5e8e7d53274bf8f97f0674f4f63af582554dbecbb4aa9d5cbcb;
|
||||
verify_secp256k1_sig.Qx = 256'h808a2c66c5b90fa1477d7820fc57a8b7574cdcb8bd829bdfcf98aa9c41fde3b4;
|
||||
verify_secp256k1_sig.Qy = 256'heed249ffde6e46d784cb53b4df8c9662313c1ce8012da56cb061f12e55a32249;
|
||||
|
||||
|
||||
write_stream(verify_secp256k1_sig, $bits(verify_secp256k1_sig)/8);
|
||||
stream_len = 0;
|
||||
fork
|
||||
begin
|
||||
while(stream_len == 0) read_stream(.data(stream_data), .len(stream_len));
|
||||
end
|
||||
begin
|
||||
while(100000) @(posedge tb.card.fpga.clk_main_a0);
|
||||
$fatal(1, "ERROR: No reply received from verify_secp256k1");
|
||||
end
|
||||
join_any
|
||||
disable fork;
|
||||
|
||||
verify_secp256k1_sig_rpl = stream_data;
|
||||
|
||||
fail |= verify_secp256k1_sig_rpl.hdr.cmd != VERIFY_SECP256K1_SIG_RPL;
|
||||
fail |= (verify_secp256k1_sig_rpl.bm != 0);
|
||||
fail |= (verify_secp256k1_sig_rpl.index != verify_secp256k1_sig.index);
|
||||
assert (~fail) else $fatal(1, "%m ERROR: test_block_secp256k1 failed :\n%p", verify_secp256k1_sig_rpl);
|
||||
|
||||
|
||||
$display("test_block_secp256k1 PASSED");
|
||||
end
|
||||
endtask;
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -22,10 +22,12 @@ module bls12_381_axi_bridge (
|
|||
if_axi_lite.sink axi_lite_if,
|
||||
if_ram.source data_ram_if,
|
||||
if_ram.source inst_ram_if,
|
||||
|
||||
|
||||
// Configuration signals
|
||||
input [31:0] i_curr_inst_pt,
|
||||
input [31:0] i_last_inst_cnt
|
||||
input [31:0] i_last_inst_cnt,
|
||||
output logic [31:0] o_new_inst_pt,
|
||||
output logic o_new_inst_pt_val
|
||||
);
|
||||
|
||||
import bls12_381_pkg::*;
|
||||
|
@ -41,6 +43,7 @@ logic [31:0] last_inst_cnt;
|
|||
always_ff @ (posedge i_clk) begin
|
||||
curr_inst_pt <= i_curr_inst_pt;
|
||||
last_inst_cnt <= i_last_inst_cnt;
|
||||
|
||||
end
|
||||
|
||||
always_ff @ (posedge i_clk) begin
|
||||
|
@ -52,7 +55,12 @@ always_ff @ (posedge i_clk) begin
|
|||
inst_ram_read <= 0;
|
||||
wr_active <= 0;
|
||||
wr_addr <= 0;
|
||||
o_new_inst_pt_val <= 0;
|
||||
o_new_inst_pt <= 0;
|
||||
end else begin
|
||||
|
||||
o_new_inst_pt_val <= 0;
|
||||
|
||||
data_ram_read <= data_ram_read << 1;
|
||||
inst_ram_read <= inst_ram_read << 1;
|
||||
|
||||
|
@ -66,7 +74,7 @@ always_ff @ (posedge i_clk) begin
|
|||
|
||||
axi_lite_if.arready <= data_ram_read == 0 && inst_ram_read == 0 &&
|
||||
axi_lite_if.arvalid == 0 && wr_active == 0;
|
||||
|
||||
|
||||
axi_lite_if.awready <= data_ram_read == 0 && inst_ram_read == 0 &&
|
||||
axi_lite_if.awvalid == 0 && wr_active == 0;
|
||||
|
||||
|
@ -124,8 +132,15 @@ always_ff @ (posedge i_clk) begin
|
|||
if (axi_lite_if.wready && axi_lite_if.wvalid) begin
|
||||
axi_lite_if.bvalid <= 1;
|
||||
if (wr_addr < INST_AXIL_START) begin
|
||||
// Config area - all RO
|
||||
// Config area
|
||||
case(wr_addr)
|
||||
32'h10: begin // This updates the current instruction pointer
|
||||
o_new_inst_pt_val <= 1;
|
||||
o_new_inst_pt <= axi_lite_if.wdata;
|
||||
end
|
||||
endcase
|
||||
end else
|
||||
// TODO change this to be atomic writes
|
||||
if (wr_addr < DATA_AXIL_START) begin
|
||||
// Instruction memory
|
||||
inst_ram_if.we <= 0;
|
||||
|
|
|
@ -79,6 +79,9 @@ if_axi_stream #(.DAT_BITS($bits(bls12_381_pkg::fe_t)), .CTL_BITS(16)) sub_out_
|
|||
if_axi_stream #(.DAT_BITS($bits(bls12_381_pkg::fe_t))) binv_i_if(i_clk);
|
||||
if_axi_stream #(.DAT_BITS($bits(bls12_381_pkg::fe_t))) binv_o_if(i_clk);
|
||||
|
||||
logic [31:0] new_inst_pt;
|
||||
logic new_inst_pt_val, new_inst_pt_val_l;
|
||||
|
||||
logic [7:0] cnt;
|
||||
integer unsigned pt_size;
|
||||
|
||||
|
@ -116,7 +119,13 @@ always_ff @ (posedge i_clk) begin
|
|||
idx_in_if.reset_source();
|
||||
interrupt_in_if.reset_source();
|
||||
last_inst_cnt <= 0;
|
||||
|
||||
new_inst_pt_val_l <= 0;
|
||||
|
||||
end else begin
|
||||
|
||||
new_inst_pt_val_l <= new_inst_pt_val || new_inst_pt_val_l; // Latch this pulse if we want to update instruction pointer
|
||||
|
||||
inst_ram_sys_if.re <= 1;
|
||||
inst_ram_sys_if.en <= 1;
|
||||
inst_ram_read <= inst_ram_read << 1;
|
||||
|
@ -141,8 +150,7 @@ always_ff @ (posedge i_clk) begin
|
|||
NOOP_WAIT: begin
|
||||
last_inst_cnt <= last_inst_cnt;
|
||||
// Wait in this state
|
||||
inst_state <= curr_inst.code;
|
||||
cnt <= 0;
|
||||
get_next_inst();
|
||||
end
|
||||
COPY_REG: begin
|
||||
inst_state <= curr_inst.code;
|
||||
|
@ -170,17 +178,20 @@ always_ff @ (posedge i_clk) begin
|
|||
task_fp2_fpoint_mult();
|
||||
end
|
||||
endcase
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
bls12_381_axi_bridge bls12_381_axi_bridge (
|
||||
.i_clk ( i_clk ),
|
||||
.i_rst ( i_rst ),
|
||||
.axi_lite_if ( axi_lite_if ),
|
||||
.data_ram_if ( data_ram_usr_if ),
|
||||
.inst_ram_if ( inst_ram_usr_if ),
|
||||
.i_curr_inst_pt ( curr_inst_pt ),
|
||||
.i_last_inst_cnt ( last_inst_cnt )
|
||||
.axi_lite_if ( axi_lite_if ),
|
||||
.data_ram_if ( data_ram_usr_if ),
|
||||
.inst_ram_if ( inst_ram_usr_if ),
|
||||
.i_curr_inst_pt ( curr_inst_pt ),
|
||||
.i_last_inst_cnt ( last_inst_cnt ),
|
||||
.o_new_inst_pt ( new_inst_pt ),
|
||||
.o_new_inst_pt_val ( new_inst_pt_val )
|
||||
);
|
||||
|
||||
always_comb begin
|
||||
|
@ -277,8 +288,8 @@ resource_share # (
|
|||
.DAT_BITS ( 2*$bits(bls12_381_pkg::fe_t) ),
|
||||
.CTL_BITS ( 16 ),
|
||||
.OVR_WRT_BIT ( 14 ),
|
||||
.PIPELINE_IN ( 0 ),
|
||||
.PIPELINE_OUT ( 0 )
|
||||
.PIPELINE_IN ( 1 ),
|
||||
.PIPELINE_OUT ( 1 )
|
||||
)
|
||||
resource_share_mul (
|
||||
.i_clk ( i_clk ),
|
||||
|
@ -294,8 +305,8 @@ resource_share # (
|
|||
.DAT_BITS ( 2*$bits(bls12_381_pkg::fe_t) ),
|
||||
.CTL_BITS ( 16 ),
|
||||
.OVR_WRT_BIT ( 14 ),
|
||||
.PIPELINE_IN ( 0 ),
|
||||
.PIPELINE_OUT ( 0 )
|
||||
.PIPELINE_IN ( 1 ),
|
||||
.PIPELINE_OUT ( 1 )
|
||||
)
|
||||
resource_share_sub (
|
||||
.i_clk ( i_clk ),
|
||||
|
@ -311,8 +322,8 @@ resource_share # (
|
|||
.DAT_BITS ( 2*$bits(bls12_381_pkg::fe_t) ),
|
||||
.CTL_BITS ( 16 ),
|
||||
.OVR_WRT_BIT ( 14 ),
|
||||
.PIPELINE_IN ( 0 ),
|
||||
.PIPELINE_OUT ( 0 )
|
||||
.PIPELINE_IN ( 1 ),
|
||||
.PIPELINE_OUT ( 1 )
|
||||
)
|
||||
resource_share_add (
|
||||
.i_clk ( i_clk ),
|
||||
|
@ -377,9 +388,21 @@ bin_inv (
|
|||
// While cnt != 0, take output and assign it to current memory pointer, and then increase pointer and shift the output
|
||||
|
||||
// Tasks for each of the different instructions
|
||||
|
||||
task get_next_inst();
|
||||
if(inst_ram_read == 0) begin
|
||||
inst_ram_sys_if.a <= new_inst_pt_val_l ? new_inst_pt : inst_state == NOOP_WAIT ? inst_ram_sys_if.a : inst_ram_sys_if.a + 1;
|
||||
inst_ram_read[0] <= 1;
|
||||
end
|
||||
if (inst_ram_read[READ_CYCLE]) begin
|
||||
inst_state <= curr_inst.code;
|
||||
cnt <= 0;
|
||||
end
|
||||
new_inst_pt_val_l <= 0;
|
||||
endtask
|
||||
|
||||
task task_copy_reg();
|
||||
inst_ram_sys_if.a <= inst_ram_sys_if.a + 1;
|
||||
inst_ram_read[0] <= 1;
|
||||
get_next_inst();
|
||||
|
||||
data_ram_sys_if.a <= curr_inst.a;
|
||||
data_ram_read[0] <= 1;
|
||||
|
@ -389,9 +412,6 @@ task task_copy_reg();
|
|||
new_data <= curr_data;
|
||||
data_ram_sys_if.we <= -1;
|
||||
end
|
||||
if (inst_ram_read[READ_CYCLE]) begin
|
||||
inst_state <= curr_inst.code;
|
||||
end
|
||||
endtask
|
||||
|
||||
task task_scalar_inv();
|
||||
|
@ -415,13 +435,12 @@ task task_scalar_inv();
|
|||
new_data.pt <= curr_data.pt;
|
||||
new_data.dat <= binv_o_if.dat;
|
||||
data_ram_sys_if.we <= -1;
|
||||
inst_ram_sys_if.a <= inst_ram_sys_if.a + 1;
|
||||
inst_ram_read[0] <= 1;
|
||||
end
|
||||
if (inst_ram_read[READ_CYCLE]) begin
|
||||
inst_state <= curr_inst.code;
|
||||
cnt <= cnt + 1;
|
||||
end
|
||||
end
|
||||
3: begin
|
||||
get_next_inst();
|
||||
end
|
||||
endcase
|
||||
endtask
|
||||
|
||||
|
@ -473,10 +492,7 @@ task task_point_mult();
|
|||
end
|
||||
end
|
||||
5: begin
|
||||
if (inst_ram_read[READ_CYCLE]) begin
|
||||
inst_state <= curr_inst.code;
|
||||
cnt <= 0;
|
||||
end
|
||||
get_next_inst();
|
||||
end
|
||||
endcase
|
||||
endtask
|
||||
|
@ -509,16 +525,11 @@ task task_fp_fpoint_mult();
|
|||
cnt <= cnt + 1;
|
||||
if (cnt == 4) begin
|
||||
fp2_pt_mult_out_if.rdy <= 1;
|
||||
inst_ram_sys_if.a <= inst_ram_sys_if.a + 1;
|
||||
inst_ram_read[0] <= 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
5: begin
|
||||
if (inst_ram_read[READ_CYCLE]) begin
|
||||
inst_state <= curr_inst.code;
|
||||
cnt <= 0;
|
||||
end
|
||||
get_next_inst();
|
||||
end
|
||||
endcase
|
||||
endtask
|
||||
|
@ -547,20 +558,15 @@ task task_fp2_fpoint_mult();
|
|||
new_data.pt <= FP2_JB;
|
||||
new_data.dat <= fp2_pt_mult_out_if.dat >> ((cnt-2)*DAT_BITS);
|
||||
data_ram_sys_if.we <= -1;
|
||||
data_ram_sys_if.a <= data_ram_sys_if.a + 1;
|
||||
if (cnt > 2) data_ram_sys_if.a <= data_ram_sys_if.a + 1;
|
||||
cnt <= cnt + 1;
|
||||
if (cnt == 7) begin
|
||||
fp2_pt_mult_out_if.rdy <= 1;
|
||||
inst_ram_sys_if.a <= inst_ram_sys_if.a + 1;
|
||||
inst_ram_read[0] <= 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
8: begin
|
||||
if (inst_ram_read[READ_CYCLE]) begin
|
||||
inst_state <= curr_inst.code;
|
||||
cnt <= 0;
|
||||
end
|
||||
get_next_inst();
|
||||
end
|
||||
endcase
|
||||
endtask
|
||||
|
@ -600,16 +606,11 @@ task task_send_interrupt();
|
|||
data_ram_sys_if.a <= data_ram_sys_if.a + 1;
|
||||
if (pt_size == 1) begin
|
||||
cnt <= cnt + 1;
|
||||
inst_ram_sys_if.a <= inst_ram_sys_if.a + 1;
|
||||
inst_ram_read[0] <= 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
3: begin
|
||||
if (inst_ram_read[READ_CYCLE]) begin
|
||||
inst_state <= curr_inst.code;
|
||||
cnt <= 0;
|
||||
end
|
||||
get_next_inst();
|
||||
end
|
||||
endcase
|
||||
endtask
|
||||
|
|
Loading…
Reference in New Issue