URL
https://opencores.org/ocsvn/amber/amber/trunk
Subversion Repositories amber
Compare Revisions
- This comparison shows the changes necessary to convert path
/amber/trunk/hw/vlog/amber25
- from Rev 17 to Rev 20
- ↔ Reverse comparison
Rev 17 → Rev 20
/a25_decode.v
125,9 → 125,12
output o_dabt_trigger, |
output [31:0] o_dabt_address, |
output [7:0] o_dabt_status, |
output o_conflict |
output o_conflict, |
output reg o_rn_use_read, |
output reg o_rm_use_read, |
output reg o_rs_use_read, |
output reg o_rd_use_read |
|
|
); |
|
`include "a25_localparams.v" |
270,6 → 273,7
|
wire instruction_valid; |
wire instruction_execute; |
reg instruction_execute_r = 'd0; |
|
reg [3:0] mtrans_reg1; // the current register being accessed as part of stm/ldm |
reg [3:0] mtrans_reg2; // the next register being accessed as part of stm/ldm |
327,6 → 331,10
wire conflict2; // Register conflict1 with ldr operation |
wire conflict; // Register conflict1 with ldr operation |
reg conflict_r = 'd0; |
reg rn_conflict1_r = 'd0; |
reg rm_conflict1_r = 'd0; |
reg rs_conflict1_r = 'd0; |
reg rd_conflict1_r = 'd0; |
|
|
// ======================================================== |
512,32 → 520,32
// ======================================================== |
// Register Conflict Detection |
// ======================================================== |
assign rn_valid = type == REGOP || type == MULT || type == SWAP || type == TRANS || type == MTRANS || type == CODTRANS; |
assign rm_valid = type == REGOP || type == MULT || type == SWAP || (type == TRANS && immediate_shift_op); |
assign rs_valid = rds_use_rs; |
assign rd_valid = type == TRANS && store_op; // str instruction |
assign stm_valid = type == MTRANS && !instruction[20]; // stm instruction |
|
assign rn_conflict1 = rn_valid && ( load_rd_d1_nxt[4] && rn_sel_nxt == load_rd_d1_nxt[3:0] ); |
assign rn_conflict2 = rn_valid && ( load_rd_d1 [4] && rn_sel_nxt == load_rd_d1 [3:0] ); |
assign rm_conflict1 = rm_valid && ( load_rd_d1_nxt[4] && rm_sel_nxt == load_rd_d1_nxt[3:0] ); |
assign rm_conflict2 = rm_valid && ( load_rd_d1 [4] && rm_sel_nxt == load_rd_d1 [3:0] ); |
assign rs_conflict1 = rs_valid && ( load_rd_d1_nxt[4] && rs_sel_nxt == load_rd_d1_nxt[3:0] ); |
assign rs_conflict2 = rs_valid && ( load_rd_d1 [4] && rs_sel_nxt == load_rd_d1 [3:0] ); |
assign rd_conflict1 = rd_valid && ( load_rd_d1_nxt[4] && instruction[15:12] == load_rd_d1_nxt[3:0] ); |
assign rd_conflict2 = rd_valid && ( load_rd_d1 [4] && instruction[15:12] == load_rd_d1 [3:0] ); |
assign stm_conflict1a = stm_valid && ( load_rd_d1_nxt[4] && mtrans_reg1 == load_rd_d1_nxt[3:0] ); |
assign stm_conflict1b = stm_valid && ( load_rd_d1_nxt[4] && mtrans_reg2 == load_rd_d1_nxt[3:0] ); |
assign stm_conflict2a = stm_valid && ( load_rd_d1 [4] && mtrans_reg1 == load_rd_d1 [3:0] ); |
assign stm_conflict2b = stm_valid && ( load_rd_d1 [4] && mtrans_reg2 == load_rd_d1 [3:0] ); |
assign rn_valid = type == REGOP || type == MULT || type == SWAP || type == TRANS || type == MTRANS || type == CODTRANS; |
assign rm_valid = type == REGOP || type == MULT || type == SWAP || (type == TRANS && immediate_shift_op); |
assign rs_valid = rds_use_rs; |
assign rd_valid = (type == TRANS && store_op) || (type == REGOP || type == SWAP); |
assign stm_valid = type == MTRANS && !instruction[20]; // stm instruction |
|
|
assign rn_conflict1 = instruction_execute && rn_valid && ( load_rd_d1_nxt[4] && rn_sel_nxt == load_rd_d1_nxt[3:0] ); |
assign rn_conflict2 = instruction_execute_r && rn_valid && ( load_rd_d1 [4] && rn_sel_nxt == load_rd_d1 [3:0] ); |
assign rm_conflict1 = instruction_execute && rm_valid && ( load_rd_d1_nxt[4] && rm_sel_nxt == load_rd_d1_nxt[3:0] ); |
assign rm_conflict2 = instruction_execute_r && rm_valid && ( load_rd_d1 [4] && rm_sel_nxt == load_rd_d1 [3:0] ); |
assign rs_conflict1 = instruction_execute && rs_valid && ( load_rd_d1_nxt[4] && rs_sel_nxt == load_rd_d1_nxt[3:0] ); |
assign rs_conflict2 = instruction_execute_r && rs_valid && ( load_rd_d1 [4] && rs_sel_nxt == load_rd_d1 [3:0] ); |
assign rd_conflict1 = instruction_execute && rd_valid && ( load_rd_d1_nxt[4] && instruction[15:12] == load_rd_d1_nxt[3:0] ); |
assign rd_conflict2 = instruction_execute_r && rd_valid && ( load_rd_d1 [4] && instruction[15:12] == load_rd_d1 [3:0] ); |
|
assign stm_conflict1a = instruction_execute && stm_valid && ( load_rd_d1_nxt[4] && mtrans_reg1 == load_rd_d1_nxt[3:0] ); |
assign stm_conflict1b = instruction_execute && stm_valid && ( load_rd_d1_nxt[4] && mtrans_reg2 == load_rd_d1_nxt[3:0] ); |
assign stm_conflict2a = instruction_execute_r && stm_valid && ( load_rd_d1 [4] && mtrans_reg1 == load_rd_d1 [3:0] ); |
assign stm_conflict2b = instruction_execute_r && stm_valid && ( load_rd_d1 [4] && mtrans_reg2 == load_rd_d1 [3:0] ); |
|
assign conflict1 = instruction_valid && |
(rn_conflict1 || rm_conflict1 || rs_conflict1 || rd_conflict1 || |
stm_conflict1a || stm_conflict1b); |
|
assign conflict2 = instruction_valid && |
(rn_conflict2 || rm_conflict2 || rs_conflict2 || rd_conflict2 || |
stm_conflict2a || stm_conflict2b); |
assign conflict2 = instruction_valid && (stm_conflict2a || stm_conflict2b); |
|
assign conflict = conflict1 || conflict2; |
|
545,7 → 553,16
always @( posedge i_clk ) |
if ( !i_access_stall ) |
begin |
conflict_r <= conflict; |
conflict_r <= conflict; |
instruction_execute_r <= instruction_execute; |
rn_conflict1_r <= rn_conflict1 && instruction_execute; |
rm_conflict1_r <= rm_conflict1 && instruction_execute; |
rs_conflict1_r <= rs_conflict1 && instruction_execute; |
rd_conflict1_r <= rd_conflict1 && instruction_execute; |
o_rn_use_read <= instruction_valid && ( rn_conflict1_r || rn_conflict2 ); |
o_rm_use_read <= instruction_valid && ( rm_conflict1_r || rm_conflict2 ); |
o_rs_use_read <= instruction_valid && ( rs_conflict1_r || rs_conflict2 ); |
o_rd_use_read <= instruction_valid && ( rd_conflict1_r || rd_conflict2 ); |
end |
|
assign o_conflict = conflict; |
/a25_core.v
178,8 → 178,11
wire icache_wb_ready; |
|
wire conflict; |
wire rn_use_read; |
wire rm_use_read; |
wire rs_use_read; |
wire rd_use_read; |
|
|
// data abort has priority |
assign decode_fault_status = dabt_trigger ? dabt_fault_status : iabt_fault_status; |
assign decode_fault_address = dabt_trigger ? dabt_fault_address : iabt_fault_address; |
287,7 → 290,11
.o_dabt_address ( dabt_fault_address ), |
.o_dabt_status ( dabt_fault_status ), |
|
.o_conflict ( conflict ) |
.o_conflict ( conflict ), |
.o_rn_use_read ( rn_use_read ), |
.o_rm_use_read ( rm_use_read ), |
.o_rs_use_read ( rs_use_read ), |
.o_rd_use_read ( rd_use_read ) |
); |
|
|
360,7 → 367,11
.i_status_bits_irq_mask_wen ( status_bits_irq_mask_wen ), |
.i_status_bits_firq_mask_wen ( status_bits_firq_mask_wen ), |
.i_copro_write_data_wen ( copro_write_data_wen ), |
.i_conflict ( conflict ) |
.i_conflict ( conflict ), |
.i_rn_use_read ( rn_use_read ), |
.i_rm_use_read ( rm_use_read ), |
.i_rs_use_read ( rs_use_read ), |
.i_rd_use_read ( rd_use_read ) |
); |
|
|
/a25_execute.v
119,8 → 119,11
input i_status_bits_irq_mask_wen, |
input i_status_bits_firq_mask_wen, |
input i_copro_write_data_wen, |
input i_conflict |
|
input i_conflict, |
input i_rn_use_read, |
input i_rm_use_read, |
input i_rs_use_read, |
input i_rd_use_read |
); |
|
`include "a25_localparams.v" |
142,6 → 145,10
wire [31:0] rs; |
wire [31:0] rd; |
wire [31:0] rn; |
wire [31:0] reg_bank_rn; |
wire [31:0] reg_bank_rm; |
wire [31:0] reg_bank_rs; |
wire [31:0] reg_bank_rd; |
wire [31:0] pc; |
wire [31:0] pc_nxt; |
wire [31:0] interrupt_vector; |
173,6 → 180,10
// case of data abort |
wire [31:0] read_data_filtered1; |
wire [31:0] read_data_filtered; |
wire [31:0] read_data_filtered_c; |
reg [31:0] read_data_filtered_r = 'd0; |
reg [3:0] load_rd_r = 'd0; |
wire [3:0] load_rd_c; |
|
wire write_enable_nxt; |
wire daddress_valid_nxt; |
446,10 → 457,34
// Address Valid |
// ======================================================== |
assign daddress_valid_nxt = execute && i_decode_daccess && !i_access_stall; |
assign iaddress_valid_nxt = i_decode_iaccess; |
|
// For some multi-cycle instructions, the stream of instrution |
// reads can be paused. However if the instruction does not execute |
// then the read stream must not be interrupted. |
assign iaddress_valid_nxt = i_decode_iaccess || !execute; |
|
|
// ======================================================== |
// Use read value from data memory instead of from register |
// ======================================================== |
assign rn = i_rn_use_read && i_rn_sel == load_rd_c ? read_data_filtered_c : reg_bank_rn; |
assign rm = i_rm_use_read && i_rm_sel == load_rd_c ? read_data_filtered_c : reg_bank_rm; |
assign rs = i_rs_use_read && i_rs_sel == load_rd_c ? read_data_filtered_c : reg_bank_rs; |
assign rd = i_rd_use_read && i_rs_sel == load_rd_c ? read_data_filtered_c : reg_bank_rd; |
|
|
always@( posedge i_clk ) |
if ( i_wb_read_data_valid ) |
begin |
read_data_filtered_r <= read_data_filtered; |
load_rd_r <= i_wb_load_rd[3:0]; |
end |
|
assign read_data_filtered_c = i_wb_read_data_valid ? read_data_filtered : read_data_filtered_r; |
assign load_rd_c = i_wb_read_data_valid ? i_wb_load_rd[3:0] : load_rd_r; |
|
|
// ======================================================== |
// Register Update |
// ======================================================== |
|
576,14 → 611,15
// use one-hot version for speed, combine with i_user_mode_regs_store |
.i_mode_rds_exec ( status_bits_mode_rds_oh ), |
|
.o_rm ( rm ), |
.o_rs ( rs ), |
.o_rd ( rd ), |
.o_rn ( rn ), |
.o_rm ( reg_bank_rm ), |
.o_rs ( reg_bank_rs ), |
.o_rd ( reg_bank_rd ), |
.o_rn ( reg_bank_rn ), |
.o_pc ( pc ) |
); |
|
|
|
// ======================================================== |
// Debug - non-synthesizable code |
// ======================================================== |