blob: b9d9350d63b2210192f0bc77c6e07cd1a9b0eaf8 [file] [log] [blame]
`timescale 1ns / 1ps
`include "decred_defines.v"
module decred_controller (
`ifdef USE_POWER_PINS
inout vdda1, // User area 1 3.3V supply
inout vdda2, // User area 2 3.3V supply
inout vssa1, // User area 1 analog ground
inout vssa2, // User area 2 analog ground
inout vccd1, // User area 1 1.8V supply
inout vccd2, // User area 2 1.8v supply
inout vssd1, // User area 1 digital ground
inout vssd2, // User area 2 digital ground
`endif
input wire EXT_RESET_N_fromHost,
input wire SCLK_fromHost,
input wire M1_CLK_IN,
input wire M1_CLK_SELECT,
output wire m1_clk_local,
input wire PLL_INPUT,
input wire S1_CLK_IN,
input wire S1_CLK_SELECT,
input wire SCSN_fromHost,
input wire MOSI_fromHost,
input wire MISO_fromClient,
input wire IRQ_OUT_fromClient,
input wire ID_fromClient,
output wire SCSN_toClient,
output wire SCLK_toClient,
output wire MOSI_toClient,
output wire EXT_RESET_N_toClient,
output wire ID_toHost,
output wire CLK_LED,
output wire MISO_toHost,
output wire HASH_LED,
output wire IRQ_OUT_toHost,
// hash macro exports
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,
// user_project_wrapper exports
output wire zero,
output wire one
);
assign zero = 1'b0;
assign one = 1'b1;
// //////////////////////////////////////////////////////
// Clocking
// M1 clock is sourced from pin or PLL
assign m1_clk_local = (M1_CLK_SELECT) ? M1_CLK_IN : PLL_INPUT;
// Resync reset pin to m1_clk_local
reg [1:0] reset_resync;
always @(posedge m1_clk_local)
reset_resync = {reset_resync[0], !EXT_RESET_N_fromHost};
wire rst_local_m1;
assign rst_local_m1 = reset_resync[1];
// Stretch reset signal for SPI - assume m1 >> s1
reg [19:0] spi_reset_stretch;
always @(posedge m1_clk_local)
spi_reset_stretch = {spi_reset_stretch[18:0], !EXT_RESET_N_fromHost};
wire s1_reset_stretch;
assign s1_reset_stretch = spi_reset_stretch[19];
// S1 clock is sourced from pin or divider
wire s1_clk_local;
wire s1_div_output;
clock_div clock_divBlock (
.iCLK(m1_clk_local),
.clk_out(s1_div_output),
.RST(rst_local_m1)
);
assign s1_clk_local = (S1_CLK_SELECT) ? S1_CLK_IN : s1_div_output;
// //////////////////////////////////////////////////////
// Pass-through wires
wire rst_local_s1;
wire sclk_local;
wire scsn_local;
wire mosi_local;
wire miso_local;
wire irq_local;
wire address_stobe;
wire write_enable;
wire [6:0] setSPIAddr;
// //////////////////////////////////////////////////////
// Heartbeat output
reg [23:1] counter;
always @(posedge m1_clk_local)
if (rst_local_m1)
counter <= 0;
else
counter <= counter + 1'b1;
assign CLK_LED = counter[23];
// //////////////////////////////////////////////////////
// SPI deserializer
wire start_of_transfer;
wire end_of_transfer;
wire [7:0] mosi_data_out;
wire mosi_data_ready;
wire miso_data_request;
wire [7:0] miso_data_in;
spi spiBlock(
.SPI_CLK(s1_clk_local),
.RST(rst_local_s1),
.SCLK(sclk_local),
.SCSN(scsn_local),
.MOSI(mosi_local),
.start_of_transfer(start_of_transfer),
.end_of_transfer(end_of_transfer),
.mosi_data_out(mosi_data_out),
.mosi_data_ready(mosi_data_ready),
.MISO(miso_local),
.miso_data_request(miso_data_request),
.miso_data_in(miso_data_in)
);
// //////////////////////////////////////////////////////
// SPI pass through
assign EXT_RESET_N_toClient = EXT_RESET_N_fromHost;
assign SCLK_toClient = SCLK_fromHost;
assign SCSN_toClient = SCSN_fromHost;
assign MOSI_toClient = MOSI_fromHost;
spi_passthrough spiPassBlock(
.SPI_CLK(s1_clk_local),
.SPI_CLK_RST(s1_reset_stretch),
.RSTin(rst_local_m1),
.ID_in(ID_fromClient),
.IRQ_in(IRQ_OUT_fromClient),
.address_strobe(address_stobe),
.currentSPIAddr(address[14:8]),
.setSPIAddr(setSPIAddr),
.SCLKin(SCLK_fromHost),
.SCSNin(SCSN_fromHost),
.MOSIin(MOSI_fromHost),
.MISOout(MISO_toHost),
.rst_local_s1(rst_local_s1),
.sclk_local(sclk_local),
.scsn_local(scsn_local),
.mosi_local(mosi_local),
.miso_local(miso_local),
.irq_local(irq_local),
.write_enable(write_enable),
.MISOin(MISO_fromClient),
.IRQout(IRQ_OUT_toHost)
);
// //////////////////////////////////////////////////////
// Interface to addressalyzer
wire [14:0] address;
wire regFile_read_strobe;
wire regFile_write_strobe;
addressalyzer addressalyzerBlock (
.SPI_CLK(s1_clk_local),
.RST(rst_local_s1),
.start_of_transfer(start_of_transfer),
.end_of_transfer(end_of_transfer),
.data_in_value(mosi_data_out),
.data_in_ready(mosi_data_ready),
.data_out_request(miso_data_request),
.write_enable_mask(write_enable),
.ram_address_out(address),
.address_strobe(address_stobe),
.ram_read_strobe(regFile_read_strobe),
.ram_write_strobe(regFile_write_strobe)
);
// //////////////////////////////////////////////////////
// Interface to regfile
regBank regBankBlock (
.SPI_CLK(s1_clk_local),
.RST_S1(rst_local_s1),
.M1_CLK(m1_clk_local),
.RST_M1(rst_local_m1),
.address(address[7:0]),
.data_in(mosi_data_out),
.read_strobe(regFile_read_strobe),
.write_strobe(regFile_write_strobe),
.hash_clock_reset(),
.data_out(miso_data_in),
.LED_out(HASH_LED),
.spi_addr(setSPIAddr),
.ID_out(ID_toHost),
.interrupt_out(irq_local),
// hash macro exports
.HASH_EN(HASH_EN),
.MACRO_WR_SELECT(MACRO_WR_SELECT),
.DATA_TO_HASH(DATA_TO_HASH),
.MACRO_RD_SELECT(MACRO_RD_SELECT),
.HASH_ADDR(HASH_ADDR),
.THREAD_COUNT(THREAD_COUNT),
.DATA_AVAILABLE(DATA_AVAILABLE),
.DATA_FROM_HASH(DATA_FROM_HASH)
);
endmodule // decred_controller