blob: 024abb8691781e153311d1491292fc082ab18386 [file] [log] [blame]
`timescale 1ns / 1ps
`include "decred_defines.v"
module regBank #(
parameter DATA_WIDTH=8,
parameter ADDR_WIDTH=8
)(
input wire SPI_CLK,
input wire RST_S1,
input wire M1_CLK,
input wire RST_M1,
input wire [ADDR_WIDTH-1:0] address,
input wire [DATA_WIDTH-1:0] data_in,
input wire read_strobe,
input wire write_strobe,
output reg [DATA_WIDTH-1:0] data_out,
output wire hash_clock_reset,
output wire LED_out,
output wire [6:0] spi_addr,
output wire ID_out,
output wire interrupt_out,
output wire HASH_EN,
output wire [`NUMBER_OF_MACROS - 1: 0] MACRO_WR_SELECT,
output wire [7: 0] DATA_TO_HASH,
output wire [`NUMBER_OF_MACROS - 1: 0] MACRO_RD_SELECT,
output wire [5: 0] HASH_ADDR,
input wire [3 :0] THREAD_COUNT,
input wire [`NUMBER_OF_MACROS - 1: 0] DATA_AVAILABLE,
input wire [7: 0] DATA_FROM_HASH
);
localparam REGISTERS = 6;
// //////////////////////////////////////////////////////
// reg array
reg [DATA_WIDTH-1:0] registers [REGISTERS-1:0];
reg [7: 0] macro_data_read_rs[1:0];
reg [31:0] perf_counter;
always @(posedge M1_CLK)
if (RST_M1)
perf_counter <= 0;
else if (registers[3][2] == 1'b1)
perf_counter <= perf_counter + 1'b1;
always @(posedge SPI_CLK) begin : REG_WRITE_BLOCK
integer i;
if(RST_S1) begin
for (i = 0; i < REGISTERS; i = i + 1) begin
registers[i] <= 0;
end
end
else begin
if (write_strobe) begin
registers[address] <= data_in;
end
end
end
always @(posedge SPI_CLK) begin
if (read_strobe) begin
if (address[7:0] == 8'h02) begin
// interrupt active register
data_out <= macro_rs[1];
end else
if (address[7:0] == 8'h05) begin
// ID register
data_out <= 8'h11;
end else
if (address[7:0] == 8'h06) begin
// MACRO_INFO register
data_out <= ((`NUMBER_OF_MACROS << 4) | (THREAD_COUNT));
end else
if (address[7:0] == 8'h07) begin
data_out <= perf_counter[7:0];
end else
if (address[7:0] == 8'h08) begin
data_out <= perf_counter[15:8];
end else
if (address[7:0] == 8'h09) begin
data_out <= perf_counter[23:16];
end else
if (address[7:0] == 8'h0A) begin
data_out <= perf_counter[31:24];
end else
if (address[7] == 0) begin
data_out <= registers[address[6:0]];
end
else begin
data_out <= macro_data_read_rs[1];
end
end
end
// WRITE REGS
// MACRO_ADDR = 0 : 0x00
// MACRO_DATA = 1 : 0x01 (write only)
// MACRO_SELECT= 2 : 0x02 (int status on readback)
// CONTROL = 3 : 0x03
// CONTROL.0 = HASHCTRL
// CONTROL.1 = <available>
// CONTROL.2 = PERF_COUNTER run
// CONTROL.3 = LED output
// CONTROL.4 = hash_clock_reset
// CONTROL.5 = ID_out
// SPI_ADDR = 4 : 0x04
// SPI_ADDR.x= Address on SPI bus (6:0)
// ID REG = 5 : 0x05 (read-only)
// MACRO_WR_EN = 5 : macro write enable
// MACRO_INFO = 6 : 0x06 macro count (read-only)
// PERF_CTR = 10-7 : 0x0A - 0x07 (read-only)
assign spi_addr = registers[4][6:0];
assign LED_out = registers[3][3];
assign ID_out = registers[3][5];
assign hash_clock_reset = registers[3][4];
// //////////////////////////////////////////////////////
// resync - signals to hash_macro
reg [1:0] hash_en_rs;
always @(posedge M1_CLK) begin
if (RST_M1) begin
hash_en_rs <= 0;
end
else begin
hash_en_rs <= {hash_en_rs[0], registers[3][0]};
end
end
assign HASH_EN = hash_en_rs[1];
reg [`NUMBER_OF_MACROS - 1: 0] wr_select_rs[1:0];
always @(posedge M1_CLK) begin
if (RST_M1) begin
wr_select_rs[1] <= 0;
wr_select_rs[0] <= 0;
end
else begin
wr_select_rs[1] <= wr_select_rs[0];
wr_select_rs[0] <= registers[5][`NUMBER_OF_MACROS - 1: 0];
end
end
assign MACRO_WR_SELECT = wr_select_rs[1];
reg [7: 0] macro_data_write_rs[1:0];
always @(posedge M1_CLK) begin
if (RST_M1) begin
macro_data_write_rs[1] <= 0;
macro_data_write_rs[0] <= 0;
end
else begin
macro_data_write_rs[1] <= macro_data_write_rs[0];
macro_data_write_rs[0] <= registers[1];
end
end
assign DATA_TO_HASH = macro_data_write_rs[1];
reg [`NUMBER_OF_MACROS - 1: 0] rd_select_rs[1:0];
always @(posedge M1_CLK) begin
if (RST_M1) begin
rd_select_rs[1] <= 0;
rd_select_rs[0] <= 0;
end
else begin
rd_select_rs[1] <= rd_select_rs[0];
rd_select_rs[0] <= registers[2][`NUMBER_OF_MACROS - 1: 0];
end
end
assign MACRO_RD_SELECT = rd_select_rs[1];
reg [5: 0] macro_addr_rs[1:0];
always @(posedge M1_CLK) begin
if (RST_M1) begin
macro_addr_rs[1] <= 0;
macro_addr_rs[0] <= 0;
end
else begin
macro_addr_rs[1] <= macro_addr_rs[0];
macro_addr_rs[0] <= registers[0][5:0];
end
end
assign HASH_ADDR = macro_addr_rs[1];
// //////////////////////////////////////////////////////
// resync - signals from hash_macro
wire [`NUMBER_OF_MACROS - 1: 0] macro_interrupts;
reg [`NUMBER_OF_MACROS - 1: 0] macro_rs[1:0];
always @(posedge SPI_CLK) begin
if (RST_S1) begin
macro_rs[1] <= 0;
macro_rs[0] <= 0;
end
else begin
macro_rs[1] <= macro_rs[0];
macro_rs[0] <= macro_interrupts;
end
end
assign macro_interrupts = DATA_AVAILABLE;
assign interrupt_out = |macro_rs[1];
wire [7: 0] macro_data_readback;
always @(posedge SPI_CLK) begin
if (RST_S1) begin
macro_data_read_rs[1] <= 0;
macro_data_read_rs[0] <= 0;
end
else begin
macro_data_read_rs[1] <= macro_data_read_rs[0];
macro_data_read_rs[0] <= macro_data_readback;
end
end
assign macro_data_readback = DATA_FROM_HASH;
endmodule // regBank