OpenCores
URL https://opencores.org/ocsvn/altor32/altor32/trunk

Subversion Repositories altor32

[/] [altor32/] [trunk/] [rtl/] [cpu/] [altor32.v] - Diff between revs 36 and 37

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 36 Rev 37
Line 8... Line 8...
//               Email: admin@ultra-embedded.com
//               Email: admin@ultra-embedded.com
//
//
//                       License: LGPL
//                       License: LGPL
//-----------------------------------------------------------------
//-----------------------------------------------------------------
//
//
// Copyright (C) 2011 - 2013 Ultra-Embedded.com
// Copyright (C) 2011 - 2014 Ultra-Embedded.com
//
//
// This source file may be used and distributed without         
// This source file may be used and distributed without         
// restriction provided that this copyright statement is not    
// restriction provided that this copyright statement is not    
// removed from the file and that any derivative work contains  
// removed from the file and that any derivative work contains  
// the original copyright notice and the associated disclaimer. 
// the original copyright notice and the associated disclaimer. 
Line 89... Line 89...
 
 
//-----------------------------------------------------------------
//-----------------------------------------------------------------
// Registers / Wires
// Registers / Wires
//-----------------------------------------------------------------
//-----------------------------------------------------------------
 
 
 
// Instruction fetch
 
wire        fetch_rd_w;
 
wire [31:0] fetch_pc_w;
 
wire [31:0] fetch_opcode_w;
 
wire        fetch_valid_w;
 
 
 
// Decode opcode / PC / state
 
wire [31:0] dec_opcode_w;
 
wire [31:0] dec_opcode_pc_w;
 
wire        dec_opcode_valid_w;
 
 
// Register number (rA)
// Register number (rA)
wire [4:0]  w_ra;
wire [4:0]  dec_ra_w;
 
 
// Register number (rB)
// Register number (rB)
wire [4:0]  w_rb;
wire [4:0]  dec_rb_w;
 
 
// Destination register number (pre execute stage)
// Destination register number (pre execute stage)
wire [4:0]  w_rd;
wire [4:0]  dec_rd_w;
 
 
// Destination register number (post execute stage)
 
wire [4:0]  w_e_rd;
 
 
 
// Register value (rA)
// Register value (rA)
wire [31:0] w_reg_ra;
wire [31:0] dec_ra_val_w;
 
 
// Register value (rB)
// Register value (rB)
wire [31:0] w_reg_rb;
wire [31:0] dec_rb_val_w;
 
 
 
// Destination register number (post execute stage)
 
wire [4:0]  ex_rd_w;
 
 
// Current opcode
// Current executing instruction
wire [31:0] w_d_opcode;
wire [31:0] ex_opcode_w;
wire [31:0] w_d_pc;
 
wire        w_d_valid;
 
 
 
wire [31:0] w_e_opcode;
// Result from execute
 
wire [31:0] ex_result_w;
 
wire        ex_mult_w;
 
wire [31:0] ex_mult_res_w;
 
 
 
// Branch request
 
wire        ex_branch_w;
 
wire [31:0] ex_branch_pc_w;
 
wire        ex_stall_w;
 
 
// Register writeback value
// Register writeback value
wire [4:0]  w_wb_rd;
wire [4:0]  wb_rd_w;
wire [31:0] w_wb_reg_rd;
wire [31:0] wb_rd_val_w;
 
 
// Register writeback enable
// Register writeback enable
wire        w_wb_write_rd;
wire        wb_rd_write_w;
 
 
// Result from execute
wire [31:0] dcache_addr_w;
wire [31:0] w_e_result;
wire [31:0] dcache_data_out_w;
wire        w_e_mult;
wire [31:0] dcache_data_in_w;
wire [31:0] w_e_mult_result;
wire [3:0]  dcache_sel_w;
 
wire        dcache_we_w;
 
wire        dcache_stb_w;
 
wire        dcache_cyc_w;
 
wire        dcache_ack_w;
 
