|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| `timescale 1ns/1ps
|
|
|
| module mmio_bridge #(
|
| parameter CORE_ID_BITS = 7,
|
| parameter NEURON_BITS = 10,
|
| parameter DATA_WIDTH = 16,
|
| parameter POOL_ADDR_BITS = 15,
|
| parameter ROUTE_SLOT_BITS = 3,
|
| parameter GLOBAL_ROUTE_SLOT_BITS = 2,
|
| parameter COUNT_BITS = 12
|
| )(
|
| input wire clk,
|
| input wire rst_n,
|
|
|
| input wire mgmt_phase,
|
|
|
| input wire mmio_valid,
|
| input wire mmio_we,
|
| input wire [15:0] mmio_addr,
|
| input wire [31:0] mmio_wdata,
|
| output reg [31:0] mmio_rdata,
|
| output reg mmio_ready,
|
|
|
| output reg mesh_start,
|
| output reg ext_valid,
|
| output reg [CORE_ID_BITS-1:0] ext_core,
|
| output reg [NEURON_BITS-1:0] ext_neuron_id,
|
| output reg signed [DATA_WIDTH-1:0] ext_current,
|
|
|
| output reg prog_param_we,
|
| output reg [CORE_ID_BITS-1:0] prog_param_core,
|
| output reg [NEURON_BITS-1:0] prog_param_neuron,
|
| output reg [4:0] prog_param_id,
|
| output reg signed [DATA_WIDTH-1:0] prog_param_value,
|
|
|
| output reg probe_read,
|
| output reg [CORE_ID_BITS-1:0] probe_core,
|
| output reg [NEURON_BITS-1:0] probe_neuron,
|
| output reg [3:0] probe_state_id,
|
| input wire signed [DATA_WIDTH-1:0] probe_data,
|
| input wire probe_valid,
|
|
|
| output reg [7:0] uart_tx_data,
|
| output reg uart_tx_valid,
|
| input wire uart_tx_ready,
|
| input wire [7:0] uart_rx_data,
|
| input wire uart_rx_valid,
|
|
|
| input wire rv_halted,
|
| input wire rv_running,
|
| input wire [31:0] timestep_count,
|
|
|
| output reg learn_enable,
|
| output reg graded_enable,
|
| output reg dendritic_enable,
|
| output reg async_enable,
|
| output reg threefactor_enable,
|
| output reg noise_enable,
|
| output reg skip_idle_enable,
|
|
|
| output reg signed [DATA_WIDTH-1:0] reward_value,
|
|
|
| output reg prog_route_we,
|
| output reg [CORE_ID_BITS-1:0] prog_route_src_core,
|
| output reg [NEURON_BITS-1:0] prog_route_src_neuron,
|
| output reg [ROUTE_SLOT_BITS-1:0] prog_route_slot,
|
| output reg [CORE_ID_BITS-1:0] prog_route_dest_core,
|
| output reg [NEURON_BITS-1:0] prog_route_dest_neuron,
|
| output reg signed [DATA_WIDTH-1:0] prog_route_weight,
|
|
|
| output reg prog_delay_we,
|
| output reg [CORE_ID_BITS-1:0] prog_delay_core,
|
| output reg [POOL_ADDR_BITS-1:0] prog_delay_addr,
|
| output reg [5:0] prog_delay_value,
|
|
|
| output reg prog_ucode_we,
|
| output reg [CORE_ID_BITS-1:0] prog_ucode_core,
|
| output reg [7:0] prog_ucode_addr,
|
| output reg [31:0] prog_ucode_data,
|
|
|
| output reg [7:0] dvfs_stall,
|
|
|
| output reg prog_index_we,
|
| output reg [CORE_ID_BITS-1:0] prog_index_core,
|
| output reg [NEURON_BITS-1:0] prog_index_neuron,
|
| output reg [POOL_ADDR_BITS-1:0] prog_index_base,
|
| output reg [COUNT_BITS-1:0] prog_index_count,
|
|
|
| output reg prog_noise_seed_we,
|
| output reg [CORE_ID_BITS-1:0] prog_noise_seed_core,
|
| output reg [31:0] prog_noise_seed_value,
|
|
|
| output reg prog_dend_parent_we,
|
| output reg [CORE_ID_BITS-1:0] prog_dend_parent_core,
|
| output reg [NEURON_BITS-1:0] prog_dend_parent_neuron,
|
| output reg [7:0] prog_dend_parent_data,
|
|
|
| output reg prog_global_route_we,
|
| output reg [CORE_ID_BITS-1:0] prog_global_route_src_core,
|
| output reg [NEURON_BITS-1:0] prog_global_route_src_neuron,
|
| output reg [GLOBAL_ROUTE_SLOT_BITS-1:0] prog_global_route_slot,
|
| output reg [CORE_ID_BITS-1:0] prog_global_route_dest_core,
|
| output reg [NEURON_BITS-1:0] prog_global_route_dest_neuron,
|
| output reg signed [DATA_WIDTH-1:0] prog_global_route_weight,
|
|
|
| input wire [31:0] perf_spike_count,
|
| input wire [31:0] perf_synop_count,
|
| input wire [31:0] perf_active_cycles,
|
| input wire [31:0] perf_power_estimate,
|
|
|
| output reg perf_reset_we,
|
| output reg [CORE_ID_BITS-1:0] perf_reset_core,
|
|
|
| output reg [31:0] debug_bp_addr_0,
|
| output reg [31:0] debug_bp_addr_1,
|
| output reg [31:0] debug_bp_addr_2,
|
| output reg [31:0] debug_bp_addr_3,
|
| output reg [3:0] debug_bp_enable,
|
| output reg debug_resume,
|
| output reg debug_halt_req,
|
| output reg debug_single_step
|
| );
|
|
|
| reg [CORE_ID_BITS-1:0] sel_core;
|
| reg [NEURON_BITS-1:0] sel_neuron;
|
| reg [POOL_ADDR_BITS-1:0] sel_pool_addr;
|
|
|
| reg [CORE_ID_BITS-1:0] route_dest_core;
|
| reg [NEURON_BITS-1:0] route_dest_neuron;
|
| reg signed [DATA_WIDTH-1:0] route_weight;
|
|
|
| reg [POOL_ADDR_BITS-1:0] index_base;
|
|
|
| reg [7:0] ucode_addr;
|
|
|
| always @(posedge clk or negedge rst_n) begin
|
| if (!rst_n) begin
|
| mmio_rdata <= 32'd0;
|
| mmio_ready <= 1'b0;
|
| mesh_start <= 1'b0;
|
| ext_valid <= 1'b0;
|
| ext_core <= 0;
|
| ext_neuron_id <= 0;
|
| ext_current <= 0;
|
| prog_param_we <= 1'b0;
|
| prog_param_core <= 0;
|
| prog_param_neuron <= 0;
|
| prog_param_id <= 0;
|
| prog_param_value <= 0;
|
| probe_read <= 1'b0;
|
| probe_core <= 0;
|
| probe_neuron <= 0;
|
| probe_state_id <= 0;
|
| uart_tx_data <= 8'd0;
|
| uart_tx_valid <= 1'b0;
|
| sel_core <= 0;
|
| sel_neuron <= 0;
|
| sel_pool_addr <= 0;
|
| learn_enable <= 1'b0;
|
| graded_enable <= 1'b0;
|
| dendritic_enable <= 1'b0;
|
| async_enable <= 1'b0;
|
| threefactor_enable <= 1'b0;
|
| noise_enable <= 1'b0;
|
| skip_idle_enable <= 1'b0;
|
| reward_value <= 0;
|
| prog_route_we <= 1'b0;
|
| prog_route_src_core <= 0;
|
| prog_route_src_neuron <= 0;
|
| prog_route_slot <= 0;
|
| prog_route_dest_core <= 0;
|
| prog_route_dest_neuron <= 0;
|
| prog_route_weight <= 0;
|
| route_dest_core <= 0;
|
| route_dest_neuron <= 0;
|
| route_weight <= 0;
|
| prog_delay_we <= 1'b0;
|
| prog_delay_core <= 0;
|
| prog_delay_addr <= 0;
|
| prog_delay_value <= 0;
|
| prog_ucode_we <= 1'b0;
|
| prog_ucode_core <= 0;
|
| prog_ucode_addr <= 0;
|
| prog_ucode_data <= 0;
|
| ucode_addr <= 0;
|
| dvfs_stall <= 8'd0;
|
| prog_index_we <= 1'b0;
|
| prog_index_core <= 0;
|
| prog_index_neuron <= 0;
|
| prog_index_base <= 0;
|
| prog_index_count <= 0;
|
| index_base <= 0;
|
| prog_noise_seed_we <= 1'b0;
|
| prog_noise_seed_core <= 0;
|
| prog_noise_seed_value <= 0;
|
| prog_dend_parent_we <= 1'b0;
|
| prog_dend_parent_core <= 0;
|
| prog_dend_parent_neuron <= 0;
|
| prog_dend_parent_data <= 0;
|
| prog_global_route_we <= 1'b0;
|
| prog_global_route_src_core <= 0;
|
| prog_global_route_src_neuron <= 0;
|
| prog_global_route_slot <= 0;
|
| prog_global_route_dest_core <= 0;
|
| prog_global_route_dest_neuron <= 0;
|
| prog_global_route_weight <= 0;
|
| perf_reset_we <= 1'b0;
|
| perf_reset_core <= 0;
|
| debug_bp_addr_0 <= 32'd0;
|
| debug_bp_addr_1 <= 32'd0;
|
| debug_bp_addr_2 <= 32'd0;
|
| debug_bp_addr_3 <= 32'd0;
|
| debug_bp_enable <= 4'd0;
|
| debug_resume <= 1'b0;
|
| debug_halt_req <= 1'b0;
|
| debug_single_step <= 1'b0;
|
| end else begin
|
| mmio_ready <= 1'b0;
|
| mesh_start <= 1'b0;
|
| ext_valid <= 1'b0;
|
| prog_param_we <= 1'b0;
|
| probe_read <= 1'b0;
|
| uart_tx_valid <= 1'b0;
|
| prog_route_we <= 1'b0;
|
| prog_delay_we <= 1'b0;
|
| prog_ucode_we <= 1'b0;
|
| prog_index_we <= 1'b0;
|
| prog_noise_seed_we <= 1'b0;
|
| prog_dend_parent_we <= 1'b0;
|
| prog_global_route_we <= 1'b0;
|
| perf_reset_we <= 1'b0;
|
| debug_resume <= 1'b0;
|
| debug_halt_req <= 1'b0;
|
| debug_single_step <= 1'b0;
|
|
|
| if (mmio_valid && !mmio_ready) begin
|
| mmio_ready <= 1'b1;
|
|
|
| if (mmio_we) begin
|
| case (mmio_addr)
|
| 16'h0000: begin
|
| if (mmio_wdata[0]) mesh_start <= 1'b1;
|
| end
|
| 16'h0004: sel_core <= mmio_wdata[CORE_ID_BITS-1:0];
|
| 16'h0008: sel_neuron <= mmio_wdata[NEURON_BITS-1:0];
|
| 16'h000C: begin
|
| prog_param_we <= mgmt_phase;
|
| prog_param_core <= sel_core;
|
| prog_param_neuron <= sel_neuron;
|
| prog_param_id <= mmio_wdata[20:16];
|
| prog_param_value <= mmio_wdata[DATA_WIDTH-1:0];
|
| end
|
| 16'h0010: sel_pool_addr <= mmio_wdata[POOL_ADDR_BITS-1:0];
|
| 16'h0018: begin
|
| ext_valid <= 1'b1;
|
| ext_core <= sel_core;
|
| ext_neuron_id <= mmio_wdata[NEURON_BITS-1:0];
|
| ext_current <= mmio_wdata[DATA_WIDTH+NEURON_BITS-1:NEURON_BITS];
|
| end
|
| 16'h0020: begin
|
| uart_tx_data <= mmio_wdata[7:0];
|
| uart_tx_valid <= 1'b1;
|
| end
|
|
|
|
|
| 16'h0030: begin
|
| if (mgmt_phase) begin
|
| learn_enable <= mmio_wdata[0];
|
| graded_enable <= mmio_wdata[1];
|
| dendritic_enable <= mmio_wdata[2];
|
| async_enable <= mmio_wdata[3];
|
| threefactor_enable <= mmio_wdata[4];
|
| noise_enable <= mmio_wdata[5];
|
| skip_idle_enable <= mmio_wdata[6];
|
| end
|
| end
|
|
|
| 16'h0034: begin
|
| if (mgmt_phase)
|
| reward_value <= mmio_wdata[DATA_WIDTH-1:0];
|
| end
|
|
|
| 16'h0038: begin
|
| route_dest_core <= mmio_wdata[CORE_ID_BITS-1:0];
|
| end
|
|
|
| 16'h003C: begin
|
| route_dest_neuron <= mmio_wdata[NEURON_BITS-1:0];
|
| end
|
|
|
| 16'h0040: begin
|
| route_weight <= mmio_wdata[DATA_WIDTH-1:0];
|
| end
|
|
|
| 16'h0044: begin
|
| if (mgmt_phase) begin
|
| prog_route_we <= 1'b1;
|
| prog_route_src_core <= sel_core;
|
| prog_route_src_neuron <= sel_neuron;
|
| prog_route_slot <= mmio_wdata[ROUTE_SLOT_BITS-1:0];
|
| prog_route_dest_core <= route_dest_core;
|
| prog_route_dest_neuron <= route_dest_neuron;
|
| prog_route_weight <= route_weight;
|
| end
|
| end
|
|
|
| 16'h0048: begin
|
| if (mgmt_phase) begin
|
| prog_delay_we <= 1'b1;
|
| prog_delay_core <= sel_core;
|
| prog_delay_addr <= sel_pool_addr;
|
| prog_delay_value <= mmio_wdata[5:0];
|
| end
|
| end
|
|
|
| 16'h004C: begin
|
| ucode_addr <= mmio_wdata[7:0];
|
| end
|
|
|
| 16'h0050: begin
|
| if (mgmt_phase) begin
|
| prog_ucode_we <= 1'b1;
|
| prog_ucode_core <= sel_core;
|
| prog_ucode_addr <= ucode_addr;
|
| prog_ucode_data <= mmio_wdata;
|
| end
|
| end
|
|
|
| 16'h0054: begin
|
| if (mgmt_phase)
|
| dvfs_stall <= mmio_wdata[7:0];
|
| end
|
|
|
| 16'h0058: begin
|
| if (mgmt_phase) begin
|
| perf_reset_we <= 1'b1;
|
| perf_reset_core <= sel_core;
|
| end
|
| end
|
|
|
| 16'h005C: begin
|
| index_base <= mmio_wdata[POOL_ADDR_BITS-1:0];
|
| end
|
|
|
| 16'h0060: begin
|
| if (mgmt_phase) begin
|
| prog_index_we <= 1'b1;
|
| prog_index_core <= sel_core;
|
| prog_index_neuron <= sel_neuron;
|
| prog_index_base <= index_base;
|
| prog_index_count <= mmio_wdata[COUNT_BITS-1:0];
|
| end
|
| end
|
|
|
| 16'h0064: begin
|
| if (mgmt_phase) begin
|
| prog_noise_seed_we <= 1'b1;
|
| prog_noise_seed_core <= sel_core;
|
| prog_noise_seed_value <= mmio_wdata;
|
| end
|
| end
|
|
|
| 16'h0068: begin
|
| if (mgmt_phase) begin
|
| prog_dend_parent_we <= 1'b1;
|
| prog_dend_parent_core <= sel_core;
|
| prog_dend_parent_neuron <= sel_neuron;
|
| prog_dend_parent_data <= mmio_wdata[7:0];
|
| end
|
| end
|
|
|
| 16'h006C: begin
|
| if (mgmt_phase) begin
|
| prog_global_route_we <= 1'b1;
|
| prog_global_route_src_core <= sel_core;
|
| prog_global_route_src_neuron <= sel_neuron;
|
| prog_global_route_slot <= mmio_wdata[GLOBAL_ROUTE_SLOT_BITS-1:0];
|
| prog_global_route_dest_core <= route_dest_core;
|
| prog_global_route_dest_neuron <= route_dest_neuron;
|
| prog_global_route_weight <= route_weight;
|
| end
|
| end
|
|
|
|
|
| 16'h0090: begin
|
| debug_resume <= mmio_wdata[0];
|
| debug_halt_req <= mmio_wdata[1];
|
| debug_single_step <= mmio_wdata[2];
|
| end
|
|
|
| 16'h0094: debug_bp_addr_0 <= mmio_wdata;
|
| 16'h0098: debug_bp_addr_1 <= mmio_wdata;
|
| 16'h009C: debug_bp_addr_2 <= mmio_wdata;
|
| 16'h00A0: debug_bp_addr_3 <= mmio_wdata;
|
| 16'h00A4: debug_bp_enable <= mmio_wdata[3:0];
|
|
|
| default: ;
|
| endcase
|
| end else begin
|
| case (mmio_addr)
|
| 16'h0000: mmio_rdata <= {30'd0, rv_running, rv_halted};
|
| 16'h0004: mmio_rdata <= {{(32-CORE_ID_BITS){1'b0}}, sel_core};
|
| 16'h0008: mmio_rdata <= {{(32-NEURON_BITS){1'b0}}, sel_neuron};
|
| 16'h000C: begin
|
| probe_read <= 1'b1;
|
| probe_core <= sel_core;
|
| probe_neuron <= sel_neuron;
|
| probe_state_id <= mmio_wdata[3:0];
|
| mmio_rdata <= {{(32-DATA_WIDTH){probe_data[DATA_WIDTH-1]}}, probe_data};
|
| end
|
| 16'h0024: mmio_rdata <= {24'd0, uart_rx_data};
|
| 16'h0028: mmio_rdata <= {30'd0, uart_rx_valid, uart_tx_ready};
|
| 16'h002C: mmio_rdata <= timestep_count;
|
|
|
| 16'h0070: mmio_rdata <= perf_spike_count;
|
| 16'h0074: mmio_rdata <= perf_synop_count;
|
| 16'h0078: mmio_rdata <= perf_active_cycles;
|
| 16'h007C: mmio_rdata <= perf_power_estimate;
|
|
|
| default: mmio_rdata <= 32'd0;
|
| endcase
|
| end
|
| end
|
| end
|
| end
|
|
|
| endmodule
|
|
|