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

Subversion Repositories amber

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /amber/trunk
    from Rev 86 to Rev 87
    Reverse comparison

Rev 86 → Rev 87

/sw/boot-loader-serial/fpga-version.h
1,?rev1len? → ?rev2line?,?rev2len?
#define AMBER_FPGA_VERSION "20150308134642"
#define AMBER_FPGA_VERSION "20150406182528"
/hw/tests/mov_rrx.S
0,0 → 1,93
/*****************************************************************
// //
// Amber 2 Core Instruction Test //
// //
// This file is part of the Amber project //
// http://www.opencores.org/project,amber //
// //
// Description //
// Tests mov with RRX //
// Checks that the carry flag value is rotated into //
// target register //
// Author(s): //
// - Conor Santifort, csantifort.amber@gmail.com //
// //
//////////////////////////////////////////////////////////////////
// //
// Copyright (C) 2010 Authors and OPENCORES.ORG //
// //
// This source file may be used and distributed without //
// restriction provided that this copyright statement is not //
// removed from the file and that any derivative work contains //
// the original copyright notice and the associated disclaimer. //
// //
// This source file is free software; you can redistribute it //
// and/or modify it under the terms of the GNU Lesser General //
// Public License as published by the Free Software Foundation; //
// either version 2.1 of the License, or (at your option) any //
// later version. //
// //
// This source is distributed in the hope that it will be //
// useful, but WITHOUT ANY WARRANTY; without even the implied //
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //
// PURPOSE. See the GNU Lesser General Public License for more //
// details. //
// //
// You should have received a copy of the GNU Lesser General //
// Public License along with this source; if not, download it //
// from http://www.opencores.org/lgpl.shtml //
// //
*****************************************************************/
 
#include "amber_registers.h"
#include "amber_macros.h"
 
.section .text
.globl main
main:
// sets the carry big
// Cant use p version of instrustion in 32-bit CPU because it writes the upper 4 bits of PC
teqp pc, #0x20000000
mov r0, #0
// without the 's' the rotation does not change the carry flag
mov r0, r0, rrx
// carry flag should still be set
bcc testfail
// check that r0 got the carry flag into bit 31
cmp r0, #0x80000000
bne testfail
 
// same again, except with movs so the carry flag gets set to bit 0 of r0
mov r0, #0
movs r0, r0, rrx
// carry flag should be cleared now
bcs testfail
// check that r0 got the carry flag into bit 31
cmp r0, #0x80000000
bne testfail
 
// check that carry flag can be set to 1 with same sequence
mov r0, #1
teqp pc, #0x00000000
bcs testfail
movs r0, r0, rrx
bcc testfail
cmp r0, #0x00000000
bne testfail
 
b testpass
testfail:
ldr r11, AdrTestStatus
str r10, [r11]
b testfail
testpass:
ldr r11, AdrTestStatus
mov r10, #17
str r10, [r11]
b testpass
 
AdrTestStatus: .word ADR_AMBER_TEST_STATUS
 
/hw/tests/teq.S
41,10 → 41,13
// Test "Strange issue with r12 after TEQLSP"
// Tests for bug where testlsp command would switch the core
// from supervisor into FIRQ mode if it were executed. However the condition is not
// met so it is not executed. Thje bug is the next instrument works in FIRQ mode anyway.
// met so it is not executed. The bug is the next instrument works in FIRQ mode anyway.
// This was caused because the mode bits used in the ececute stage were not conditional on the
// teq instrumention being executed.
 
// Also tests correct setting of carry flag when second operand is a constant
 
 
#include "amber_registers.h"
#include "amber_macros.h"
 
66,6 → 69,29
cmp r12, r6 // error if user mode r12 was not updated with new value
bne testfail
 
// check the carry flag
// When a flexible second operand constant is used with the instructions MOVS, MVNS, ANDS, ORRS, ORNS, EORS, BICS,
// TEQ or TST, the carry flag is updated to bit[31] of the constant, if the constant is greater than 255
// and can be produced by shifting an 8-bit value. These instructions do not affect the carry flag if
// Operand2 is any other constant.
teq r4, #0x80000000
bcc testfail
 
// keeps carry flag the same
teq r4, #0x00000000
bcc testfail
 
// sets the carry flag back to zero
teq r4, #0x40000000
bcs testfail
 
// set the carry flag and verify that teq with register for operand 2 does not clear it
teq r4, #0x80000000
mov r4, #0
mov r5, #0x40000000
teq r4, r5
bcc testfail
b testpass
testfail:
/hw/tests/and.S
58,13 → 58,14
mov r1, #0x0000005a
 
// should not unset the V flag value
// the carry flag is set to the shifter carry out
ands r2, r1, #0x00000055
 
// Check the V flag is still set, the Z flag is clear, the C flag
// gets cleared, and the N flag gets cleared
// is unchanged, and the N flag gets cleared
bvc testfail
beq testfail
bcs testfail
bcc testfail
bmi testfail
 
tst r2, #0x00000050
/hw/tests/tst.S
61,10 → 61,10
tst r1, #0
 
// Check the V flag and Z flag are still set, the C flag
// is clear, and the N flag gets cleared
// is set to the carry out, and the N flag gets cleared
bvc testfail
bne testfail
bcs testfail
bcc testfail
bmi testfail
 
// Test "Strange issue with r12 after TEQLSP"
96,6 → 96,36
movcc r0, #0
movcs r0, #1
 
// test carry flag
mov r0, #2
mov r1, #1
mov r3, #0x930
cmp r0, #1
mov r1, r3
tst r1, #0x10
bcc testfail
bcc testfail
bcc testfail
 
 
// clears all four flags
// Cant use p version of instrustion in 32-bit CPU because it writes the upper 4 bits of PC
teqp pc, #0x00000000
 
mov r0, #2
mov r1, #1
mov r3, #0x930
// next instruction sets the carry flag
// compare subtracts a 1 from the r0 value of 2
// means 2's compliment of '1' gets added to '2', so the carry bit is set
cmp r0, #1
mov r1, r3
// leaves carry flag at previous value
tst r1, #0x10
bcc testfail
 
b testpass
testfail:
/hw/tests/ldm5.S
48,10 → 48,20
ldmia r13!,{r1-r14}^ // load into user mode registers
 
// supervisor r14 value should be unchanged
//nop
//nop
mov r0, r14
cmp r0, #100
bne testfail
 
// same test again, using r13 instead of r14
mov r13, #100
ldr r14, Data1Base
ldmia r14!,{r1-r13}^ // load into user mode registers
mov r0, r13
cmp r0, #100
ldr r1, Data14Base
cmp r1, r14
bne testfail
 
beq testpass
 
testfail:
69,6 → 79,7
/* Write 17 to this address to generate a Test Passed message */
AdrTestStatus: .word ADR_AMBER_TEST_STATUS
Data1Base: .word Data1
Data14Base: .word Data14
Data1: .word 0x00
.word 0x01
.word 0x02
82,7 → 93,7
.word 0x0a
.word 0x0b
.word 0x0c
.word 0x0d
Data14: .word 0x0d
.word 0x0e
.word 0x0f
.word 0x10
/hw/vlog/amber23/a23_decode.v
173,7 → 173,7
// the instruction
wire [7:0] instruction_iabt_status; // abort status, follows the instruction
wire [1:0] instruction_sel;
reg [3:0] type;
reg [3:0] itype;
wire [3:0] opcode;
wire [7:0] imm8;
wire [31:0] offset12;
366,16 → 366,16
// Instruction Decode - Order is important!
always @*
casez ({instruction[27:20], instruction[7:4]})
12'b00010?001001 : type = SWAP;
12'b000000??1001 : type = MULT;
12'b00?????????? : type = REGOP;
12'b01?????????? : type = TRANS;
12'b100????????? : type = MTRANS;
12'b101????????? : type = BRANCH;
12'b110????????? : type = CODTRANS;
12'b1110???????0 : type = COREGOP;
12'b1110???????1 : type = CORTRANS;
default: type = SWI;
12'b00010?001001 : itype = SWAP;
12'b000000??1001 : itype = MULT;
12'b00?????????? : itype = REGOP;
12'b01?????????? : itype = TRANS;
12'b100????????? : itype = MTRANS;
12'b101????????? : itype = BRANCH;
12'b110????????? : itype = CODTRANS;
12'b1110???????0 : itype = COREGOP;
12'b1110???????1 : itype = CORTRANS;
default: itype = SWI;
endcase
 
388,28 → 388,32
 
assign o_rm_sel_nxt = instruction[3:0];
assign o_rn_sel_nxt = branch ? 4'd15 : // Use PC to calculate branch destination
instruction[19:16] ;
assign o_rn_sel_nxt = branch ? 4'd15 : // Use PC to calculate branch destination
instruction[19:16] ;
 
assign o_rds_sel_nxt = control_state == SWAP_WRITE ? instruction[3:0] : // Rm gets written out to memory
type == MTRANS ? mtrans_reg :
branch ? 4'd15 : // Update the PC
rds_use_rs ? instruction[11:8] :
instruction[15:12] ;
itype == MTRANS ? mtrans_reg :
branch ? 4'd15 : // Update the PC
rds_use_rs ? instruction[11:8] :
instruction[15:12] ;
 
assign shift_imm = instruction[11:7];
 
// this is used for RRX
assign shift_extend = !instruction[25] && !instruction[4] && !(|instruction[11:7]) && instruction[6:5] == 2'b11;
 