wire        dcache_stall_w;
 
 
// Branch request
wire        icache_flush_w;
wire        w_e_branch;
wire        dcache_flush_w;
wire [31:0] w_e_branch_pc;
 
wire        w_e_stall;
 
 
 
wire        icache_rd;
 
wire [31:0] icache_pc;
 
wire [31:0] icache_inst;
 
wire        icache_valid;
 
wire        icache_invalidate;
 
 
 
wire [31:0] dcache_addr;
 
wire [31:0] dcache_data_o;
 
wire [31:0] dcache_data_i;
 
wire [3:0]  dcache_sel;
 
wire        dcache_we;
 
wire        dcache_stb;
 
wire        dcache_cyc;
 
wire        dcache_ack;
 
wire        dcache_stall;
 
wire        dcache_flush;
 
 
 
//-----------------------------------------------------------------
//-----------------------------------------------------------------
// Instantiation
 
//-----------------------------------------------------------------
 
 
 
// Instruction Cache
// Instruction Cache
 
//-----------------------------------------------------------------
generate
generate
if (ENABLE_ICACHE == "ENABLED")
if (ENABLE_ICACHE == "ENABLED")
begin : ICACHE
begin : ICACHE
    // Instruction cache
    // Instruction cache
    altor32_icache
    altor32_icache
Line 167... Line 168...
    (
    (
        .clk_i(clk_i),
        .clk_i(clk_i),
        .rst_i(rst_i),
        .rst_i(rst_i),
 
 
        // Processor interface
        // Processor interface
        .rd_i(icache_rd),
        .rd_i(fetch_rd_w),
        .pc_i(icache_pc),
        .pc_i(fetch_pc_w),
        .instruction_o(icache_inst),
        .instruction_o(fetch_opcode_w),
        .valid_o(icache_valid),
        .valid_o(fetch_valid_w),
        .invalidate_i(icache_invalidate),
        .invalidate_i(icache_flush_w),
 
 
        // Instruction memory
        // Instruction memory
        .wbm_addr_o(imem_addr_o),
        .wbm_addr_o(imem_addr_o),
        .wbm_dat_i(imem_dat_i),
        .wbm_dat_i(imem_dat_i),
        .wbm_cti_o(imem_cti_o),
        .wbm_cti_o(imem_cti_o),
Line 183... Line 184...
        .wbm_stb_o(imem_stb_o),
        .wbm_stb_o(imem_stb_o),
        .wbm_stall_i(imem_stall_i),
        .wbm_stall_i(imem_stall_i),
        .wbm_ack_i(imem_ack_i)
        .wbm_ack_i(imem_ack_i)
    );
    );
end
end
 
//-----------------------------------------------------------------
 
// No instruction cache
 
//-----------------------------------------------------------------
else
else
begin : NO_ICACHE
begin : NO_ICACHE
    // No instruction cache
 
    altor32_noicache
    altor32_noicache
    u_icache
    u_icache
    (
    (
        .clk_i(clk_i),
        .clk_i(clk_i),
        .rst_i(rst_i),
        .rst_i(rst_i),
 
 
        // Processor interface
        // Processor interface
        .rd_i(icache_rd),
        .rd_i(fetch_rd_w),
        .pc_i(icache_pc),
        .pc_i(fetch_pc_w),
        .instruction_o(icache_inst),
        .instruction_o(fetch_opcode_w),
        .valid_o(icache_valid),
        .valid_o(fetch_valid_w),
        .invalidate_i(icache_invalidate),
        .invalidate_i(icache_flush_w),
 
 
        // Instruction memory
        // Instruction memory
        .wbm_addr_o(imem_addr_o),
        .wbm_addr_o(imem_addr_o),
        .wbm_dat_i(imem_dat_i),
        .wbm_dat_i(imem_dat_i),
        .wbm_cti_o(imem_cti_o),
        .wbm_cti_o(imem_cti_o),
Line 211... Line 214...
        .wbm_ack_i(imem_ack_i)
        .wbm_ack_i(imem_ack_i)
    );
    );
