Forum

Notifications
Clear all

Verilog 384 Core CPU RISC-V MIPS Warrior I-class I6500

1 Posts
1 Users
0 Reactions
13 Views
 josh
(@josh)
Member Admin
Joined: 2 months ago
Posts: 510
Topic starter  
Here's the folder structure and file names for a 384-core MIPS Warrior I-class I6500 CPU implementation:

```
mips_warrior_i6500/
├── core/
│   ├── mips_core.sv
│   ├── cpu_controller.sv
│   ├── instruction_fetch.sv
│   ├── instruction_decode.sv
│   ├── execution_unit.sv
│   ├── memory_access.sv
│   ├── writeback.sv
│   └── register_file.sv
├── interconnect/
│   ├── crossbar.sv
│   ├── network_on_chip.sv
│   └── interconnect_controller.sv
├── memory/
│   ├── instruction_cache.sv
│   ├── data_cache.sv
│   ├── main_memory.sv
│   └── cache_controller.sv
├── system/
│   ├── processor_top.sv
│   ├── reset_controller.sv
│   └── clock_controller.sv
├── testbench/
│   ├── tb_processor.sv
│   ├── tb_core.sv
│   └── tb_memory.sv
├── config/
│   ├── mips_config.sv
│   └── constants.sv
└── README.md
```

Now, here's the main processor top-level file with a simplified 384-core structure:

```verilog
// File: mips_warrior_i6500/system/processor_top.sv

`include "mips_config.sv"

module processor_top (
    input wire clk,
    input wire rst_n,
    input wire [31:0] instruction_fetch_addr,
    input wire [31:0] data_fetch_addr,
    input wire [31:0] data_store_addr,
    input wire [31:0] data_store_data,
    input wire data_store_we,
    output reg [31:0] instruction_fetch_data,
    output reg [31:0] data_fetch_data,
    output reg data_fetch_ready,
    output reg [31:0] data_store_ack
);

// Core instances (simplified for 384 cores)
localparam NUM_CORES = 384;
localparam CORE_ID_WIDTH = 9; // log2(384) rounded up

wire [CORE_ID_WIDTH-1:0] core_id;
wire [31:0] instruction_fetch_data_core[NUM_CORES-1:0];
wire [31:0] data_fetch_data_core[NUM_CORES-1:0];
wire [31:0] data_store_ack_core[NUM_CORES-1:0];

// Core interconnect network
wire [31:0] core_to_network_in [NUM_CORES-1:0][31:0];
wire [31:0] network_to_core_out [NUM_CORES-1:0][31:0];

// Core instances
for (genvar i = 0; i < NUM_CORES; i++) begin : gen_cores
    mips_core #(.CORE_ID(i)) core_inst (
        .clk(clk),
        .rst_n(rst_n),
        .core_id(core_id),
        .instruction_fetch_addr(instruction_fetch_addr),
        .data_fetch_addr(data_fetch_addr),
        .data_store_addr(data_store_addr),
        .data_store_data(data_store_data),
        .data_store_we(data_store_we),
        .instruction_fetch_data(instruction_fetch_data_core[i]),
        .data_fetch_data(data_fetch_data_core[i]),
        .data_store_ack(data_store_ack_core[i])
    );
end

// Network on Chip interconnect
network_on_chip #(
    .NUM_CORES(NUM_CORES)
) noc_inst (
    .clk(clk),
    .rst_n(rst_n),
    .core_to_network_in(core_to_network_in),
    .network_to_core_out(network_to_core_out)
);

// Interconnect controller
interconnect_controller interconnect_ctrl_inst (
    .clk(clk),
    .rst_n(rst_n),
    .instruction_fetch_addr(instruction_fetch_addr),
    .data_fetch_addr(data_fetch_addr),
    .data_store_addr(data_store_addr),
    .data_store_data(data_store_data),
    .data_store_we(data_store_we),
    .core_id(core_id),
    .instruction_fetch_data(instruction_fetch_data_core),
    .data_fetch_data(data_fetch_data_core),
    .data_store_ack(data_store_ack_core)
);

// Output multiplexers
assign instruction_fetch_data = instruction_fetch_data_core[core_id];
assign data_fetch_data = data_fetch_data_core[core_id];
assign data_fetch_ready = 1'b1; // Simplified
assign data_store_ack = data_store_ack_core[core_id];

