| 1 |
2 |
csantifort |
//////////////////////////////////////////////////////////////////
|
| 2 |
|
|
// //
|
| 3 |
|
|
// Execute stage of Amber 2 Core //
|
| 4 |
|
|
// //
|
| 5 |
|
|
// This file is part of the Amber project //
|
| 6 |
|
|
// http://www.opencores.org/project,amber //
|
| 7 |
|
|
// //
|
| 8 |
|
|
// Description //
|
| 9 |
|
|
// Executes instructions. Instantiates the register file, ALU //
|
| 10 |
|
|
// multiplication unit and barrel shifter. This stage is //
|
| 11 |
|
|
// relitively simple. All the complex stuff is done in the //
|
| 12 |
|
|
// decode stage. //
|
| 13 |
|
|
// //
|
| 14 |
|
|
// Author(s): //
|
| 15 |
|
|
// - Conor Santifort, csantifort.amber@gmail.com //
|
| 16 |
|
|
// //
|
| 17 |
|
|
//////////////////////////////////////////////////////////////////
|
| 18 |
|
|
// //
|
| 19 |
|
|
// Copyright (C) 2010 Authors and OPENCORES.ORG //
|
| 20 |
|
|
// //
|
| 21 |
|
|
// This source file may be used and distributed without //
|
| 22 |
|
|
// restriction provided that this copyright statement is not //
|
| 23 |
|
|
// removed from the file and that any derivative work contains //
|
| 24 |
|
|
// the original copyright notice and the associated disclaimer. //
|
| 25 |
|
|
// //
|
| 26 |
|
|
// This source file is free software; you can redistribute it //
|
| 27 |
|
|
// and/or modify it under the terms of the GNU Lesser General //
|
| 28 |
|
|
// Public License as published by the Free Software Foundation; //
|
| 29 |
|
|
// either version 2.1 of the License, or (at your option) any //
|
| 30 |
|
|
// later version. //
|
| 31 |
|
|
// //
|
| 32 |
|
|
// This source is distributed in the hope that it will be //
|
| 33 |
|
|
// useful, but WITHOUT ANY WARRANTY; without even the implied //
|
| 34 |
|
|
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //
|
| 35 |
|
|
// PURPOSE. See the GNU Lesser General Public License for more //
|
| 36 |
|
|
// details. //
|
| 37 |
|
|
// //
|
| 38 |
|
|
// You should have received a copy of the GNU Lesser General //
|
| 39 |
|
|
// Public License along with this source; if not, download it //
|
| 40 |
|
|
// from http://www.opencores.org/lgpl.shtml //
|
| 41 |
|
|
// //
|
| 42 |
|
|
//////////////////////////////////////////////////////////////////
|
| 43 |
|
|
|
| 44 |
82 |
csantifort |
`include "a23_config_defines.vh"
|
| 45 |
2 |
csantifort |
|
| 46 |
15 |
csantifort |
module a23_execute (
|
| 47 |
2 |
csantifort |
|
| 48 |
|
|
input i_clk,
|
| 49 |
|
|
input [31:0] i_read_data,
|
| 50 |
|
|
input [4:0] i_read_data_alignment, // 2 LSBs of address in [4:3], appended
|
| 51 |
|
|
// with 3 zeros
|
| 52 |
|
|
input [31:0] i_copro_read_data, // From Co-Processor, to either Register
|
| 53 |
|
|
// or Memory
|
| 54 |
|
|
input i_data_access_exec, // from Instruction Decode stage
|
| 55 |
|
|
// high means the memory access is a read
|
| 56 |
|
|
// read or write, low for instruction
|
| 57 |
|
|
|
| 58 |
|
|
output reg [31:0] o_copro_write_data = 'd0,
|
| 59 |
|
|
output reg [31:0] o_write_data = 'd0,
|
| 60 |
|
|
output reg [31:0] o_address = 32'hdead_dead,
|
| 61 |
|
|
output reg o_adex = 'd0, // Address Exception
|
| 62 |
|
|
output reg o_address_valid = 'd0, // Prevents the reset address value being a
|
| 63 |
|
|
// wishbone access
|
| 64 |
|
|
output [31:0] o_address_nxt, // un-registered version of address to the
|
| 65 |
|
|
// cache rams address ports
|
| 66 |
|
|
output reg o_priviledged = 'd0, // Priviledged access
|
| 67 |
|
|
output reg o_exclusive = 'd0, // swap access
|
| 68 |
|
|
output reg o_write_enable = 'd0,
|
| 69 |
|
|
output reg [3:0] o_byte_enable = 'd0,
|
| 70 |
|
|
output reg o_data_access = 'd0, // To Fetch stage. high = data fetch,
|
| 71 |
|
|
// low = instruction fetch
|
| 72 |
|
|
output [31:0] o_status_bits, // Full PC will all status bits, but PC part zero'ed out
|
| 73 |
|
|
output o_multiply_done,
|
| 74 |
|
|
|
| 75 |
|
|
|
| 76 |
|
|
// --------------------------------------------------
|
| 77 |
|
|
// Control signals from Instruction Decode stage
|
| 78 |
|
|
// --------------------------------------------------
|
| 79 |
|
|
input i_fetch_stall, // stall all stages of the cpu at the same time
|
| 80 |
|
|
input [1:0] i_status_bits_mode,
|
| 81 |
|
|
input i_status_bits_irq_mask,
|
| 82 |
|
|
input i_status_bits_firq_mask,
|
| 83 |
|
|
input [31:0] i_imm32,
|
| 84 |
|
|
input [4:0] i_imm_shift_amount,
|
| 85 |
|
|
input i_shift_imm_zero,
|
| 86 |
|
|
input [3:0] i_condition,
|
| 87 |
|
|
input i_exclusive_exec, // swap access
|
| 88 |
|
|
|
| 89 |
|
|
input [3:0] i_rm_sel,
|
| 90 |
|
|
input [3:0] i_rds_sel,
|
| 91 |
|
|
input [3:0] i_rn_sel,
|
| 92 |
71 |
csantifort |
input [3:0] i_rm_sel_nxt,
|
| 93 |
|
|
input [3:0] i_rds_sel_nxt,
|
| 94 |
|
|
input [3:0] i_rn_sel_nxt,
|
| 95 |
2 |
csantifort |
input [1:0] i_barrel_shift_amount_sel,
|
| 96 |
|
|
input [1:0] i_barrel_shift_data_sel,
|
| 97 |
|
|
input [1:0] i_barrel_shift_function,
|
| 98 |
|
|
input [8:0] i_alu_function,
|
| 99 |
|
|
input [1:0] i_multiply_function,
|
| 100 |
|
|
input [2:0] i_interrupt_vector_sel,
|
| 101 |
|
|
input [3:0] i_address_sel,
|
| 102 |
|
|
input [1:0] i_pc_sel,
|
| 103 |
|
|
input [1:0] i_byte_enable_sel,
|
| 104 |
|
|
input [2:0] i_status_bits_sel,
|
| 105 |
|
|
input [2:0] i_reg_write_sel,
|
| 106 |
|
|
input i_user_mode_regs_load,
|
| 107 |
|
|
input i_user_mode_regs_store_nxt,
|
| 108 |
|
|
input i_firq_not_user_mode,
|
| 109 |
|
|
|
| 110 |
|
|
input i_write_data_wen,
|
| 111 |
|
|
input i_base_address_wen, // save LDM base address register,
|
| 112 |
|
|
// in case of data abort
|
| 113 |
|
|
input i_pc_wen,
|
| 114 |
|
|
input [14:0] i_reg_bank_wen,
|
| 115 |
71 |
csantifort |
input [3:0] i_reg_bank_wsel,
|
| 116 |
2 |
csantifort |
input i_status_bits_flags_wen,
|
| 117 |
|
|
input i_status_bits_mode_wen,
|
| 118 |
|
|
input i_status_bits_irq_mask_wen,
|
| 119 |
|
|
input i_status_bits_firq_mask_wen,
|
| 120 |
|
|
input i_copro_write_data_wen
|
| 121 |
|
|
|
| 122 |
|
|
);
|
| 123 |
|
|
|
| 124 |
82 |
csantifort |
`include "a23_localparams.vh"
|
| 125 |
|
|
`include "a23_functions.vh"
|
| 126 |
2 |
csantifort |
|
| 127 |
|
|
// ========================================================
|
| 128 |
|
|
// Internal signals
|
| 129 |
|
|
// ========================================================
|
| 130 |
|
|
wire [31:0] write_data_nxt;
|
| 131 |
|
|
wire [3:0] byte_enable_nxt;
|
| 132 |
|
|
wire [31:0] pc_plus4;
|
| 133 |
|
|
wire [31:0] pc_minus4;
|
| 134 |
|
|
wire [31:0] address_plus4;
|
| 135 |
|
|
wire [31:0] alu_plus4;
|
| 136 |
|
|
wire [31:0] rn_plus4;
|
| 137 |
|
|
wire [31:0] alu_out;
|
| 138 |
|
|
wire [3:0] alu_flags;
|
| 139 |
|
|
wire [31:0] rm;
|
| 140 |
|
|
wire [31:0] rs;
|
| 141 |
|
|
wire [31:0] rd;
|
| 142 |
|
|
wire [31:0] rn;
|
| 143 |
|
|
wire [31:0] pc;
|
| 144 |
|
|
wire [31:0] pc_nxt;
|
| 145 |
|
|
wire write_enable_nxt;
|
| 146 |
|
|
wire [31:0] interrupt_vector;
|
| 147 |
|
|
wire [7:0] shift_amount;
|
| 148 |
|
|
wire [31:0] barrel_shift_in;
|
| 149 |
|
|
wire [31:0] barrel_shift_out;
|
| 150 |
|
|
wire barrel_shift_carry;
|
| 151 |
|
|
|
| 152 |
|
|
wire [3:0] status_bits_flags_nxt;
|
| 153 |
|
|
reg [3:0] status_bits_flags = 'd0;
|
| 154 |
|
|
wire [1:0] status_bits_mode_nxt;
|
| 155 |
71 |
csantifort |
wire [1:0] status_bits_mode_nr;
|
| 156 |
2 |
csantifort |
reg [1:0] status_bits_mode = SVC;
|
| 157 |
71 |
csantifort |
// raw rs select
|
| 158 |
|
|
wire [1:0] status_bits_mode_rds_nxt;
|
| 159 |
|
|
wire [1:0] status_bits_mode_rds_nr;
|
| 160 |
|
|
reg [1:0] status_bits_mode_rds;
|
| 161 |
2 |
csantifort |
// one-hot encoded rs select
|
| 162 |
|
|
wire [3:0] status_bits_mode_rds_oh_nxt;
|
| 163 |
|
|
reg [3:0] status_bits_mode_rds_oh = 1'd1 << OH_SVC;
|
| 164 |
|
|
wire status_bits_mode_rds_oh_update;
|
| 165 |
|
|
wire status_bits_irq_mask_nxt;
|
| 166 |
|
|
reg status_bits_irq_mask = 1'd1;
|
| 167 |
|
|
wire status_bits_firq_mask_nxt;
|
| 168 |
|
|
reg status_bits_firq_mask = 1'd1;
|
| 169 |
|
|
|
| 170 |
|
|
wire execute; // high when condition execution is true
|
| 171 |
|
|
wire [31:0] reg_write_nxt;
|
| 172 |
|
|
wire pc_wen;
|
| 173 |
|
|
wire [14:0] reg_bank_wen;
|
| 174 |
71 |
csantifort |
wire [3:0] reg_bank_wsel;
|
| 175 |
2 |
csantifort |
wire [31:0] multiply_out;
|
| 176 |
|
|
wire [1:0] multiply_flags;
|
| 177 |
|
|
reg [31:0] base_address = 'd0; // Saves base address during LDM instruction in
|
| 178 |
|
|
// case of data abort
|
| 179 |
|
|
|
| 180 |
|
|
wire priviledged_nxt;
|
| 181 |
|
|
wire priviledged_update;
|
| 182 |
|
|
wire address_update;
|
| 183 |
|
|
wire base_address_update;
|
| 184 |
|
|
wire write_data_update;
|
| 185 |
|
|
wire copro_write_data_update;
|
| 186 |
|
|
wire byte_enable_update;
|
| 187 |
|
|
wire data_access_update;
|
| 188 |
|
|
wire write_enable_update;
|
| 189 |
|
|
wire exclusive_update;
|
| 190 |
|
|
wire status_bits_flags_update;
|
| 191 |
|
|
wire status_bits_mode_update;
|
| 192 |
|
|
wire status_bits_irq_mask_update;
|
| 193 |
|
|
wire status_bits_firq_mask_update;
|
| 194 |
82 |
csantifort |
wire [1:0] status_bits_out;
|
| 195 |
2 |
csantifort |
|
| 196 |
|
|
wire [31:0] alu_out_pc_filtered;
|
| 197 |
|
|
wire adex_nxt;
|
| 198 |
|
|
|
| 199 |
|
|
// ========================================================
|
| 200 |
|
|
// Status Bits in PC register
|
| 201 |
|
|
// ========================================================
|
| 202 |
82 |
csantifort |
assign status_bits_out = (i_status_bits_mode_wen && i_status_bits_sel == 3'd1 && execute) ?
|
| 203 |
54 |
csantifort |
alu_out[1:0] : status_bits_mode ;
|
| 204 |
|
|
|
| 205 |
|
|
|
| 206 |
2 |
csantifort |
assign o_status_bits = { status_bits_flags, // 31:28
|
| 207 |
|
|
status_bits_irq_mask, // 7
|
| 208 |
|
|
status_bits_firq_mask, // 6
|
| 209 |
|
|
24'd0,
|
| 210 |
54 |
csantifort |
status_bits_out}; // 1:0 = mode
|
| 211 |
2 |
csantifort |
|
| 212 |
|
|
// ========================================================
|
| 213 |
|
|
// Status Bits Select
|
| 214 |
|
|
// ========================================================
|
| 215 |
|
|
assign status_bits_flags_nxt = i_status_bits_sel == 3'd0 ? alu_flags :
|
| 216 |
|
|
i_status_bits_sel == 3'd1 ? alu_out [31:28] :
|
| 217 |
|
|
i_status_bits_sel == 3'd3 ? i_copro_read_data[31:28] :
|
| 218 |
82 |
csantifort |
// update flags after a multiply operation
|
| 219 |
|
|
i_status_bits_sel == 3'd4 ? { multiply_flags, status_bits_flags[1:0] } :
|
| 220 |
|
|
// regops that do not change the overflow flag
|
| 221 |
|
|
i_status_bits_sel == 3'd5 ? { alu_flags[3:1], status_bits_flags[0] } :
|
| 222 |
|
|
4'b1111 ;
|
| 223 |
2 |
csantifort |
|
| 224 |
|
|
assign status_bits_mode_nxt = i_status_bits_sel == 3'd0 ? i_status_bits_mode :
|
| 225 |
82 |
csantifort |
i_status_bits_sel == 3'd5 ? i_status_bits_mode :
|
| 226 |
2 |
csantifort |
i_status_bits_sel == 3'd1 ? alu_out [1:0] :
|
| 227 |
|
|
i_copro_read_data [1:0] ;
|
| 228 |
|
|
|
| 229 |
|
|
|
| 230 |
|
|
// Used for the Rds output of register_bank - this special version of
|
| 231 |
|
|
// status_bits_mode speeds up the critical path from status_bits_mode through the
|
| 232 |
|
|
// register_bank, barrel_shifter and alu. It moves a mux needed for the
|
| 233 |
|
|
// i_user_mode_regs_store_nxt signal back into the previous stage -
|
| 234 |
|
|
// so its really part of the decode stage even though the logic is right here
|
| 235 |
|
|
// In addition the signal is one-hot encoded to further speed up the logic
|
| 236 |
71 |
csantifort |
// Raw version is also kept for ram-based register bank implementation.
|
| 237 |
2 |
csantifort |
|
| 238 |
72 |
csantifort |
assign status_bits_mode_rds_nxt = i_user_mode_regs_store_nxt ? USR :
|
| 239 |
71 |
csantifort |
status_bits_mode_update ? status_bits_mode_nxt :
|
| 240 |
|
|
status_bits_mode ;
|
| 241 |
2 |
csantifort |
|
| 242 |
71 |
csantifort |
assign status_bits_mode_rds_oh_nxt = oh_status_bits_mode(status_bits_mode_rds_nxt);
|
| 243 |
|
|
|
| 244 |
|
|
|
| 245 |
2 |
csantifort |
assign status_bits_irq_mask_nxt = i_status_bits_sel == 3'd0 ? i_status_bits_irq_mask :
|
| 246 |
82 |
csantifort |
i_status_bits_sel == 3'd5 ? i_status_bits_irq_mask :
|
| 247 |
2 |
csantifort |
i_status_bits_sel == 3'd1 ? alu_out [27] :
|
| 248 |
|
|
i_copro_read_data [27] ;
|
| 249 |
|
|
|
| 250 |
|
|
assign status_bits_firq_mask_nxt = i_status_bits_sel == 3'd0 ? i_status_bits_firq_mask :
|
| 251 |
82 |
csantifort |
i_status_bits_sel == 3'd5 ? i_status_bits_firq_mask :
|
| 252 |
2 |
csantifort |
i_status_bits_sel == 3'd1 ? alu_out [26] :
|
| 253 |
|
|
i_copro_read_data [26] ;
|
| 254 |
|
|
|
| 255 |
|
|
|
| 256 |
|
|
|
| 257 |
|
|
// ========================================================
|
| 258 |
|
|
// Adders
|
| 259 |
|
|
// ========================================================
|
| 260 |
|
|
assign pc_plus4 = pc + 32'd4;
|
| 261 |
|
|
assign pc_minus4 = pc - 32'd4;
|
| 262 |
|
|
assign address_plus4 = o_address + 32'd4;
|
| 263 |
|
|
assign alu_plus4 = alu_out + 32'd4;
|
| 264 |
|
|
assign rn_plus4 = rn + 32'd4;
|
| 265 |
|
|
|
| 266 |
|
|
// ========================================================
|
| 267 |
|
|
// Barrel Shift Amount Select
|
| 268 |
|
|
// ========================================================
|
| 269 |
|
|
// An immediate shift value of 0 is translated into 32
|
| 270 |
|
|
assign shift_amount = i_barrel_shift_amount_sel == 2'd0 ? 8'd0 :
|
| 271 |
82 |
csantifort |
i_barrel_shift_amount_sel == 2'd1 ? rs[7:0] :
|
| 272 |
2 |
csantifort |
i_barrel_shift_amount_sel == 2'd2 ? {3'd0, i_imm_shift_amount } :
|
| 273 |
|
|
{3'd0, i_read_data_alignment } ;
|
| 274 |
|
|
|
| 275 |
|
|
// ========================================================
|
| 276 |
|
|
// Barrel Shift Data Select
|
| 277 |
|
|
// ========================================================
|
| 278 |
|
|
assign barrel_shift_in = i_barrel_shift_data_sel == 2'd0 ? i_imm32 :
|
| 279 |
|
|
i_barrel_shift_data_sel == 2'd1 ? i_read_data :
|
| 280 |
|
|
rm ;
|
| 281 |
|
|
|
| 282 |
|
|
// ========================================================
|
| 283 |
|
|
// Interrupt vector Select
|
| 284 |
|
|
// ========================================================
|
| 285 |
|
|
|
| 286 |
|
|
assign interrupt_vector = // Reset vector
|
| 287 |
|
|
(i_interrupt_vector_sel == 3'd0) ? 32'h00000000 :
|
| 288 |
|
|
// Data abort interrupt vector
|
| 289 |
|
|
(i_interrupt_vector_sel == 3'd1) ? 32'h00000010 :
|
| 290 |
|
|
// Fast interrupt vector
|
| 291 |
|
|
(i_interrupt_vector_sel == 3'd2) ? 32'h0000001c :
|
| 292 |
|
|
// Regular interrupt vector
|
| 293 |
|
|
(i_interrupt_vector_sel == 3'd3) ? 32'h00000018 :
|
| 294 |
|
|
// Prefetch abort interrupt vector
|
| 295 |
|
|
(i_interrupt_vector_sel == 3'd5) ? 32'h0000000c :
|
| 296 |
|
|
// Undefined instruction interrupt vector
|
| 297 |
|
|
(i_interrupt_vector_sel == 3'd6) ? 32'h00000004 :
|
| 298 |
|
|
// Software (SWI) interrupt vector
|
| 299 |
|
|
(i_interrupt_vector_sel == 3'd7) ? 32'h00000008 :
|
| 300 |
|
|
// Default is the address exception interrupt
|
| 301 |
|
|
32'h00000014 ;
|
| 302 |
|
|
|
| 303 |
|
|
|
| 304 |
|
|
// ========================================================
|
| 305 |
|
|
// Address Select
|
| 306 |
|
|
// ========================================================
|
| 307 |
|
|
|
| 308 |
|
|
// If rd is the pc, then seperate the address bits from the status bits for
|
| 309 |
|
|
// generating the next address to fetch
|
| 310 |
|
|
assign alu_out_pc_filtered = pc_wen && i_pc_sel == 2'd1 ? pcf(alu_out) : alu_out;
|
| 311 |
|
|
|
| 312 |
|
|
// if current instruction does not execute because it does not meet the condition
|
| 313 |
|
|
// then address advances to next instruction
|
| 314 |
|
|
assign o_address_nxt = (!execute) ? pc_plus4 :
|
| 315 |
|
|
(i_address_sel == 4'd0) ? pc_plus4 :
|
| 316 |
|
|
(i_address_sel == 4'd1) ? alu_out_pc_filtered :
|
| 317 |
|
|
(i_address_sel == 4'd2) ? interrupt_vector :
|
| 318 |
|
|
(i_address_sel == 4'd3) ? pc :
|
| 319 |
|
|
(i_address_sel == 4'd4) ? rn :
|
| 320 |
|
|
(i_address_sel == 4'd5) ? address_plus4 : // MTRANS address incrementer
|
| 321 |
|
|
(i_address_sel == 4'd6) ? alu_plus4 : // MTRANS decrement after
|
| 322 |
|
|
rn_plus4 ; // MTRANS increment before
|
| 323 |
|
|
|
| 324 |
|
|
// Data accesses use 32-bit address space, but instruction
|
| 325 |
|
|
// accesses are restricted to 26 bit space
|
| 326 |
|
|
assign adex_nxt = |o_address_nxt[31:26] && !i_data_access_exec;
|
| 327 |
|
|
|
| 328 |
|
|
// ========================================================
|
| 329 |
|
|
// Program Counter Select
|
| 330 |
|
|
// ========================================================
|
| 331 |
|
|
// If current instruction does not execute because it does not meet the condition
|
| 332 |
|
|
// then PC advances to next instruction
|
| 333 |
|
|
assign pc_nxt = (!execute) ? pc_plus4 :
|
| 334 |
|
|
i_pc_sel == 2'd0 ? pc_plus4 :
|
| 335 |
|
|
i_pc_sel == 2'd1 ? alu_out :
|
| 336 |
|
|
interrupt_vector ;
|
| 337 |
|
|
|
| 338 |
|
|
|
| 339 |
|
|
// ========================================================
|
| 340 |
|
|
// Register Write Select
|
| 341 |
|
|
// ========================================================
|
| 342 |
|
|
wire [31:0] save_int_pc;
|
| 343 |
|
|
wire [31:0] save_int_pc_m4;
|
| 344 |
|
|
|
| 345 |
|
|
assign save_int_pc = { status_bits_flags,
|
| 346 |
|
|
status_bits_irq_mask,
|
| 347 |
|
|
status_bits_firq_mask,
|
| 348 |
|
|
pc[25:2],
|
| 349 |
|
|
status_bits_mode };
|
| 350 |
|
|
|
| 351 |
|
|
|
| 352 |
|
|
assign save_int_pc_m4 = { status_bits_flags,
|
| 353 |
|
|
status_bits_irq_mask,
|
| 354 |
|
|
status_bits_firq_mask,
|
| 355 |
|
|
pc_minus4[25:2],
|
| 356 |
|
|
status_bits_mode };
|
| 357 |
|
|
|
| 358 |
|
|
|
| 359 |
|
|
assign reg_write_nxt = i_reg_write_sel == 3'd0 ? alu_out :
|
| 360 |
|
|
// save pc to lr on an interrupt
|
| 361 |
|
|
i_reg_write_sel == 3'd1 ? save_int_pc_m4 :
|
| 362 |
|
|
// to update Rd at the end of Multiplication
|
| 363 |
|
|
i_reg_write_sel == 3'd2 ? multiply_out :
|
| 364 |
|
|
i_reg_write_sel == 3'd3 ? o_status_bits :
|
| 365 |
|
|
i_reg_write_sel == 3'd5 ? i_copro_read_data : // mrc
|
| 366 |
|
|
i_reg_write_sel == 3'd6 ? base_address :
|
| 367 |
|
|
save_int_pc ;
|
| 368 |
|
|
|
| 369 |
|
|
|
| 370 |
|
|
// ========================================================
|
| 371 |
|
|
// Byte Enable Select
|
| 372 |
|
|
// ========================================================
|
| 373 |
|
|
assign byte_enable_nxt = i_byte_enable_sel == 2'd0 ? 4'b1111 : // word write
|
| 374 |
|
|
i_byte_enable_sel == 2'd2 ? // halfword write
|
| 375 |
|
|
( o_address_nxt[1] == 1'd0 ? 4'b0011 :
|
| 376 |
|
|
4'b1100 ) :
|
| 377 |
|
|
|
| 378 |
|
|
o_address_nxt[1:0] == 2'd0 ? 4'b0001 : // byte write
|
| 379 |
|
|
o_address_nxt[1:0] == 2'd1 ? 4'b0010 :
|
| 380 |
|
|
o_address_nxt[1:0] == 2'd2 ? 4'b0100 :
|
| 381 |
|
|
4'b1000 ;
|
| 382 |
|
|
|
| 383 |
|
|
|
| 384 |
|
|
// ========================================================
|
| 385 |
|
|
// Write Data Select
|
| 386 |
|
|
// ========================================================
|
| 387 |
|
|
assign write_data_nxt = i_byte_enable_sel == 2'd0 ? rd :
|
| 388 |
|
|
{4{rd[ 7:0]}} ;
|
| 389 |
|
|
|
| 390 |
|
|
|
| 391 |
|
|
// ========================================================
|
| 392 |
|
|
// Conditional Execution
|
| 393 |
|
|
// ========================================================
|
| 394 |
|
|
assign execute = conditional_execute ( i_condition, status_bits_flags );
|
| 395 |
|
|
|
| 396 |
|
|
// allow the PC to increment to the next instruction when current
|
| 397 |
|
|
// instruction does not execute
|
| 398 |
|
|
assign pc_wen = i_pc_wen || !execute;
|
| 399 |
|
|
|
| 400 |
|
|
// only update register bank if current instruction executes
|
| 401 |
|
|
assign reg_bank_wen = {{15{execute}} & i_reg_bank_wen};
|
| 402 |
|
|
|
| 403 |
71 |
csantifort |
assign reg_bank_wsel = {{4{~execute}} | i_reg_bank_wsel};
|
| 404 |
2 |
csantifort |
|
| 405 |
71 |
csantifort |
|
| 406 |
2 |
csantifort |
// ========================================================
|
| 407 |
|
|
// Priviledged output flag
|
| 408 |
|
|
// ========================================================
|
| 409 |
|
|
// Need to look at status_bits_mode_nxt so switch to priviledged mode
|
| 410 |
|
|
// at the same time as assert interrupt vector address
|
| 411 |
|
|
assign priviledged_nxt = ( i_status_bits_mode_wen ? status_bits_mode_nxt : status_bits_mode ) != USR ;
|
| 412 |
|
|
|
| 413 |
|
|
|
| 414 |
|
|
// ========================================================
|
| 415 |
|
|
// Write Enable
|
| 416 |
|
|
// ========================================================
|
| 417 |
|
|
// This must be de-asserted when execute is fault
|
| 418 |
|
|
assign write_enable_nxt = execute && i_write_data_wen;
|
| 419 |
|
|
|
| 420 |
|
|
|
| 421 |
|
|
// ========================================================
|
| 422 |
|
|
// Register Update
|
| 423 |
|
|
// ========================================================
|
| 424 |
|
|
|
| 425 |
|
|
assign priviledged_update = !i_fetch_stall;
|
| 426 |
|
|
assign data_access_update = !i_fetch_stall && execute;
|
| 427 |
|
|
assign write_enable_update = !i_fetch_stall;
|
| 428 |
|
|
assign write_data_update = !i_fetch_stall && execute && i_write_data_wen;
|
| 429 |
|
|
assign exclusive_update = !i_fetch_stall && execute;
|
| 430 |
|
|
assign address_update = !i_fetch_stall;
|
| 431 |
|
|
assign byte_enable_update = !i_fetch_stall && execute && i_write_data_wen;
|
| 432 |
|
|
assign copro_write_data_update = !i_fetch_stall && execute && i_copro_write_data_wen;
|
| 433 |
|
|
|
| 434 |
|
|
assign base_address_update = !i_fetch_stall && execute && i_base_address_wen;
|
| 435 |
|
|
assign status_bits_flags_update = !i_fetch_stall && execute && i_status_bits_flags_wen;
|
| 436 |
|
|
assign status_bits_mode_update = !i_fetch_stall && execute && i_status_bits_mode_wen;
|
| 437 |
|
|
assign status_bits_mode_rds_oh_update = !i_fetch_stall;
|
| 438 |
|
|
assign status_bits_irq_mask_update = !i_fetch_stall && execute && i_status_bits_irq_mask_wen;
|
| 439 |
|
|
assign status_bits_firq_mask_update = !i_fetch_stall && execute && i_status_bits_firq_mask_wen;
|
| 440 |
|
|
|
| 441 |
71 |
csantifort |
assign status_bits_mode_rds_nr = status_bits_mode_rds_oh_update ? status_bits_mode_rds_nxt :
|
| 442 |
|
|
status_bits_mode_rds ;
|
| 443 |
2 |
csantifort |
|
| 444 |
71 |
csantifort |
assign status_bits_mode_nr = status_bits_mode_update ? status_bits_mode_nxt :
|
| 445 |
|
|
status_bits_mode ;
|
| 446 |
|
|
|
| 447 |
2 |
csantifort |
always @( posedge i_clk )
|
| 448 |
|
|
begin
|
| 449 |
|
|
o_priviledged <= priviledged_update ? priviledged_nxt : o_priviledged;
|
| 450 |
|
|
o_exclusive <= exclusive_update ? i_exclusive_exec : o_exclusive;
|
| 451 |
|
|
o_data_access <= data_access_update ? i_data_access_exec : o_data_access;
|
| 452 |
|
|
o_write_enable <= write_enable_update ? write_enable_nxt : o_write_enable;
|
| 453 |
|
|
o_write_data <= write_data_update ? write_data_nxt : o_write_data;
|
| 454 |
|
|
o_address <= address_update ? o_address_nxt : o_address;
|
| 455 |
|
|
o_adex <= address_update ? adex_nxt : o_adex;
|
| 456 |
|
|
o_address_valid <= address_update ? 1'd1 : o_address_valid;
|
| 457 |
|
|
o_byte_enable <= byte_enable_update ? byte_enable_nxt : o_byte_enable;
|
| 458 |
|
|
o_copro_write_data <= copro_write_data_update ? write_data_nxt : o_copro_write_data;
|
| 459 |
|
|
|
| 460 |
|
|
base_address <= base_address_update ? rn : base_address;
|
| 461 |
|
|
|
| 462 |
|
|
status_bits_flags <= status_bits_flags_update ? status_bits_flags_nxt : status_bits_flags;
|
| 463 |
71 |
csantifort |
status_bits_mode <= status_bits_mode_nr;
|
| 464 |
2 |
csantifort |
status_bits_mode_rds_oh <= status_bits_mode_rds_oh_update ? status_bits_mode_rds_oh_nxt : status_bits_mode_rds_oh;
|
| 465 |
71 |
csantifort |
status_bits_mode_rds <= status_bits_mode_rds_nr;
|
| 466 |
2 |
csantifort |
status_bits_irq_mask <= status_bits_irq_mask_update ? status_bits_irq_mask_nxt : status_bits_irq_mask;
|
| 467 |
|
|
status_bits_firq_mask <= status_bits_firq_mask_update ? status_bits_firq_mask_nxt : status_bits_firq_mask;
|
| 468 |
|
|
end
|
| 469 |
|
|
|
| 470 |
|
|
|
| 471 |
|
|
// ========================================================
|
| 472 |
|
|
// Instantiate Barrel Shift
|
| 473 |
|
|
// ========================================================
|
| 474 |
74 |
csantifort |
`ifndef ALTERA_FPGA
|
| 475 |
15 |
csantifort |
a23_barrel_shift u_barrel_shift (
|
| 476 |
74 |
csantifort |
`else
|
| 477 |
|
|
a23_barrel_shift_fpga u_barrel_shift (
|
| 478 |
|
|
`endif
|
| 479 |
2 |
csantifort |
.i_in ( barrel_shift_in ),
|
| 480 |
|
|
.i_carry_in ( status_bits_flags[1] ),
|
| 481 |
|
|
.i_shift_amount ( shift_amount ),
|
| 482 |
|
|
.i_shift_imm_zero ( i_shift_imm_zero ),
|
| 483 |
|
|
.i_function ( i_barrel_shift_function ),
|
| 484 |
|
|
|
| 485 |
|
|
.o_out ( barrel_shift_out ),
|
| 486 |
|
|
.o_carry_out ( barrel_shift_carry )
|
| 487 |
|
|
);
|
| 488 |
|
|
|
| 489 |
|
|
|
| 490 |
|
|
// ========================================================
|
| 491 |
|
|
// Instantiate ALU
|
| 492 |
|
|
// ========================================================
|
| 493 |
15 |
csantifort |
a23_alu u_alu (
|
| 494 |
2 |
csantifort |
.i_a_in ( rn ),
|
| 495 |
|
|
.i_b_in ( barrel_shift_out ),
|
| 496 |
|
|
.i_barrel_shift_carry ( barrel_shift_carry ),
|
| 497 |
|
|
.i_status_bits_carry ( status_bits_flags[1] ),
|
| 498 |
|
|
.i_function ( i_alu_function ),
|
| 499 |
|
|
|
| 500 |
|
|
.o_out ( alu_out ),
|
| 501 |
|
|
.o_flags ( alu_flags )
|
| 502 |
|
|
);
|
| 503 |
|
|
|
| 504 |
|
|
|
| 505 |
|
|
// ========================================================
|
| 506 |
|
|
// Instantiate Booth 64-bit Multiplier-Accumulator
|
| 507 |
|
|
// ========================================================
|
| 508 |
15 |
csantifort |
a23_multiply u_multiply (
|
| 509 |
2 |
csantifort |
.i_clk ( i_clk ),
|
| 510 |
|
|
.i_fetch_stall ( i_fetch_stall ),
|
| 511 |
|
|
.i_a_in ( rs ),
|
| 512 |
|
|
.i_b_in ( rm ),
|
| 513 |
|
|
.i_function ( i_multiply_function ),
|
| 514 |
|
|
.i_execute ( execute ),
|
| 515 |
|
|
.o_out ( multiply_out ),
|
| 516 |
|
|
.o_flags ( multiply_flags ), // [1] = N, [0] = Z
|
| 517 |
|
|
.o_done ( o_multiply_done )
|
| 518 |
|
|
);
|
| 519 |
|
|
|
| 520 |
|
|
|
| 521 |
|
|
// ========================================================
|
| 522 |
|
|
// Instantiate Register Bank
|
| 523 |
|
|
// ========================================================
|
| 524 |
73 |
csantifort |
`ifndef A23_RAM_REGISTER_BANK
|
| 525 |
15 |
csantifort |
a23_register_bank u_register_bank(
|
| 526 |
2 |
csantifort |
.i_clk ( i_clk ),
|
| 527 |
|
|
.i_fetch_stall ( i_fetch_stall ),
|
| 528 |
|
|
.i_rm_sel ( i_rm_sel ),
|
| 529 |
|
|
.i_rds_sel ( i_rds_sel ),
|
| 530 |
|
|
.i_rn_sel ( i_rn_sel ),
|
| 531 |
|
|
.i_pc_wen ( pc_wen ),
|
| 532 |
|
|
.i_reg_bank_wen ( reg_bank_wen ),
|
| 533 |
|
|
.i_pc ( pc_nxt[25:2] ),
|
| 534 |
|
|
.i_reg ( reg_write_nxt ),
|
| 535 |
|
|
.i_mode_idec ( i_status_bits_mode ),
|
| 536 |
|
|
.i_mode_exec ( status_bits_mode ),
|
| 537 |
|
|
|
| 538 |
|
|
.i_status_bits_flags ( status_bits_flags ),
|
| 539 |
|
|
.i_status_bits_irq_mask ( status_bits_irq_mask ),
|
| 540 |
|
|
.i_status_bits_firq_mask ( status_bits_firq_mask ),
|
| 541 |
|
|
|
| 542 |
|
|
// pre-encoded in decode stage to speed up long path
|
| 543 |
|
|
.i_firq_not_user_mode ( i_firq_not_user_mode ),
|
| 544 |
|
|
|
| 545 |
|
|
// use one-hot version for speed, combine with i_user_mode_regs_store
|
| 546 |
|
|
.i_mode_rds_exec ( status_bits_mode_rds_oh ),
|
| 547 |
|
|
|
| 548 |
|
|
.i_user_mode_regs_load ( i_user_mode_regs_load ),
|
| 549 |
|
|
.o_rm ( rm ),
|
| 550 |
|
|
.o_rs ( rs ),
|
| 551 |
|
|
.o_rd ( rd ),
|
| 552 |
|
|
.o_rn ( rn ),
|
| 553 |
|
|
.o_pc ( pc )
|
| 554 |
|
|
);
|
| 555 |
73 |
csantifort |
`else
|
| 556 |
|
|
a23_ram_register_bank u_register_bank(
|
| 557 |
|
|
.i_clk ( i_clk ),
|
| 558 |
|
|
.i_fetch_stall ( i_fetch_stall ),
|
| 559 |
|
|
.i_rm_sel ( i_rm_sel_nxt ),
|
| 560 |
|
|
.i_rds_sel ( i_rds_sel_nxt ),
|
| 561 |
|
|
.i_rn_sel ( i_rn_sel_nxt ),
|
| 562 |
|
|
.i_pc_wen ( pc_wen ),
|
| 563 |
|
|
.i_reg_bank_wsel ( reg_bank_wsel ),
|
| 564 |
|
|
.i_pc ( pc_nxt[25:2] ),
|
| 565 |
|
|
.i_reg ( reg_write_nxt ),
|
| 566 |
2 |
csantifort |
|
| 567 |
73 |
csantifort |
.i_mode_exec_nxt ( status_bits_mode_nr ),
|
| 568 |
|
|
.i_mode_exec ( status_bits_mode ),
|
| 569 |
|
|
.i_mode_rds_exec ( status_bits_mode_rds_nr ),
|
| 570 |
|
|
.i_user_mode_regs_load ( i_user_mode_regs_load ),
|
| 571 |
2 |
csantifort |
|
| 572 |
73 |
csantifort |
.i_status_bits_flags ( status_bits_flags ),
|
| 573 |
|
|
.i_status_bits_irq_mask ( status_bits_irq_mask ),
|
| 574 |
|
|
.i_status_bits_firq_mask ( status_bits_firq_mask ),
|
| 575 |
|
|
|
| 576 |
|
|
.o_rm ( rm ),
|
| 577 |
|
|
.o_rs ( rs ),
|
| 578 |
|
|
.o_rd ( rd ),
|
| 579 |
|
|
.o_rn ( rn ),
|
| 580 |
|
|
.o_pc ( pc )
|
| 581 |
|
|
);
|
| 582 |
|
|
`endif
|
| 583 |
|
|
|
| 584 |
2 |
csantifort |
// ========================================================
|
| 585 |
|
|
// Debug - non-synthesizable code
|
| 586 |
|
|
// ========================================================
|
| 587 |
|
|
//synopsys translate_off
|
| 588 |
|
|
|
| 589 |
|
|
wire [(2*8)-1:0] xCONDITION;
|
| 590 |
|
|
wire [(4*8)-1:0] xMODE;
|
| 591 |
|
|
|
| 592 |
|
|
assign xCONDITION = i_condition == EQ ? "EQ" :
|
| 593 |
|
|
i_condition == NE ? "NE" :
|
| 594 |
|
|
i_condition == CS ? "CS" :
|
| 595 |
|
|
i_condition == CC ? "CC" :
|
| 596 |
|
|
i_condition == MI ? "MI" :
|
| 597 |
|
|
i_condition == PL ? "PL" :
|
| 598 |
|
|
i_condition == VS ? "VS" :
|
| 599 |
|
|
i_condition == VC ? "VC" :
|
| 600 |
|
|
i_condition == HI ? "HI" :
|
| 601 |
|
|
i_condition == LS ? "LS" :
|
| 602 |
|
|
i_condition == GE ? "GE" :
|
| 603 |
|
|
i_condition == LT ? "LT" :
|
| 604 |
|
|
i_condition == GT ? "GT" :
|
| 605 |
|
|
i_condition == LE ? "LE" :
|
| 606 |
|
|
i_condition == AL ? "AL" :
|
| 607 |
|
|
"NV " ;
|
| 608 |
|
|
|
| 609 |
|
|
assign xMODE = status_bits_mode == SVC ? "SVC" :
|
| 610 |
|
|
status_bits_mode == IRQ ? "IRQ" :
|
| 611 |
|
|
status_bits_mode == FIRQ ? "FIRQ" :
|
| 612 |
|
|
status_bits_mode == USR ? "USR" :
|
| 613 |
|
|
"XXX" ;
|
| 614 |
|
|
|
| 615 |
|
|
|
| 616 |
|
|
//synopsys translate_on
|
| 617 |
|
|
|
| 618 |
|
|
endmodule
|
| 619 |
|
|
|
| 620 |
|
|
|