diff options
Diffstat (limited to 'rtl/src/verilog/core_selector.v')
-rw-r--r-- | rtl/src/verilog/core_selector.v | 375 |
1 files changed, 226 insertions, 149 deletions
diff --git a/rtl/src/verilog/core_selector.v b/rtl/src/verilog/core_selector.v index 092a704..093830a 100644 --- a/rtl/src/verilog/core_selector.v +++ b/rtl/src/verilog/core_selector.v @@ -2,20 +2,20 @@ // // core_selector.v // --------------- -// Core selector Cryptech Novena FPGA framework. -// This is basically the top of the Cryptech subsystem for the -// FPGA. The module is responsible for selecting which core is -// connected to the extermal high speed interface. +// Top level wrapper that creates the Cryptech coretest system. +// The wrapper contains instances of external interface, coretest +// and the core to be tested. And if more than one core is +// present the wrapper also includes address and data muxes. // // -// Author: Pavel Shatov, Paul Sekirk, Joachim Strömbergson -// Copyright (c) 2014, NORDUnet A/S All rights reserved. -// +// Authors: Joachim Strombergson, Paul Selkirk, Pavel Shatov +// Copyright (c) 2014-2015, NORDUnet A/S All rights reserved. +// // Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// - Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. +// modification, are permitted provided that the following conditions are +// met: +// - Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. // // - Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the @@ -40,144 +40,221 @@ //====================================================================== module core_selector - ( - input wire sys_clk, - input wire sys_rst, - - input wire ct_noise, - output wire [07 : 0] ct_led, - - input wire [13: 0] sys_eim_addr, - input wire sys_eim_wr, - input wire sys_eim_rd, - - output wire [31 : 0] read_data, - input wire [31 : 0] write_data - ); - - // - // Internal Registers - // - reg [31: 0] reg_x = {32{1'b0}}; - reg [31: 0] reg_y = {32{1'b0}}; - reg [15: 0] reg_ctl = {16{1'b0}}; - reg [31: 0] read_data_reg = {32{1'b0}}; - - - // - // Parameters - // - localparam ADDER_BASE_ADDR = 12'h321; // upper 12 bits of address - localparam ADDER_OFFSET_REG_X = 2'd0; // X - localparam ADDER_OFFSET_REG_Y = 2'd1; // Y - localparam ADDER_OFFSET_REG_Z = 2'd2; // Z - localparam ADDER_OFFSET_REG_SC = 2'd3; // {STATUS, CONTROL} - - - /* This flag detects whether adder core is being addressed. */ - wire eim_access_adder = (sys_eim_addr[13:2] == ADDER_BASE_ADDR) ? 1'b1 : 1'b0; - - /* These flags detect whether write or read access is requested. */ - wire eim_access_write = sys_eim_wr & eim_access_adder; - wire eim_access_read = sys_eim_rd & eim_access_adder; - - - // - // Write Request Handler - // - always @(posedge sys_clk) - // - if (sys_rst) begin - reg_x <= {32{1'b0}}; - reg_y <= {32{1'b0}}; - reg_ctl <= {16{1'b0}}; - end else if (eim_access_write) begin - // - case (sys_eim_addr[1:0]) - ADDER_OFFSET_REG_X: reg_x <= write_data; - ADDER_OFFSET_REG_Y: reg_y <= write_data; - ADDER_OFFSET_REG_SC: reg_ctl <= write_data[15 : 0]; - endcase - // - end - - - // - // Read Request Handler - // - wire [31: 0] reg_z; - wire [15: 0] reg_sts; - - always @(posedge sys_clk) - // - if (sys_rst) read_data_reg <= {32{1'b0}}; - // - else if (eim_access_read) begin - // - case (sys_eim_addr[1:0]) - ADDER_OFFSET_REG_X: read_data_reg <= reg_x; - ADDER_OFFSET_REG_Y: read_data_reg <= reg_y; - ADDER_OFFSET_REG_Z: read_data_reg <= reg_z; - ADDER_OFFSET_REG_SC: read_data_reg <= {reg_sts, reg_ctl}; - endcase - // - end - - assign read_data = read_data_reg; - - - // - // Demo Adder Core - // - demo_adder adder_core - ( - .clk (sys_clk), - .rst (sys_rst), - - .x (reg_x), - .y (reg_y), - .z (reg_z), - - .ctl (reg_ctl), - .sts (reg_sts) - ); - - - //---------------------------------------------------------------- - // Cryptech Logic - // - // Logic specific to the Cryptech use of the Novena. - // Currently we just sample the noise and drive the LEDs - // with this signal. - //---------------------------------------------------------------- - reg ct_noise_sample0_reg; - reg ct_noise_sample1_reg; - reg [7 : 0] ct_led_reg; - - always @ (posedge sys_clk) - begin - if (sys_rst) - begin - ct_led_reg <= 8'h00; - ct_noise_sample0_reg <= 1'b0; - ct_noise_sample1_reg <= 1'b0; - end - else - begin - ct_noise_sample0_reg <= ct_noise; - ct_noise_sample1_reg <= ct_noise_sample0_reg; - ct_led_reg[0] <= ct_noise_sample1_reg; - ct_led_reg[1] <= ct_noise_sample1_reg; - ct_led_reg[2] <= ct_noise_sample1_reg; - ct_led_reg[3] <= ct_noise_sample1_reg; - ct_led_reg[4] <= ct_noise_sample1_reg; - ct_led_reg[5] <= ct_noise_sample1_reg; - ct_led_reg[6] <= ct_noise_sample1_reg; - ct_led_reg[7] <= ct_noise_sample1_reg; - end - end - - assign ct_led = ct_led_reg; + ( + input wire sys_clk, + input wire sys_rst, + input wire sys_ena, + + input wire [13 : 0] sys_eim_addr, + input wire sys_eim_wr, + input wire sys_eim_rd, + output wire [31 : 0] sys_read_data, + input wire [31 : 0] sys_write_data + ); + + + /* In this memory segment (HASHES) we have 14 address bits. Every core has + * 8-bit internal address space, so we can have up to 2^(14-8) = 64 cores here. + * + * Core #0 is not an actual HASH core, but a set of board-level (global) + * registers, that can be used to get information about hardware (board + * type, bitstream version and so on). + * + * So far we have three cores: SHA-1, SHA-256 and SHA-512. + */ + + /********************************************************* + * To add new HASH core named XXX follow the steps below * + ********************************************************* + * + * 1. Add corresponding `define under "List of Available Cores", this will + * allow users to exclude your core from implementation to save some + * slices in case they don't need it. + * + * `define USE_CORE_XXX + * + * + * 2. Choose address of your new core and add corresponding line under + * "Core Address Table". Core addresses can be in the range from 1 to 63 + * inclusively. Core address 0 is reserved for a page of global + * registers and must not be used. + * + * localparam CORE_ADDR_XXX = 6'dN; + * + * + * 3. Add instantiation of your new core after all existing cores + * surrounded by conditional synthesis directives. + * You also need a 32-bit output (read data) bus for your core and an + * enable flag. Note that sys_rst in an active-high sync reset signal. + * + * `ifdef USE_CORE_XXX + * wire [31: 0] read_data_xxx; + * wire enable_xxx = sys_ena && (addr_core_num == CORE_ADDR_XXX); + * xxx xxx_inst + * ( + * .clk(sys_clk), + * .reset_n(~sys_rst), + * .cs(enable_xxx & (sys_eim_rd | sys_eim_wr)), + * .we(sys_eim_wr), + * .address(addr_core_reg), + * .write_data(sys_write_data), + * .read_data(read_data_xxx), + * .error() + * ); + * `endif + * + * + * 4. Add previously created data bus to "Output (Read Data) Multiplexor" + * in the end of this file. + * + * `ifdef USE_CORE_XXX + * CORE_ADDR_XXX: + * sys_read_data_mux = read_data_xxx; + * `endif + * + */ + + + //---------------------------------------------------------------- + // Address Decoder + //---------------------------------------------------------------- + wire [ 5: 0] addr_core_num = sys_eim_addr[13: 8]; // upper 6 bits specify core being addressed + wire [ 7: 0] addr_core_reg = sys_eim_addr[ 7: 0]; // lower 8 bits specify register offset in core + + + /* We can comment following lines to exclude cores from implementation + * in case we run out of slices. + */ + + //---------------------------------------------------------------- + // List of Available Cores + //---------------------------------------------------------------- + `define USE_CORE_SHA1 + `define USE_CORE_SHA256 + `define USE_CORE_SHA512 + + + //---------------------------------------------------------------- + // Core Address Table + //---------------------------------------------------------------- + localparam CORE_ADDR_GLOBAL_REGS = 6'd0; + localparam CORE_ADDR_SHA1 = 6'd1; + localparam CORE_ADDR_SHA256 = 6'd2; + localparam CORE_ADDR_SHA512 = 6'd3; + + + //---------------------------------------------------------------- + // Global Registers + //---------------------------------------------------------------- + wire [31: 0] read_data_global; + wire enable_global = sys_ena && (addr_core_num == CORE_ADDR_GLOBAL_REGS); + novena_regs novena_regs_inst + ( + .clk(sys_clk), + .rst(sys_rst), + + .cs(enable_global & (sys_eim_rd | sys_eim_wr)), + .we(sys_eim_wr), + + .address(addr_core_reg), + .write_data(sys_write_data), + .read_data(read_data_global) + ); + + + //---------------------------------------------------------------- + // SHA-1 + //---------------------------------------------------------------- + `ifdef USE_CORE_SHA1 + wire [31: 0] read_data_sha1; + wire enable_sha1 = sys_ena && (addr_core_num == CORE_ADDR_SHA1); + sha1 sha1_inst + ( + .clk(sys_clk), + .reset_n(~sys_rst), + + .cs(enable_sha1 & (sys_eim_rd | sys_eim_wr)), + .we(sys_eim_wr), + + .address(addr_core_reg), + .write_data(sys_write_data), + .read_data(read_data_sha1) + ); + `endif + + + //---------------------------------------------------------------- + // SHA-256 + //---------------------------------------------------------------- + `ifdef USE_CORE_SHA256 + wire [31: 0] read_data_sha256; + wire enable_sha256 = sys_ena && (addr_core_num == CORE_ADDR_SHA256); + sha256 sha256_inst + ( + .clk(sys_clk), + .reset_n(~sys_rst), + + .cs(enable_sha256 & (sys_eim_rd | sys_eim_wr)), + .we(sys_eim_wr), + + .address(addr_core_reg), + .write_data(sys_write_data), + .read_data(read_data_sha256) + ); + `endif + + + //---------------------------------------------------------------- + // SHA-512 + //---------------------------------------------------------------- + `ifdef USE_CORE_SHA512 + wire [31: 0] read_data_sha512; + wire enable_sha512 = sys_ena && (addr_core_num == CORE_ADDR_SHA512); + sha512 sha512_inst + ( + .clk(sys_clk), + .reset_n(~sys_rst), + + .cs(enable_sha512 & (sys_eim_rd | sys_eim_wr)), + .we(sys_eim_wr), + + .address(addr_core_reg), + .write_data(sys_write_data), + .read_data(read_data_sha512) + ); + `endif + + + //---------------------------------------------------------------- + // Output (Read Data) Multiplexor + //---------------------------------------------------------------- + reg [31: 0] sys_read_data_mux; + assign sys_read_data = sys_read_data_mux; + + always @* + // + case (addr_core_num) + // + CORE_ADDR_GLOBAL_REGS: + sys_read_data_mux = read_data_global; + `ifdef USE_CORE_SHA1 + CORE_ADDR_SHA1: + sys_read_data_mux = read_data_sha1; + `endif + `ifdef USE_CORE_SHA256 + CORE_ADDR_SHA256: + sys_read_data_mux = read_data_sha256; + `endif + `ifdef USE_CORE_SHA512 + CORE_ADDR_SHA512: + sys_read_data_mux = read_data_sha512; + `endif + // + default: + sys_read_data_mux = {32{1'b0}}; + // + endcase + endmodule |