assign offset12 = { 20'h0, instruction[11:0]};
assign offset24 = {{6{instruction[23]}}, instruction[23:0], 2'd0 }; // sign extend
assign imm8 = instruction[7:0];
 
assign immediate_shifter_operand = instruction[25];
assign rds_use_rs = (type == REGOP && !instruction[25] && instruction[4]) ||
(type == MULT &&
assign rds_use_rs = (itype == REGOP && !instruction[25] && instruction[4]) ||
(itype == MULT &&
(control_state == MULT_PROC1 ||
control_state == MULT_PROC2 ||
instruction_valid && !interrupt )) ;
assign branch = type == BRANCH;
assign branch = itype == BRANCH;
assign opcode_compare =
opcode == CMP ||
opcode == CMN ||
417,22 → 421,22
opcode == TST ;
assign mem_op = type == TRANS;
assign mem_op = itype == TRANS;
assign load_op = mem_op && instruction[20];
assign store_op = mem_op && !instruction[20];
assign write_pc = pc_wen_nxt && pc_sel_nxt != 2'd0;
assign regop_set_flags = type == REGOP && instruction[20];
assign regop_set_flags = itype == REGOP && instruction[20];
 
assign mem_op_pre_indexed = instruction[24] && instruction[21];
assign mem_op_post_indexed = !instruction[24];
 
assign imm32_nxt = // add 0 to Rm
type == MULT ? { 32'd0 } :
itype == MULT ? { 32'd0 } :
// 4 x number of registers
type == MTRANS ? { mtrans_base_reg_change } :
type == BRANCH ? { offset24 } :
type == TRANS ? { offset12 } :
itype == MTRANS ? { mtrans_base_reg_change } :
itype == BRANCH ? { offset24 } :
itype == TRANS ? { offset12 } :
instruction[11:8] == 4'h0 ? { 24'h0, imm8[7:0] } :
instruction[11:8] == 4'h1 ? { imm8[1:0], 24'h0, imm8[7:2] } :
instruction[11:8] == 4'h2 ? { imm8[3:0], 24'h0, imm8[7:4] } :
492,6 → 496,7
default : mtrans_reg = 4'hf ;
endcase
 
 
always @*
casez (instruction[15:0])
16'b???????????????1 : mtrans_instruction_nxt = {instruction[31:16], instruction[15: 1], 1'd0};
540,15 → 545,15
 
assign firq_request = firq && !i_execute_status_bits[26];
assign irq_request = irq && !i_execute_status_bits[27];
assign swi_request = type == SWI;
assign swi_request = itype == SWI;
assign dabt_request = dabt_reg;
 
// copro15 and copro13 only supports reg trans opcodes
// all other opcodes involving co-processors cause an
// undefined instrution interrupt
assign und_request = type == CODTRANS ||
type == COREGOP ||
( type == CORTRANS && instruction[11:8] != 4'd15 );
assign und_request = itype == CODTRANS ||
itype == COREGOP ||
( itype == CORTRANS && instruction[11:8] != 4'd15 );
 
 
// in order of priority !!
644,7 → 649,7
if ( instruction_valid && !interrupt )
begin
if ( type == REGOP )
if ( itype == REGOP )
begin
if ( !opcode_compare )
begin
678,6 → 683,7
if ( opcode == ADD || opcode == CMN ) // CMN is just like an ADD
begin
alu_out_sel_nxt = 4'd1; // Add
use_carry_in_nxt = shift_extend;
end
if ( opcode == ADC ) // Add with Carry
684,7 → 690,7
begin
alu_out_sel_nxt = 4'd1; // Add
alu_cin_sel_nxt = 2'd2; // carry in from status_bits
use_carry_in_nxt = 1'd1;
use_carry_in_nxt = shift_extend;
end
if ( opcode == SUB || opcode == CMP ) // Subtract
731,14 → 737,16
if ( opcode == EOR || opcode == TEQ ) // Logical Exclusive OR, Test Equivalence (using EOR operator)
begin
alu_out_sel_nxt = 4'd6; // XOR
alu_out_sel_nxt = 4'd6; // XOR
alu_cout_sel_nxt = 1'd1; // i_barrel_shift_carry
use_carry_in_nxt = 1'd1;
end
 
if ( opcode == ORR )
begin
alu_out_sel_nxt = 4'd7; // OR
alu_cout_sel_nxt = 1'd1; // i_barrel_shift_carry
alu_cout_sel_nxt = 1'd1; // i_barrel_shift_carry
use_carry_in_nxt = 1'd1;
end
if ( opcode == BIC ) // Bit Clear (using AND & NOT operators)
746,17 → 754,20
alu_out_sel_nxt = 4'd8; // AND
alu_not_sel_nxt = 1'd1; // invert B
alu_cout_sel_nxt = 1'd1; // i_barrel_shift_carry
use_carry_in_nxt = 1'd1;
end
if ( opcode == MOV ) // Move
begin
alu_cout_sel_nxt = 1'd1; // i_barrel_shift_carry
use_carry_in_nxt = 1'd1;
end
if ( opcode == MVN ) // Move NOT
begin
alu_not_sel_nxt = 1'd1; // invert B
alu_cout_sel_nxt = 1'd1; // i_barrel_shift_carry
alu_cout_sel_nxt = 1'd1; // i_barrel_shift_carry
use_carry_in_nxt = 1'd1;
end
end
778,7 → 789,7
if ( store_op )
begin
write_data_wen_nxt = 1'd1;
if ( type == TRANS && instruction[22] )
if ( itype == TRANS && instruction[22] )
byte_enable_sel_nxt = 2'd1; // Save byte
end
799,10 → 810,10
else
address_sel_nxt = 4'd1; // alu out
if ( instruction[25] && type == TRANS )
if ( instruction[25] && itype == TRANS )
barrel_shift_data_sel_nxt = 2'd2; // Shift value from Rm register
if ( type == TRANS && instruction[25] && shift_imm != 5'd0 )
if ( itype == TRANS && instruction[25] && shift_imm != 5'd0 )
begin
barrel_shift_function_nxt = instruction[6:5];
barrel_shift_amount_sel_nxt = 2'd2; // imm_shift_amount
809,7 → 820,7
end
end
if ( type == BRANCH )
if ( itype == BRANCH )
begin
pc_sel_nxt = 2'd1; // alu_out
address_sel_nxt = 4'd1; // alu_out
822,7 → 833,7
end
end
if ( type == MTRANS )
if ( itype == MTRANS )
begin
saved_current_instruction_wen = 1'd1; // Save the memory access instruction to refer back to later
pc_wen_nxt = 1'd0; // hold current PC value
864,11 → 875,13
// LDM: load into user mode registers, when in priviledged mode
// Don't use mtrans_r15 here because its not loaded yet
if ( {instruction[22],instruction[20],instruction[15]} == 3'b110 )
//if ( {instruction[22],instruction[20],instruction[15]} == 3'b110 )
if ( {instruction[22:20],instruction[15]} == 4'b1010 )
user_mode_regs_load_nxt = 1'd1;
 
// SDM: store the user mode registers, when in priviledged mode
if ( {instruction[22],instruction[20]} == 3'b10 )
//if ( {instruction[22],instruction[20]} == 3'b10 )
if ( {instruction[22:20]} == 3'b100 )
o_user_mode_regs_store_nxt = 1'd1;
// update the base register ?
877,7 → 890,7
end
if ( type == MULT )
if ( itype == MULT )
begin
multiply_function_nxt[0] = 1'd1; // set enable
// some bits can be changed just below
891,7 → 904,7
// swp - do read part first
if ( type == SWAP )
if ( itype == SWAP )
begin
saved_current_instruction_wen = 1'd1; // Save the memory access instruction to refer back to later
pc_wen_nxt = 1'd0; // hold current PC value
904,7 → 917,7
 
 
// mcr & mrc - takes two cycles
if ( type == CORTRANS && !und_request )
if ( itype == CORTRANS && !und_request )
begin
saved_current_instruction_wen = 1'd1; // Save the memory access instruction to refer back to later
pc_wen_nxt = 1'd0; // hold current PC value
922,7 → 935,7
end
 
if ( type == SWI || und_request )
if ( itype == SWI || und_request )
begin
// save address of next instruction to Supervisor Mode LR
reg_write_sel_nxt = 3'd1; // pc -4
1030,7 → 1043,7
barrel_shift_function_nxt = ROR;
// load a byte
if ( type == TRANS && instruction[22] )
if ( itype == TRANS && instruction[22] )
alu_out_sel_nxt = 4'd3; // zero_extend8
if ( !dabt ) // dont load data there is an abort on the data read
1065,11 → 1078,13
write_data_wen_nxt = 1'd1;
// LDM: load into user mode registers, when in priviledged mode
if ( {instruction[22],instruction[20],mtrans_r15} == 3'b110 )
//if ( {instruction[22],instruction[20],mtrans_r15} == 3'b110 )
if ( {instruction[22:20],mtrans_r15} == 4'b1010 )
user_mode_regs_load_nxt = 1'd1;
// SDM: store the user mode registers, when in priviledged mode
if ( {instruction[22],instruction[20]} == 2'b10 )
//if ( {instruction[22],instruction[20]} == 2'b10 )
if ( {instruction[22:20]} == 3'b100 )
o_user_mode_regs_store_nxt = 1'd1;
end
end
1245,7 → 1260,7
reg_write_sel_nxt = 3'd2; // multiply_out
multiply_function_nxt = o_multiply_function;
if ( type == MULT ) // 32-bit
if ( itype == MULT ) // 32-bit
reg_bank_wsel_nxt = instruction[19:16]; // Rd
else // 64-bit / Long
reg_bank_wsel_nxt = instruction[15:12]; // RdLo
1484,7 → 1499,7
control_state_nxt = MEM_WAIT1;
if ( write_pc )
control_state_nxt = PC_STALL1;
if ( type == MTRANS )
if ( itype == MTRANS )
begin
if ( mtrans_num_registers != 5'd0 )
begin
1498,13 → 1513,13
control_state_nxt = MTRANS_EXEC3;
end
 
if ( type == MULT )
if ( itype == MULT )
control_state_nxt = MULT_PROC1;
 
if ( type == SWAP )
if ( itype == SWAP )
control_state_nxt = SWAP_WRITE;
 
if ( type == CORTRANS && !und_request )
if ( itype == CORTRANS && !und_request )
control_state_nxt = COPRO_WAIT;
// interrupt overrides everything else so its last
1593,7 → 1608,7
// to the pre-fetch instruction register
// then when its decoded, a copy is saved to the saved_current_instruction
// register
if (type == MTRANS)
if (itype == MTRANS)
begin
saved_current_instruction <= mtrans_instruction_nxt;
saved_current_instruction_iabt <= instruction_iabt;
/hw/vlog/amber23/a23_decompile.v
74,12 → 74,12
wire [4:0] shift_imm;
wire [3:0] opcode;
wire [3:0] condition;
wire [3:0] type;
wire [3:0] itype;
wire opcode_compare;
wire opcode_move;
wire no_shift;
wire shift_op_imm;
wire [1:0] mtrans_type;
wire [1:0] mtrans_itype;
wire s_bit;
 
reg [(5*8)-1:0] xINSTRUCTION_EXECUTE;
138,7 → 138,7
assign imm8 = execute_instruction[7:0];
 
assign no_shift = execute_instruction[11:4] == 8'h0;
assign mtrans_type = execute_instruction[24:23];
assign mtrans_itype = execute_instruction[24:23];
 
 
assign opcode_compare =
151,7 → 151,7
opcode == MOV ||
opcode == MVN ;
assign shift_op_imm = type == REGOP && execute_instruction[25] == 1'd1;
assign shift_op_imm = itype == REGOP && execute_instruction[25] == 1'd1;
 
assign imm32 = execute_instruction[11:8] == 4'h0 ? { 24'h0, imm8[7:0] } :
execute_instruction[11:8] == 4'h1 ? { imm8[1:0], 24'h0, imm8[7:2] } :
175,7 → 175,7
// Instruction decode
// ========================================================
// the order of these matters
assign type =
assign itype =
{execute_instruction[27:23], execute_instruction[21:20], execute_instruction[11:4] } == { 5'b00010, 2'b00, 8'b00001001 } ? SWAP : // Before REGOP
{execute_instruction[27:22], execute_instruction[7:4] } == { 6'b000000, 4'b1001 } ? MULT : // Before REGOP
{execute_instruction[27:26] } == { 2'b00 } ? REGOP :
192,16 → 192,16
// Convert some important signals to ASCII
// so their values can easily be displayed on a waveform viewer
//
assign TYPE_NAME = type == REGOP ? "REGOP " :
type == MULT ? "MULT " :
type == SWAP ? "SWAP " :
type == TRANS ? "TRANS " :
type == MTRANS ? "MTRANS " :
type == BRANCH ? "BRANCH " :
type == CODTRANS ? "CODTRANS" :
type == COREGOP ? "COREGOP " :
type == CORTRANS ? "CORTRANS" :
type == SWI ? "SWI " :
assign TYPE_NAME = itype == REGOP ? "REGOP " :
itype == MULT ? "MULT " :
itype == SWAP ? "SWAP " :
itype == TRANS ? "TRANS " :
itype == MTRANS ? "MTRANS " :
itype == BRANCH ? "BRANCH " :
itype == CODTRANS ? "CODTRANS" :
itype == COREGOP ? "COREGOP " :
itype == CORTRANS ? "CORTRANS" :
itype == SWI ? "SWI " :
"UNKNOWN " ;
 
213,40 → 213,40
xINSTRUCTION_EXECUTE = xINSTRUCTION_EXECUTE_R;
end // stalled
 
else if ( type == REGOP && opcode == ADC ) xINSTRUCTION_EXECUTE = "adc ";
else if ( type == REGOP && opcode == ADD ) xINSTRUCTION_EXECUTE = "add ";
else if ( type == REGOP && opcode == AND ) xINSTRUCTION_EXECUTE = "and ";
else if ( type == BRANCH && execute_instruction[24] == 1'b0 ) xINSTRUCTION_EXECUTE = "b ";
else if ( type == REGOP && opcode == BIC ) xINSTRUCTION_EXECUTE = "bic ";
else if ( type == BRANCH && execute_instruction[24] == 1'b1 ) xINSTRUCTION_EXECUTE = "bl ";
else if ( type == COREGOP ) xINSTRUCTION_EXECUTE = "cdp ";
else if ( type == REGOP && opcode == CMN ) xINSTRUCTION_EXECUTE = "cmn ";
else if ( type == REGOP && opcode == CMP ) xINSTRUCTION_EXECUTE = "cmp ";
else if ( type == REGOP && opcode == EOR ) xINSTRUCTION_EXECUTE = "eor ";
else if ( type == CODTRANS && execute_instruction[20] == 1'b1 ) xINSTRUCTION_EXECUTE = "ldc ";
else if ( type == MTRANS && execute_instruction[20] == 1'b1 ) xINSTRUCTION_EXECUTE = "ldm ";
else if ( type == TRANS && {execute_instruction[22],execute_instruction[20]} == {1'b0, 1'b1} ) xINSTRUCTION_EXECUTE = "ldr ";
else if ( type == TRANS && {execute_instruction[22],execute_instruction[20]} == {1'b1, 1'b1} ) xINSTRUCTION_EXECUTE = "ldrb ";
else if ( type == CORTRANS && execute_instruction[20] == 1'b0 ) xINSTRUCTION_EXECUTE = "mcr ";
else if ( type == MULT && execute_instruction[21] == 1'b1 ) xINSTRUCTION_EXECUTE = "mla ";
else if ( type == REGOP && opcode == MOV ) xINSTRUCTION_EXECUTE = "mov ";
else if ( type == CORTRANS && execute_instruction[20] == 1'b1 ) xINSTRUCTION_EXECUTE = "mrc ";
else if ( type == MULT && execute_instruction[21] == 1'b0 ) xINSTRUCTION_EXECUTE = "mul ";
else if ( type == REGOP && opcode == MVN ) xINSTRUCTION_EXECUTE = "mvn ";
else if ( type == REGOP && opcode == ORR ) xINSTRUCTION_EXECUTE = "orr ";
else if ( type == REGOP && opcode == RSB ) xINSTRUCTION_EXECUTE = "rsb ";
else if ( type == REGOP && opcode == RSC ) xINSTRUCTION_EXECUTE = "rsc ";
else if ( type == REGOP && opcode == SBC ) xINSTRUCTION_EXECUTE = "sbc ";
else if ( type == CODTRANS && execute_instruction[20] == 1'b0 ) xINSTRUCTION_EXECUTE = "stc ";
else if ( type == MTRANS && execute_instruction[20] == 1'b0 ) xINSTRUCTION_EXECUTE = "stm ";
else if ( type == TRANS && {execute_instruction[22],execute_instruction[20]} == {1'b0, 1'b0} ) xINSTRUCTION_EXECUTE = "str ";
else if ( type == TRANS && {execute_instruction[22],execute_instruction[20]} == {1'b1, 1'b0} ) xINSTRUCTION_EXECUTE = "strb ";
else if ( type == REGOP && opcode == SUB ) xINSTRUCTION_EXECUTE = "sub ";
else if ( type == SWI ) xINSTRUCTION_EXECUTE = "swi ";
else if ( type == SWAP && execute_instruction[22] == 1'b0 ) xINSTRUCTION_EXECUTE = "swp ";
else if ( type == SWAP && execute_instruction[22] == 1'b1 ) xINSTRUCTION_EXECUTE = "swpb ";
else if ( type == REGOP && opcode == TEQ ) xINSTRUCTION_EXECUTE = "teq ";
else if ( type == REGOP && opcode == TST ) xINSTRUCTION_EXECUTE = "tst ";
else if ( itype == REGOP && opcode == ADC ) xINSTRUCTION_EXECUTE = "adc ";
else if ( itype == REGOP && opcode == ADD ) xINSTRUCTION_EXECUTE = "add ";
else if ( itype == REGOP && opcode == AND ) xINSTRUCTION_EXECUTE = "and ";
else if ( itype == BRANCH && execute_instruction[24] == 1'b0 ) xINSTRUCTION_EXECUTE = "b ";
else if ( itype == REGOP && opcode == BIC ) xINSTRUCTION_EXECUTE = "bic ";
else if ( itype == BRANCH && execute_instruction[24] == 1'b1 ) xINSTRUCTION_EXECUTE = "bl ";
else if ( itype == COREGOP ) xINSTRUCTION_EXECUTE = "cdp ";
else if ( itype == REGOP && opcode == CMN ) xINSTRUCTION_EXECUTE = "cmn ";
else if ( itype == REGOP && opcode == CMP ) xINSTRUCTION_EXECUTE = "cmp ";
else if ( itype == REGOP && opcode == EOR ) xINSTRUCTION_EXECUTE = "eor ";
else if ( itype == CODTRANS && execute_instruction[20] == 1'b1 ) xINSTRUCTION_EXECUTE = "ldc ";
else if ( itype == MTRANS && execute_instruction[20] == 1'b1 ) xINSTRUCTION_EXECUTE = "ldm ";
else if ( itype == TRANS && {execute_instruction[22],execute_instruction[20]} == {1'b0, 1'b1} ) xINSTRUCTION_EXECUTE = "ldr ";
else if ( itype == TRANS && {execute_instruction[22],execute_instruction[20]} == {1'b1, 1'b1} ) xINSTRUCTION_EXECUTE = "ldrb ";
else if ( itype == CORTRANS && execute_instruction[20] == 1'b0 ) xINSTRUCTION_EXECUTE = "mcr ";
else if ( itype == MULT && execute_instruction[21] == 1'b1 ) xINSTRUCTION_EXECUTE = "mla ";
else if ( itype == REGOP && opcode == MOV ) xINSTRUCTION_EXECUTE = "mov ";
else if ( itype == CORTRANS && execute_instruction[20] == 1'b1 ) xINSTRUCTION_EXECUTE = "mrc ";
else if ( itype == MULT && execute_instruction[21] == 1'b0 ) xINSTRUCTION_EXECUTE = "mul ";
else if ( itype == REGOP && opcode == MVN ) xINSTRUCTION_EXECUTE = "mvn ";
else if ( itype == REGOP && opcode == ORR ) xINSTRUCTION_EXECUTE = "orr ";
else if ( itype == REGOP && opcode == RSB ) xINSTRUCTION_EXECUTE = "rsb ";
else if ( itype == REGOP && opcode == RSC ) xINSTRUCTION_EXECUTE = "rsc ";
else if ( itype == REGOP && opcode == SBC ) xINSTRUCTION_EXECUTE = "sbc ";
else if ( itype == CODTRANS && execute_instruction[20] == 1'b0 ) xINSTRUCTION_EXECUTE = "stc ";
else if ( itype == MTRANS && execute_instruction[20] == 1'b0 ) xINSTRUCTION_EXECUTE = "stm ";
else if ( itype == TRANS && {execute_instruction[22],execute_instruction[20]} == {1'b0, 1'b0} ) xINSTRUCTION_EXECUTE = "str ";
else if ( itype == TRANS && {execute_instruction[22],execute_instruction[20]} == {1'b1, 1'b0} ) xINSTRUCTION_EXECUTE = "strb ";
else if ( itype == REGOP && opcode == SUB ) xINSTRUCTION_EXECUTE = "sub ";
else if ( itype == SWI ) xINSTRUCTION_EXECUTE = "swi ";
else if ( itype == SWAP && execute_instruction[22] == 1'b0 ) xINSTRUCTION_EXECUTE = "swp ";
else if ( itype == SWAP && execute_instruction[22] == 1'b1 ) xINSTRUCTION_EXECUTE = "swpb ";
else if ( itype == REGOP && opcode == TEQ ) xINSTRUCTION_EXECUTE = "teq ";
else if ( itype == REGOP && opcode == TST ) xINSTRUCTION_EXECUTE = "tst ";
else xINSTRUCTION_EXECUTE = "unkow";
end
 
277,7 → 277,7
if (!i_instruction_execute)
begin
$fwrite(decompile_file,"-");
if ( type == SWI )
if ( itype == SWI )
$display ("Cycle %09d SWI not taken *************", `U_TB.clk_count);
end
else
296,8 → 296,8
 
fchars = 8 - numchars(xINSTRUCTION_EXECUTE);
// Print the Multiple transfer type
if (type == MTRANS )
// Print the Multiple transfer itype
if (itype == MTRANS )
begin
w_mtrans_type;
fchars = fchars - 2;
304,7 → 304,7
end
 
// Print the s bit
if ( ((type == REGOP && !opcode_compare) || type == MULT ) && s_bit == 1'b1 )
if ( ((itype == REGOP && !opcode_compare) || itype == MULT ) && s_bit == 1'b1 )
begin
$fwrite(decompile_file,"s");
fchars = fchars - 1;
311,7 → 311,7
end
 
// Print the p bit
if ( type == REGOP && opcode_compare && s_bit == 1'b1 && reg_d == 4'd15 )
if ( itype == REGOP && opcode_compare && s_bit == 1'b1 && reg_d == 4'd15 )
begin
$fwrite(decompile_file,"p");
fchars = fchars - 1;
341,7 → 341,7
// ========================================
// print the arguments for the instruction
// ========================================
case ( type )
case ( itype )
REGOP: regop_args;
TRANS: trans_args;
MTRANS: mtrans_args;
373,7 → 373,7
end
// Software Interrupt
if ( i_instruction_execute && type == SWI )
if ( i_instruction_execute && itype == SWI )
begin
$fwrite( decompile_file,"%09d interrupt swi", `U_TB.clk_count );
$fwrite( decompile_file,", return addr " );
397,7 → 397,7
3'd3: $fwrite( decompile_file,"irq" );
3'd4: $fwrite( decompile_file,"address exception" );
3'd5: $fwrite( decompile_file,"instruction abort" );
default: $fwrite( decompile_file,"unknown type" );
default: $fwrite( decompile_file,"unknown itype" );
endcase
$fwrite( decompile_file,", return addr " );
424,7 → 424,7
i_instruction_execute &&
i_interrupt == 3'd0 &&
!execute_undefined &&
type != SWI &&
itype != SWI &&
execute_address != get_32bit_signal(0) // Don't print jump to same address
)
begin
510,7 → 510,7
// ldm and stm types
task w_mtrans_type;
begin
case( mtrans_type )
case( mtrans_itype )
4'h0: $fwrite(decompile_file,"da");
4'h1: $fwrite(decompile_file,"ia");
4'h2: $fwrite(decompile_file,"db");
/hw/vlog/amber23/a23_execute.v
494,6 → 494,11
);
 
 
wire barrel_shift_carry_real;
assign barrel_shift_carry_real = i_barrel_shift_data_sel == 2'd0 ?
(i_imm_shift_amount[4:1] == 0 ? status_bits_flags[1] : i_imm32[31]) :
barrel_shift_carry;
 
// ========================================================
// Instantiate ALU
// ========================================================
500,7 → 505,8
a23_alu u_alu (
.i_a_in ( rn ),
.i_b_in ( barrel_shift_out ),
.i_barrel_shift_carry ( barrel_shift_carry ),
//.i_barrel_shift_carry ( barrel_shift_carry ),
.i_barrel_shift_carry ( barrel_shift_carry_real ),
.i_status_bits_carry ( status_bits_flags[1] ),
.i_function ( i_alu_function ),
 
/hw/vlog/amber25/a25_decompile.v
73,12 → 73,12
wire [4:0] shift_imm;
wire [3:0] opcode;
wire [3:0] condition;
wire [3:0] type;
wire [3:0] itype;
wire opcode_compare;
wire opcode_move;
wire no_shift;
wire shift_op_imm;
wire [1:0] mtrans_type;
wire [1:0] mtrans_itype;
wire s_bit;
 
reg [(5*8)-1:0] xINSTRUCTION_EXECUTE;
124,22 → 124,20
// ========================================================
// Fields within the instruction
// ========================================================
assign opcode = execute_instruction[24:21];
assign condition = execute_instruction[31:28];
assign s_bit = execute_instruction[20];
assign reg_n = execute_instruction[19:16];
assign reg_d = execute_instruction[15:12];
assign reg_m = execute_instruction[3:0];
assign reg_s = execute_instruction[11:8];
assign shift_imm = execute_instruction[11:7];
assign offset12 = execute_instruction[11:0];
assign offset8 = {execute_instruction[11:8], execute_instruction[3:0]};
assign imm8 = execute_instruction[7:0];
assign opcode = execute_instruction[24:21];
assign condition = execute_instruction[31:28];
assign s_bit = execute_instruction[20];
assign reg_n = execute_instruction[19:16];
assign reg_d = execute_instruction[15:12];
assign reg_m = execute_instruction[3:0];
assign reg_s = execute_instruction[11:8];
assign shift_imm = execute_instruction[11:7];
assign offset12 = execute_instruction[11:0];
assign offset8 = {execute_instruction[11:8], execute_instruction[3:0]};
assign imm8 = execute_instruction[7:0];
assign no_shift = execute_instruction[11:4] == 8'h0;
assign mtrans_itype = execute_instruction[24:23];
 
assign no_shift = execute_instruction[11:4] == 8'h0;
assign mtrans_type = execute_instruction[24:23];
 
 
assign opcode_compare =
opcode == CMP ||
opcode == CMN ||
150,7 → 148,7
opcode == MOV ||
opcode == MVN ;
assign shift_op_imm = type == REGOP && execute_instruction[25] == 1'd1;
assign shift_op_imm = itype == REGOP && execute_instruction[25] == 1'd1;
 
assign imm32 = execute_instruction[11:8] == 4'h0 ? { 24'h0, imm8[7:0] } :
execute_instruction[11:8] == 4'h1 ? { imm8[1:0], 24'h0, imm8[7:2] } :
174,7 → 172,7
// Instruction decode
// ========================================================
// the order of these matters
assign type =
assign itype =
{execute_instruction[27:23], execute_instruction[21:20], execute_instruction[11:4] } == { 5'b00010, 2'b00, 8'b00001001 } ? SWAP : // Before REGOP
{execute_instruction[27:22], execute_instruction[7:4] } == { 6'b000000, 4'b1001 } ? MULT : // Before REGOP
{execute_instruction[27:26] } == { 2'b00 } ? REGOP :
191,16 → 189,16
// Convert some important signals to ASCII
// so their values can easily be displayed on a waveform viewer
//
assign TYPE_NAME = type == REGOP ? "REGOP " :
type == MULT ? "MULT " :
type == SWAP ? "SWAP " :
type == TRANS ? "TRANS " :
type == MTRANS ? "MTRANS " :
type == BRANCH ? "BRANCH " :
type == CODTRANS ? "CODTRANS" :
type == COREGOP ? "COREGOP " :
type == CORTRANS ? "CORTRANS" :
type == SWI ? "SWI " :
assign TYPE_NAME = itype == REGOP ? "REGOP " :
itype == MULT ? "MULT " :
itype == SWAP ? "SWAP " :
itype == TRANS ? "TRANS " :
itype == MTRANS ? "MTRANS " :
itype == BRANCH ? "BRANCH " :
itype == CODTRANS ? "CODTRANS" :
itype == COREGOP ? "COREGOP " :
itype == CORTRANS ? "CORTRANS" :
itype == SWI ? "SWI " :
"UNKNOWN " ;
 
212,41 → 210,41
xINSTRUCTION_EXECUTE = xINSTRUCTION_EXECUTE_R;
end // stalled
 
else if ( type == REGOP && opcode == ADC ) xINSTRUCTION_EXECUTE = "adc ";
else if ( type == REGOP && opcode == ADD ) xINSTRUCTION_EXECUTE = "add ";
else if ( type == REGOP && opcode == AND ) xINSTRUCTION_EXECUTE = "and ";
else if ( type == BRANCH && execute_instruction[24] == 1'b0 ) xINSTRUCTION_EXECUTE = "b ";
else if ( type == REGOP && opcode == BIC ) xINSTRUCTION_EXECUTE = "bic ";
else if ( type == BRANCH && execute_instruction[24] == 1'b1 ) xINSTRUCTION_EXECUTE = "bl ";
else if ( type == COREGOP ) xINSTRUCTION_EXECUTE = "cdp ";
else if ( type == REGOP && opcode == CMN ) xINSTRUCTION_EXECUTE = "cmn ";
else if ( type == REGOP && opcode == CMP ) xINSTRUCTION_EXECUTE = "cmp ";
else if ( type == REGOP && opcode == EOR ) xINSTRUCTION_EXECUTE = "eor ";
else if ( type == CODTRANS && execute_instruction[20] == 1'b1 ) xINSTRUCTION_EXECUTE = "ldc ";
else if ( type == MTRANS && execute_instruction[20] == 1'b1 ) xINSTRUCTION_EXECUTE = "ldm ";
else if ( type == TRANS && {execute_instruction[22],execute_instruction[20]} == {1'b0, 1'b1} ) xINSTRUCTION_EXECUTE = "ldr ";
else if ( type == TRANS && {execute_instruction[22],execute_instruction[20]} == {1'b1, 1'b1} ) xINSTRUCTION_EXECUTE = "ldrb ";
else if ( type == CORTRANS && execute_instruction[20] == 1'b0 ) xINSTRUCTION_EXECUTE = "mcr ";
else if ( type == MULT && execute_instruction[21] == 1'b1 ) xINSTRUCTION_EXECUTE = "mla ";
else if ( type == REGOP && opcode == MOV ) xINSTRUCTION_EXECUTE = "mov ";
else if ( type == CORTRANS && execute_instruction[20] == 1'b1 ) xINSTRUCTION_EXECUTE = "mrc ";
else if ( type == MULT && execute_instruction[21] == 1'b0 ) xINSTRUCTION_EXECUTE = "mul ";
else if ( type == REGOP && opcode == MVN ) xINSTRUCTION_EXECUTE = "mvn ";
else if ( type == REGOP && opcode == ORR ) xINSTRUCTION_EXECUTE = "orr ";
else if ( type == REGOP && opcode == RSB ) xINSTRUCTION_EXECUTE = "rsb ";
else if ( type == REGOP && opcode == RSC ) xINSTRUCTION_EXECUTE = "rsc ";
else if ( type == REGOP && opcode == SBC ) xINSTRUCTION_EXECUTE = "sbc ";
else if ( type == CODTRANS && execute_instruction[20] == 1'b0 ) xINSTRUCTION_EXECUTE = "stc ";
else if ( type == MTRANS && execute_instruction[20] == 1'b0 ) xINSTRUCTION_EXECUTE = "stm ";
else if ( type == TRANS && {execute_instruction[22],execute_instruction[20]} == {1'b0, 1'b0} ) xINSTRUCTION_EXECUTE = "str ";
else if ( type == TRANS && {execute_instruction[22],execute_instruction[20]} == {1'b1, 1'b0} ) xINSTRUCTION_EXECUTE = "strb ";
else if ( type == REGOP && opcode == SUB ) xINSTRUCTION_EXECUTE = "sub ";
else if ( type == SWI ) xINSTRUCTION_EXECUTE = "swi ";
else if ( type == SWAP && execute_instruction[22] == 1'b0 ) xINSTRUCTION_EXECUTE = "swp ";
else if ( type == SWAP && execute_instruction[22] == 1'b1 ) xINSTRUCTION_EXECUTE = "swpb ";
else if ( type == REGOP && opcode == TEQ ) xINSTRUCTION_EXECUTE = "teq ";
else if ( type == REGOP && opcode == TST ) xINSTRUCTION_EXECUTE = "tst ";
else xINSTRUCTION_EXECUTE = "unkow";
else if ( itype == REGOP && opcode == ADC ) xINSTRUCTION_EXECUTE = "adc ";
else if ( itype == REGOP && opcode == ADD ) xINSTRUCTION_EXECUTE = "add ";
else if ( itype == REGOP && opcode == AND ) xINSTRUCTION_EXECUTE = "and ";
else if ( itype == BRANCH && execute_instruction[24] == 1'b0 ) xINSTRUCTION_EXECUTE = "b ";
else if ( itype == REGOP && opcode == BIC ) xINSTRUCTION_EXECUTE = "bic ";
else if ( itype == BRANCH && execute_instruction[24] == 1'b1 ) xINSTRUCTION_EXECUTE = "bl ";
else if ( itype == COREGOP ) xINSTRUCTION_EXECUTE = "cdp ";
else if ( itype == REGOP && opcode == CMN ) xINSTRUCTION_EXECUTE = "cmn ";
else if ( itype == REGOP && opcode == CMP ) xINSTRUCTION_EXECUTE = "cmp ";
else if ( itype == REGOP && opcode == EOR ) xINSTRUCTION_EXECUTE = "eor ";
else if ( itype == CODTRANS && execute_instruction[20] == 1'b1 ) xINSTRUCTION_EXECUTE = "ldc ";
else if ( itype == MTRANS && execute_instruction[20] == 1'b1 ) xINSTRUCTION_EXECUTE = "ldm ";
else if ( itype == TRANS && {execute_instruction[22],execute_instruction[20]} == {1'b0, 1'b1} ) xINSTRUCTION_EXECUTE = "ldr ";
else if ( itype == TRANS && {execute_instruction[22],execute_instruction[20]} == {1'b1, 1'b1} ) xINSTRUCTION_EXECUTE = "ldrb ";
else if ( itype == CORTRANS && execute_instruction[20] == 1'b0 ) xINSTRUCTION_EXECUTE = "mcr ";
else if ( itype == MULT && execute_instruction[21] == 1'b1 ) xINSTRUCTION_EXECUTE = "mla ";
else if ( itype == REGOP && opcode == MOV ) xINSTRUCTION_EXECUTE = "mov ";
else if ( itype == CORTRANS && execute_instruction[20] == 1'b1 ) xINSTRUCTION_EXECUTE = "mrc ";
else if ( itype == MULT && execute_instruction[21] == 1'b0 ) xINSTRUCTION_EXECUTE = "mul ";
else if ( itype == REGOP && opcode == MVN ) xINSTRUCTION_EXECUTE = "mvn ";
else if ( itype == REGOP && opcode == ORR ) xINSTRUCTION_EXECUTE = "orr ";
else if ( itype == REGOP && opcode == RSB ) xINSTRUCTION_EXECUTE = "rsb ";
else if ( itype == REGOP && opcode == RSC ) xINSTRUCTION_EXECUTE = "rsc ";
else if ( itype == REGOP && opcode == SBC ) xINSTRUCTION_EXECUTE = "sbc ";
else if ( itype == CODTRANS && execute_instruction[20] == 1'b0 ) xINSTRUCTION_EXECUTE = "stc ";
else if ( itype == MTRANS && execute_instruction[20] == 1'b0 ) xINSTRUCTION_EXECUTE = "stm ";
else if ( itype == TRANS && {execute_instruction[22],execute_instruction[20]} == {1'b0, 1'b0} ) xINSTRUCTION_EXECUTE = "str ";
else if ( itype == TRANS && {execute_instruction[22],execute_instruction[20]} == {1'b1, 1'b0} ) xINSTRUCTION_EXECUTE = "strb ";
else if ( itype == REGOP && opcode == SUB ) xINSTRUCTION_EXECUTE = "sub ";
else if ( itype == SWI ) xINSTRUCTION_EXECUTE = "swi ";
else if ( itype == SWAP && execute_instruction[22] == 1'b0 ) xINSTRUCTION_EXECUTE = "swp ";
else if ( itype == SWAP && execute_instruction[22] == 1'b1 ) xINSTRUCTION_EXECUTE = "swpb ";
else if ( itype == REGOP && opcode == TEQ ) xINSTRUCTION_EXECUTE = "teq ";
else if ( itype == REGOP && opcode == TST ) xINSTRUCTION_EXECUTE = "tst ";
else xINSTRUCTION_EXECUTE = "unkow";
end
 
always @ ( posedge i_clk )
313,7 → 311,7
if (!i_instruction_execute)
begin
$fwrite(decompile_file,"-");
if ( type == SWI )
if ( itype == SWI )
$display ("Cycle %09d SWI not taken *************", `U_TB.clk_count);
end
else
332,8 → 330,8
 
fchars = 8 - numchars(xINSTRUCTION_EXECUTE);
// Print the Multiple transfer type
if (type == MTRANS )
// Print the Multiple transfer itype
if (itype == MTRANS )
begin
w_mtrans_type;
fchars = fchars - 2;
340,7 → 338,7
end
 
// Print the s bit
if ( ((type == REGOP && !opcode_compare) || type == MULT ) && s_bit == 1'b1 )
if ( ((itype == REGOP && !opcode_compare) || itype == MULT ) && s_bit == 1'b1 )
begin
$fwrite(decompile_file,"s");
fchars = fchars - 1;
347,7 → 345,7
end
 
// Print the p bit
if ( type == REGOP && opcode_compare && s_bit == 1'b1 && reg_d == 4'd15 )
if ( itype == REGOP && opcode_compare && s_bit == 1'b1 && reg_d == 4'd15 )
begin
$fwrite(decompile_file,"p");
fchars = fchars - 1;
377,7 → 375,7
// ========================================
// print the arguments for the instruction
// ========================================
case ( type )
case ( itype )
REGOP: regop_args;
TRANS: trans_args;
MTRANS: mtrans_args;
409,7 → 407,7
end
// Software Interrupt
if ( i_instruction_execute && type == SWI )
if ( i_instruction_execute && itype == SWI )
begin
$fwrite( decompile_file,"%09d interrupt swi", `U_TB.clk_count );
$fwrite( decompile_file,", return addr " );
462,7 → 460,7
i_instruction_execute &&
i_interrupt == 3'd0 &&
!execute_undefined &&
type != SWI &&
itype != SWI &&
execute_address != get_32bit_signal(0) // Don't print jump to same address
)
begin
506,7 → 504,7
// ldm and stm types
task w_mtrans_type;
begin
case( mtrans_type )
case( mtrans_itype )
4'h0: $fwrite(decompile_file,"da");
4'h1: $fwrite(decompile_file,"ia");
4'h2: $fwrite(decompile_file,"db");

powered by: WebSVN 2.1.0

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