end
end
endgenerate
endgenerate
 
 
 
//-----------------------------------------------------------------
// Instruction Fetch
// Instruction Fetch
 
//-----------------------------------------------------------------
altor32_fetch
altor32_fetch
#(
#(
    .BOOT_VECTOR(BOOT_VECTOR),
    .BOOT_VECTOR(BOOT_VECTOR),
    .PIPELINED_FETCH(PIPELINED_FETCH)
    .PIPELINED_FETCH(PIPELINED_FETCH)
)
)
Line 224... Line 229...
    // General
    // General
    .clk_i(clk_i),
    .clk_i(clk_i),
    .rst_i(rst_i),
    .rst_i(rst_i),
 
 
    // Instruction memory
    // Instruction memory
    .pc_o(icache_pc),
    .pc_o(fetch_pc_w),
    .data_i(icache_inst),
    .data_i(fetch_opcode_w),
    .fetch_o(icache_rd),
    .fetch_o(fetch_rd_w),
    .data_valid_i(icache_valid),
    .data_valid_i(fetch_valid_w),
 
 
    // Fetched opcode
    // Fetched opcode
    .opcode_o(w_d_opcode),
    .opcode_o(dec_opcode_w),
    .opcode_pc_o(w_d_pc),
    .opcode_pc_o(dec_opcode_pc_w),
    .opcode_valid_o(w_d_valid),
    .opcode_valid_o(dec_opcode_valid_w),
 
 
    // Branch target
    // Branch target
    .branch_i(w_e_branch),
    .branch_i(ex_branch_w),
    .branch_pc_i(w_e_branch_pc),
    .branch_pc_i(ex_branch_pc_w),
    .stall_i(w_e_stall),
    .stall_i(ex_stall_w),
 
 
    // Decoded register details
    // Decoded register details
    .ra_o(w_ra),
    .ra_o(dec_ra_w),
    .rb_o(w_rb),
    .rb_o(dec_rb_w),
    .rd_o(w_rd)
    .rd_o(dec_rd_w)
);
);
 
 
// Register file
//-----------------------------------------------------------------
 
// [Xilinx] Register file
 
//-----------------------------------------------------------------
generate
generate
if (REGISTER_FILE_TYPE == "XILINX")
if (REGISTER_FILE_TYPE == "XILINX")
begin : REGFILE_XIL
begin : REGFILE_XIL
    altor32_regfile_xil
    altor32_regfile_xil
    #(
    #(
        .SUPPORT_32REGS(SUPPORT_32REGS)
        .SUPPORT_32REGS(SUPPORT_32REGS)
    )
    )
    reg_bank
    u_regfile
    (
    (
        // Clocking
        // Clocking
        .clk_i(clk_i),
        .clk_i(clk_i),
        .rst_i(rst_i),
        .rst_i(rst_i),
        .wr_i(w_wb_write_rd),
        .wr_i(wb_rd_write_w),
 
 
        // Tri-port
        // Tri-port
        .rs_i(w_ra),
        .ra_i(dec_ra_w),
        .rt_i(w_rb),
        .rb_i(dec_rb_w),
        .rd_i(w_wb_rd),
        .rd_i(wb_rd_w),
        .reg_rs_o(w_reg_ra),
        .reg_ra_o(dec_ra_val_w),
        .reg_rt_o(w_reg_rb),
        .reg_rb_o(dec_rb_val_w),
        .reg_rd_i(w_wb_reg_rd)
        .reg_rd_i(wb_rd_val_w)
    );
    );
end
end
 
//-----------------------------------------------------------------
 
// [Altera] Register file
 
//-----------------------------------------------------------------
else if (REGISTER_FILE_TYPE == "ALTERA")
else if (REGISTER_FILE_TYPE == "ALTERA")
begin : REGFILE_ALT
begin : REGFILE_ALT
    altor32_regfile_alt
    altor32_regfile_alt
    #(
    #(
        .SUPPORT_32REGS(SUPPORT_32REGS)
        .SUPPORT_32REGS(SUPPORT_32REGS)
    )
    )
    reg_bank
    u_regfile
    (
    (
        // Clocking
        // Clocking
        .clk_i(clk_i),
        .clk_i(clk_i),
        .rst_i(rst_i),
        .rst_i(rst_i),
        .wr_i(w_wb_write_rd),
        .wr_i(wb_rd_write_w),
 
 
        // Tri-port
        // Tri-port
        .rs_i(w_ra),
        .ra_i(dec_ra_w),
        .rt_i(w_rb),
        .rb_i(dec_rb_w),
        .rd_i(w_wb_rd),
        .rd_i(wb_rd_w),
        .reg_rs_o(w_reg_ra),
        .reg_ra_o(dec_ra_val_w),
        .reg_rt_o(w_reg_rb),
        .reg_rb_o(dec_rb_val_w),
        .reg_rd_i(w_wb_reg_rd)
        .reg_rd_i(wb_rd_val_w)
    );
    );
end
end
 
//-----------------------------------------------------------------
 
// [Simulation] Register file
 
//-----------------------------------------------------------------
else
else
begin : REGFILE_SIM
begin : REGFILE_SIM
    altor32_regfile_sim
    altor32_regfile_sim
    #(
    #(
        .SUPPORT_32REGS(SUPPORT_32REGS)
        .SUPPORT_32REGS(SUPPORT_32REGS)
    )
    )
    reg_bank
    u_regfile
    (
    (
        // Clocking
        // Clocking
        .clk_i(clk_i),
        .clk_i(clk_i),
        .rst_i(rst_i),
        .rst_i(rst_i),
        .wr_i(w_wb_write_rd),
        .wr_i(wb_rd_write_w),
 
 
        // Tri-port
        // Tri-port
        .rs_i(w_ra),
        .ra_i(dec_ra_w),
        .rt_i(w_rb),
        .rb_i(dec_rb_w),
        .rd_i(w_wb_rd),
        .rd_i(wb_rd_w),
        .reg_rs_o(w_reg_ra),
        .reg_ra_o(dec_ra_val_w),
        .reg_rt_o(w_reg_rb),
        .reg_rb_o(dec_rb_val_w),
        .reg_rd_i(w_wb_reg_rd)
        .reg_rd_i(wb_rd_val_w)
    );
    );
end
end
endgenerate
endgenerate
 
 
 
//-----------------------------------------------------------------
 
// Data cache
 