endmodule
```

Here's the core module:

```verilog
// File: mips_warrior_i6500/core/mips_core.sv

module mips_core #(
    parameter CORE_ID = 0
)(
    input wire clk,
    input wire rst_n,
    input wire [31:0] core_id,
    input wire [31:0] instruction_fetch_addr,
    input wire [31:0] data_fetch_addr,
    input wire [31:0] data_store_addr,
    input wire [31:0] data_store_data,
    input wire data_store_we,
    output reg [31:0] instruction_fetch_data,
    output reg [31:0] data_fetch_data,
    output reg [31:0] data_store_ack
);

// Pipeline stages
reg [31:0] pc_reg;
reg [31:0] instruction_reg;
reg [31:0] operand_a_reg;
reg [31:0] operand_b_reg;
reg [31:0] result_reg;

// Control signals
reg [3:0] alu_op_reg;
reg reg_write_en_reg;
reg mem_read_en_reg;
reg mem_write_en_reg;

// Pipeline control
reg pipeline_valid;

// Instruction fetch stage
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        pc_reg <= 32'h00000000;
    end else begin
        pc_reg <= instruction_fetch_addr;
    end
end

// Instruction decode stage
always @(*) begin
    case (instruction_fetch_data[31:26])
        6'b100011: begin // lw
            alu_op_reg = 4'b0001;
            reg_write_en_reg = 1'b1;
            mem_read_en_reg = 1'b1;
            mem_write_en_reg = 1'b0;
        end
        6'b101011: begin // sw
            alu_op_reg = 4'b0010;
            reg_write_en_reg = 1'b0;
            mem_read_en_reg = 1'b0;
            mem_write_en_reg = 1'b1;
        end
        default: begin
            alu_op_reg = 4'b0000;
            reg_write_en_reg = 1'b0;
            mem_read_en_reg = 1'b0;
            mem_write_en_reg = 1'b0;
        end
    endcase
end

// Execution stage
always @(*) begin
    case (alu_op_reg)
        4'b0001: result_reg = operand_a_reg + operand_b_reg; // lw
        4'b0010: result_reg = operand_a_reg + operand_b_reg; // sw
        default: result_reg = 32'h00000000;
    endcase
end

// Memory access stage
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        data_fetch_data <= 32'h00000000;
        data_store_ack <= 32'h00000000;
    end else begin
        // Simplified memory access
        if (mem_read_en_reg) begin
            data_fetch_data <= result_reg;
        end
        if (mem_write_en_reg) begin
            data_store_ack <= data_store_data;
        end
    end
end

// Writeback stage
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        // Writeback logic here
    end else begin
        if (reg_write_en_reg) begin
            // Register write logic
        end
    end
end

endmodule
```

And here's the network on chip module:

```verilog
// File: mips_warrior_i6500/interconnect/network_on_chip.sv

module network_on_chip #(
    parameter NUM_CORES = 384,
    parameter DATA_WIDTH = 32,
    parameter ADDR_WIDTH = 32
)(
    input wire clk,
    input wire rst_n,
    input wire [NUM_CORES-1:0][DATA_WIDTH-1:0] core_to_network_in,
    output reg [NUM_CORES-1:0][DATA_WIDTH-1:0] network_to_core_out
);

// Simplified crossbar implementation for 384 cores
reg [DATA_WIDTH-1:0] crossbar_mem[NUM_CORES-1:0][NUM_CORES-1:0];

// Crossbar routing logic
always @(*) begin
    // Simplified routing - in practice this would be more complex
    for (int i = 0; i < NUM_CORES; i++) begin
        network_to_core_out[i] = core_to_network_in[i];
    end
end

endmodule
```

This is a simplified framework that demonstrates the basic structure of a 384-core MIPS Warrior I-class CPU. Key features include:

1. **Modular Design**: Separation into cores, interconnect, memory, and system components
2. **Pipeline Stages**: Instruction fetch, decode, execute, memory access, writeback
3. **Network-on-Chip**: Crossbar interconnect for 384 cores
4. **Scalability**: Parameterized design for easy modification

The actual implementation would require more detailed pipeline logic, advanced features like branch prediction, cache coherence protocols, and sophisticated interconnect topologies. This serves as a foundation for the complete system design.
This topic was modified 4 days ago by josh

   
Quote
Share: