blob: bacd02236d5818d9e36be554339d4a5aea6f996d [file] [log] [blame]
// SPDX-FileCopyrightText: 2022 Piotr Wegrzyn
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// SPDX-License-Identifier: Apache-2.0
`include "config.v"
module core #(parameter CORENO = 0, INT_VEC = 1) (
`ifdef USE_POWER_PINS
inout vccd1,
inout vssd1,
`endif
input i_clk,
input i_rst,
input i_disable,
// fetch input singals
output [`RW-1:0] o_req_addr,
output o_req_active, o_req_ppl_submit,
input [`I_SIZE-1:0] i_req_data,
input i_req_data_valid,
output [`RW-1:0] dbg_r0, dbg_pc,
// data memory connections
output [`RW-1:0] o_mem_addr, o_mem_data,
input [`RW-1:0] i_mem_data,
output o_mem_req, o_mem_we,
input i_mem_ack,
output [`ADDR_BYTES-1:0] o_mem_sel,
output o_mem_long,
output [7:0] o_mem_addr_high,
input i_irq,
output o_c_instr_page, o_c_data_page,
output [`RW-1:0] sr_bus_addr, sr_bus_data_o,
output sr_bus_we,
output o_icache_flush,
input i_mem_exception,
input i_mc_core_int,
input [`RW-1:0] i_core_int_sreg,
output o_c_instr_long,
output [7:0] o_instr_long_addr
);
// --- CPU INTERNAL CONNECTIONS ---
wire fetch_decode_next_ready;
wire fetch_decode_submit;
wire [`I_SIZE-1:0] fetch_decode_d_instr;
wire fetch_decode_jmp_pred;
wire execute_fetch_pc_update;
wire [`RW-1:0] execute_fetch_pc;
wire fde_pipeline_flush;
// Pipeline stage 0 - FETCH
fetch fetch (
`ifdef USE_POWER_PINS
.vccd1(vccd1), .vssd1(vssd1),
`endif
.i_clk(i_clk), .i_rst(i_rst), .mem_addr(o_req_addr), .mem_submit(o_req_ppl_submit),
.mem_data(i_req_data), .mem_ack(i_req_data_valid), .i_next_ready(fetch_decode_next_ready),
.o_submit(fetch_decode_submit), .o_instr(fetch_decode_d_instr), .o_jmp_predict(fetch_decode_jmp_pred),
.i_exec_pc(execute_fetch_pc), .i_flush(fde_pipeline_flush));
assign o_req_active = ~i_disable;
wire decode_execute_next_ready;
wire decode_execute_submit;
wire [`I_SIZE-17:0] de_imm_pass;
wire de_jmp_pred;
wire dec_pc_inc, dec_pc_ie;
wire dec_r_bus_imm;
wire [`ALU_MODE_W-1:0] dec_alu_mode;
wire dec_alu_carry_en, dec_alu_flags_ie;
wire [`REGNO_LOG-1:0] dec_l_reg_sel, dec_r_reg_sel;
wire [`REGNO-1:0] dec_rf_ie;
wire [`JUMP_CODE_W-1:0] dec_jump_cond_code;
wire dec_mem_access, dec_mem_we, dec_mem_width;
wire [1:0] dec_used_operands;
wire dec_sreg_load, dec_sreg_store, dec_sreg_jal_over, dec_sreg_irt, dec_sys, dec_mem_long;
// Pipeline stage 1 - DECODE
decode decode (
`ifdef USE_POWER_PINS
.vccd1(vccd1), .vssd1(vssd1),
`endif
.i_clk(i_clk), .i_rst(i_rst), .o_ready(fetch_decode_next_ready), .o_submit(decode_execute_submit),
.i_next_ready(decode_execute_next_ready), .i_instr_l(fetch_decode_d_instr[15:0]), .i_imm_pass(fetch_decode_d_instr[`I_SIZE-1:16]),
.o_imm_pass(de_imm_pass), .oc_pc_inc(dec_pc_inc), .oc_pc_ie(dec_pc_ie), .oc_r_bus_imm(dec_r_bus_imm), .oc_alu_mode(dec_alu_mode),
.oc_alu_flags_ie(dec_alu_flags_ie), .oc_alu_carry_en(dec_alu_carry_en), .oc_l_reg_sel(dec_l_reg_sel), .oc_r_reg_sel(dec_r_reg_sel),
.oc_rf_ie(dec_rf_ie), .i_submit(fetch_decode_submit), .oc_jump_cond_code(dec_jump_cond_code), .i_jmp_pred_pass(fetch_decode_jmp_pred),
.o_jmp_pred_pass(de_jmp_pred), .i_flush(fde_pipeline_flush), .oc_mem_access(dec_mem_access), .oc_mem_we(dec_mem_we),
.oc_used_operands(dec_used_operands), .oc_sreg_load(dec_sreg_load), .oc_sreg_store(dec_sreg_store), .oc_sreg_jal_over(dec_sreg_jal_over),
.oc_sreg_irt(dec_sreg_irt), .oc_sys(dec_sys), .oc_mem_width(dec_mem_width), .oc_mem_long(dec_mem_long));
wire [`RW-1:0] ew_data;
wire [`RW-1:0] ew_addr;
wire [`REGNO-1:0] ew_reg_ie;
wire ew_mem_access, ew_mem_we, ew_mem_width;
wire [`REGNO-1:0] we_reg_ie;
wire [`RW-1:0] we_reg_data;
wire ew_submit;
wire ew_next_ready;
wire ew_long_mode;
wire [7:0] ew_addr_high;
// Pipeline stage 2 - EXECUTE
execute #(.CORENO(CORENO), .INT_VEC(INT_VEC)) execute(
`ifdef USE_POWER_PINS
.vccd1(vccd1), .vssd1(vssd1),
`endif
.i_clk(i_clk), .i_rst(i_rst), .o_ready(decode_execute_next_ready), .i_imm(de_imm_pass), .c_pc_inc(dec_pc_inc),
.c_pc_ie(dec_pc_ie), .c_r_bus_imm(dec_r_bus_imm), .c_alu_mode(dec_alu_mode), .c_alu_flags_ie(dec_alu_flags_ie),
.c_alu_carry_en(dec_alu_carry_en), .c_l_reg_sel(dec_l_reg_sel), .c_r_reg_sel(dec_r_reg_sel), .c_rf_ie(dec_rf_ie),
.dbg_pc(dbg_pc), .dbg_r0(dbg_r0), .i_submit(decode_execute_submit), .c_jump_cond_code(dec_jump_cond_code), .o_pc_update(execute_fetch_pc_update),
.o_exec_pc(execute_fetch_pc), .i_jmp_predict(de_jmp_pred), .i_flush(fde_pipeline_flush), .o_flush(fde_pipeline_flush), .c_mem_access(dec_mem_access),
.c_mem_we(dec_mem_we), .o_data(ew_data), .o_addr(ew_addr), .o_reg_ie(ew_reg_ie), .o_mem_access(ew_mem_access), .o_mem_we(ew_mem_we), .o_submit(ew_submit),
.i_next_ready(ew_next_ready), .i_reg_ie(we_reg_ie), .i_reg_data(we_reg_data), .c_used_operands(dec_used_operands), .c_sreg_load(dec_sreg_load),
.c_sreg_store(dec_sreg_store), .c_sreg_jal_over(dec_sreg_jal_over), .i_irq(i_irq), .c_sreg_irt(dec_sreg_irt), .o_c_instr_page(o_c_instr_page),
.sr_bus_addr(sr_bus_addr), .sr_bus_data_o(sr_bus_data_o), .sr_bus_we(sr_bus_we), .o_icache_flush(o_icache_flush), .c_sys(dec_sys), .c_mem_width(dec_mem_width),
.o_mem_width(ew_mem_width), .o_c_data_page(o_c_data_page), .i_mem_exception(i_mem_exception),
.i_core_int(i_mc_core_int), .i_core_int_sreg(i_core_int_sreg), .o_c_instr_long_mode(o_c_instr_long), .o_instr_addr_high(o_instr_long_addr), .c_mem_long(dec_mem_long),
.o_mem_long_mode(ew_long_mode), .o_mem_addr_high(ew_addr_high));
// Pipeline stage 3 - MEM&WB
memwb memwb(
`ifdef USE_POWER_PINS
.vccd1(vccd1), .vssd1(vssd1),
`endif
.i_clk(i_clk), .i_rst(i_rst), .i_data(ew_data), .i_addr(ew_addr), .i_reg_ie(ew_reg_ie), .i_mem_access(ew_mem_access), .i_mem_we(ew_mem_we),
.o_reg_ie(we_reg_ie), .o_reg_data(we_reg_data), .i_submit(ew_submit), .o_ready(ew_next_ready), .o_mem_req(o_mem_req), .o_mem_addr(o_mem_addr),
.o_mem_data(o_mem_data), .o_mem_we(o_mem_we), .i_mem_data(i_mem_data), .i_mem_ack(i_mem_ack), .i_mem_width(ew_mem_width), .o_mem_sel(o_mem_sel),
.o_mem_exception(i_mem_exception), .i_addr_high(ew_addr_high), .i_mem_long(ew_long_mode), .o_mem_long(o_mem_long), .o_mem_addr_high(o_mem_addr_high));
endmodule
module core0 (
`ifdef USE_POWER_PINS
inout vccd1,
inout vssd1,
`endif
input i_clk,
input i_rst,
input i_disable,
// fetch input singals
output [`RW-1:0] o_req_addr,
output o_req_active, o_req_ppl_submit,
input [`I_SIZE-1:0] i_req_data,
input i_req_data_valid,
output [`RW-1:0] dbg_r0, dbg_pc,
// data memory connections
output [`RW-1:0] o_mem_addr, o_mem_data,
input [`RW-1:0] i_mem_data,
output o_mem_req, o_mem_we,
input i_mem_ack,
output [`ADDR_BYTES-1:0] o_mem_sel,
output o_mem_long,
output [7:0] o_mem_addr_high,
input i_irq,
output o_c_instr_page, o_c_data_page,
output [`RW-1:0] sr_bus_addr, sr_bus_data_o,
output sr_bus_we,
output o_icache_flush,
input i_mem_exception,
input i_mc_core_int,
input [`RW-1:0] i_core_int_sreg,
output o_c_instr_long,
output [7:0] o_instr_long_addr
);
core #(.CORENO(0), .INT_VEC(1)) core_0 (
.i_clk(i_clk),
.i_rst(i_rst),
.i_disable(i_disable),
.o_req_addr(o_req_addr),
.o_req_active(o_req_active),
.o_req_ppl_submit(o_req_ppl_submit),
.i_req_data(i_req_data),
.i_req_data_valid(i_req_data_valid),
.dbg_r0(dbg_r0),
.dbg_pc(dbg_pc),
.o_mem_addr(o_mem_addr),
.o_mem_data(o_mem_data),
.i_mem_data(i_mem_data),
.o_mem_req(o_mem_req),
.o_mem_we(o_mem_we),
.i_mem_ack(i_mem_ack),
.o_mem_sel(o_mem_sel),
.o_mem_long(o_mem_long),
.o_mem_addr_high(o_mem_addr_high),
.i_irq(i_irq),
.o_c_instr_page(o_c_instr_page),
.o_c_data_page(o_c_data_page),
.sr_bus_addr(sr_bus_addr),
.sr_bus_data_o(sr_bus_data_o),
.sr_bus_we(sr_bus_we),
.o_icache_flush(o_icache_flush),
.i_mem_exception(i_mem_exception),
.i_mc_core_int(i_mc_core_int),
.i_core_int_sreg(i_core_int_sreg),
.o_c_instr_long(o_c_instr_long),
.o_instr_long_addr(o_instr_long_addr)
);
endmodule
module core1 (
`ifdef USE_POWER_PINS
inout vccd1,
inout vssd1,
`endif
input i_clk,
input i_rst,
input i_disable,
// fetch input singals
output [`RW-1:0] o_req_addr,
output o_req_active, o_req_ppl_submit,
input [`I_SIZE-1:0] i_req_data,
input i_req_data_valid,
output [`RW-1:0] dbg_r0, dbg_pc,
// data memory connections
output [`RW-1:0] o_mem_addr, o_mem_data,
input [`RW-1:0] i_mem_data,
output o_mem_req, o_mem_we,
input i_mem_ack,
output [`ADDR_BYTES-1:0] o_mem_sel,
output o_mem_long,
output [7:0] o_mem_addr_high,
input i_irq,
output o_c_instr_page, o_c_data_page,
output [`RW-1:0] sr_bus_addr, sr_bus_data_o,
output sr_bus_we,
output o_icache_flush,
input i_mem_exception,
input i_mc_core_int,
input [`RW-1:0] i_core_int_sreg,
output o_c_instr_long,
output [7:0] o_instr_long_addr
);
core #(.CORENO(1), .INT_VEC(2)) core_1 (
.i_clk(i_clk),
.i_rst(i_rst),
.i_disable(i_disable),
.o_req_addr(o_req_addr),
.o_req_active(o_req_active),
.o_req_ppl_submit(o_req_ppl_submit),
.i_req_data(i_req_data),
.i_req_data_valid(i_req_data_valid),
.dbg_r0(dbg_r0),
.dbg_pc(dbg_pc),
.o_mem_addr(o_mem_addr),
.o_mem_data(o_mem_data),
.i_mem_data(i_mem_data),
.o_mem_req(o_mem_req),
.o_mem_we(o_mem_we),
.i_mem_ack(i_mem_ack),
.o_mem_sel(o_mem_sel),
.o_mem_long(o_mem_long),
.o_mem_addr_high(o_mem_addr_high),
.i_irq(i_irq),
.o_c_instr_page(o_c_instr_page),
.o_c_data_page(o_c_data_page),
.sr_bus_addr(sr_bus_addr),
.sr_bus_data_o(sr_bus_data_o),
.sr_bus_we(sr_bus_we),
.o_icache_flush(o_icache_flush),
.i_mem_exception(i_mem_exception),
.i_mc_core_int(i_mc_core_int),
.i_core_int_sreg(i_core_int_sreg),
.o_c_instr_long(o_c_instr_long),
.o_instr_long_addr(o_instr_long_addr)
);
endmodule