//-----------------------------------------------------------------
generate
generate
if (ENABLE_DCACHE == "ENABLED")
if (ENABLE_DCACHE == "ENABLED")
begin : DCACHE
begin : DCACHE
    // Data cache
 
    altor32_dcache
    altor32_dcache
    u_dcache
    u_dcache
    (
    (
        .clk_i(clk_i),
        .clk_i(clk_i),
        .rst_i(rst_i),
        .rst_i(rst_i),
 
 
        .flush_i(dcache_flush),
        .flush_i(dcache_flush_w),
 
 
        // Processor interface
        // Processor interface
        .address_i({dcache_addr[31:2], 2'b00}),
        .address_i({dcache_addr_w[31:2], 2'b00}),
        .data_o(dcache_data_i),
        .data_o(dcache_data_in_w),
        .data_i(dcache_data_o),
        .data_i(dcache_data_out_w),
        .we_i(dcache_we),
        .we_i(dcache_we_w),
        .stb_i(dcache_stb),
        .stb_i(dcache_stb_w),
        .sel_i(dcache_sel),
        .sel_i(dcache_sel_w),
        .stall_o(dcache_stall),
        .stall_o(dcache_stall_w),
        .ack_o(dcache_ack),
        .ack_o(dcache_ack_w),
 
 
        // Memory interface (slave)
        // Memory interface (slave)
        .mem_addr_o(dmem_addr_o),
        .mem_addr_o(dmem_addr_o),
        .mem_data_i(dmem_dat_i),
        .mem_data_i(dmem_dat_i),
        .mem_data_o(dmem_dat_o),
        .mem_data_o(dmem_dat_o),
Line 350... Line 365...
        .mem_cti_o(dmem_cti_o),
        .mem_cti_o(dmem_cti_o),
        .mem_stall_i(dmem_stall_i),
        .mem_stall_i(dmem_stall_i),
        .mem_ack_i(dmem_ack_i)
        .mem_ack_i(dmem_ack_i)
    );
    );
end
end
 
//-----------------------------------------------------------------
 
// No data cache
 
//-----------------------------------------------------------------
else
else
begin: NO_DCACHE
begin: NO_DCACHE
    // No data cache
    assign dmem_addr_o      = {dcache_addr_w[31:2], 2'b00};
    assign dmem_addr_o      = {dcache_addr[31:2], 2'b00};
    assign dmem_dat_o       = dcache_data_out_w;
    assign dmem_dat_o       = dcache_data_o;
    assign dcache_data_in_w = dmem_dat_i;
    assign dcache_data_i    = dmem_dat_i;
    assign dmem_sel_o       = dcache_sel_w;
    assign dmem_sel_o       = dcache_sel;
    assign dmem_cyc_o       = dcache_cyc_w;
    assign dmem_cyc_o       = dcache_cyc;
    assign dmem_we_o        = dcache_we_w;
    assign dmem_we_o        = dcache_we;
    assign dmem_stb_o       = dcache_stb_w;
    assign dmem_stb_o       = dcache_stb;
 
    assign dmem_cti_o       = 3'b111;
    assign dmem_cti_o       = 3'b111;
    assign dcache_ack       = dmem_ack_i;
    assign dcache_ack_w     = dmem_ack_i;
    assign dcache_stall     = dmem_stall_i;
    assign dcache_stall_w   = dmem_stall_i;
end
end
endgenerate
endgenerate
 
 
 
//-----------------------------------------------------------------
// Execution unit
// Execution unit
 
//-----------------------------------------------------------------
altor32_exec
altor32_exec
#(
#(
    .BOOT_VECTOR(BOOT_VECTOR),
    .BOOT_VECTOR(BOOT_VECTOR),
    .ISR_VECTOR(ISR_VECTOR)
    .ISR_VECTOR(ISR_VECTOR)
)
)
Line 386... Line 405...
    // Status
    // Status
    .fault_o(fault_o),
    .fault_o(fault_o),
    .break_o(break_o),
    .break_o(break_o),
 
 
    // Cache control
    // Cache control
    .icache_flush_o(icache_invalidate),
    .icache_flush_o(icache_flush_w),
    .dcache_flush_o(dcache_flush),
    .dcache_flush_o(dcache_flush_w),
 
 
    // Branch target
    // Branch target
    .branch_o(w_e_branch),
    .branch_o(ex_branch_w),
    .branch_pc_o(w_e_branch_pc),
    .branch_pc_o(ex_branch_pc_w),
    .stall_o(w_e_stall),
    .stall_o(ex_stall_w),
 
 
    // Opcode & arguments
    // Opcode & arguments
    .opcode_i(w_d_opcode),
    .opcode_i(dec_opcode_w),
    .opcode_pc_i(w_d_pc),
    .opcode_pc_i(dec_opcode_pc_w),
    .opcode_valid_i(w_d_valid),
    .opcode_valid_i(dec_opcode_valid_w),
 
 
    .reg_ra_i(w_ra),
    // Operands
    .reg_ra_value_i(w_reg_ra),
    .reg_ra_i(dec_ra_w),
 
    .reg_ra_value_i(dec_ra_val_w),
    .reg_rb_i(w_rb),
    .reg_rb_i(dec_rb_w),
    .reg_rb_value_i(w_reg_rb),
    .reg_rb_value_i(dec_rb_val_w),
 
    .reg_rd_i(dec_rd_w),
    .reg_rd_i(w_rd),
 
 
 
    // Output
    // Output
    .opcode_o(w_e_opcode),
    .opcode_o(ex_opcode_w),
    .reg_rd_o(w_e_rd),
    .opcode_pc_o(/* not used */),
    .reg_rd_value_o(w_e_result),
    .reg_rd_o(ex_rd_w),
    .mult_o(w_e_mult),
    .reg_rd_value_o(ex_result_w),
    .mult_res_o(w_e_mult_result),
    .mult_o(ex_mult_w),
 
    .mult_res_o(ex_mult_res_w),
 
 
    // Register write back bypass
    // Register write back bypass
    .wb_rd_i(w_wb_rd),
    .wb_rd_i(wb_rd_w),
    .wb_rd_value_i(w_wb_reg_rd),
    .wb_rd_value_i(wb_rd_val_w),
 
 
    // Memory Interface
    // Memory Interface
    .dmem_addr_o(dcache_addr),
    .dmem_addr_o(dcache_addr_w),
    .dmem_data_out_o(dcache_data_o),
    .dmem_data_out_o(dcache_data_out_w),
    .dmem_data_in_i(dcache_data_i),
    .dmem_data_in_i(dcache_data_in_w),
    .dmem_sel_o(dcache_sel),
    .dmem_sel_o(dcache_sel_w),
    .dmem_we_o(dcache_we),
    .dmem_we_o(dcache_we_w),
    .dmem_stb_o(dcache_stb),
    .dmem_stb_o(dcache_stb_w),
    .dmem_cyc_o(dcache_cyc),
    .dmem_cyc_o(dcache_cyc_w),
    .dmem_stall_i(dcache_stall),
    .dmem_stall_i(dcache_stall_w),
    .dmem_ack_i(dcache_ack)
    .dmem_ack_i(dcache_ack_w)
);
);
 
 
 
//-----------------------------------------------------------------
// Register file writeback
// Register file writeback
 
//-----------------------------------------------------------------
altor32_writeback
altor32_writeback
u_wb
u_wb
(
(
    // General
    // General
    .clk_i(clk_i),
    .clk_i(clk_i),
    .rst_i(rst_i),
    .rst_i(rst_i),
 
 
    // Opcode
    // Opcode
    .opcode_i(w_e_opcode),
    .opcode_i(ex_opcode_w),
 
 
    // Register target
    // Register target
    .rd_i(w_e_rd),
    .rd_i(ex_rd_w),
 
 
    // ALU result
    // ALU result
    .alu_result_i(w_e_result),
    .alu_result_i(ex_result_w),
 
 
    // Memory load result
    // Memory load result
    .mem_result_i(dcache_data_i),
    .mem_result_i(dcache_data_in_w),
    .mem_offset_i(dcache_addr[1:0]),
    .mem_offset_i(dcache_addr_w[1:0]),
    .mem_ready_i(dcache_ack),
    .mem_ready_i(dcache_ack_w),
 
 
    // Multiplier result
    // Multiplier result
    .mult_i(w_e_mult),
    .mult_i(ex_mult_w),
    .mult_result_i(w_e_mult_result),
    .mult_result_i(ex_mult_res_w),
 
 
    // Outputs
    // Outputs
    .write_enable_o(w_wb_write_rd),
    .write_enable_o(wb_rd_write_w),
    .write_addr_o(w_wb_rd),
    .write_addr_o(wb_rd_w),
    .write_data_o(w_wb_reg_rd)
    .write_data_o(wb_rd_val_w)
);
);
 
 
//-------------------------------------------------------------------
//-------------------------------------------------------------------
// Hooks for debug
// Hooks for debug
//-------------------------------------------------------------------
//-------------------------------------------------------------------
`ifdef verilator
`ifdef verilator
   function [31:0] get_pc;
   function [31:0] get_pc;
      // verilator public
      // verilator public
      get_pc = w_d_pc;
      get_pc = dec_opcode_pc_w;
   endfunction
   endfunction
   function get_fault;
   function get_fault;
      // verilator public
      // verilator public
      get_fault = fault_o;
      get_fault = fault_o;
   endfunction
   endfunction

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.