URL
https://opencores.org/ocsvn/zap/zap/trunk
Subversion Repositories zap
Compare Revisions
- This comparison shows the changes necessary to convert path
/zap
- from Rev 37 to Rev 36
- ↔ Reverse comparison
Rev 37 → Rev 36
/trunk/src/rtl/cpu/zap_alu_main.v
266,47 → 266,7
// values and not indices. |
|
|
reg [5:0] clz_rm; // Count leading zeros in Rm. |
|
always @* // CLZ implementation. |
begin |
casez(rm) |
32'b1???????????????????????????????: clz_rm = 6'd00; |
32'b01??????????????????????????????: clz_rm = 6'd01; |
32'b001?????????????????????????????: clz_rm = 6'd02; |
32'b0001????????????????????????????: clz_rm = 6'd03; |
32'b00001???????????????????????????: clz_rm = 6'd04; |
32'b000001??????????????????????????: clz_rm = 6'd05; |
32'b0000001?????????????????????????: clz_rm = 6'd06; |
32'b00000001????????????????????????: clz_rm = 6'd07; |
32'b000000001???????????????????????: clz_rm = 6'd08; |
32'b0000000001??????????????????????: clz_rm = 6'd09; |
32'b00000000001?????????????????????: clz_rm = 6'd10; |
32'b000000000001????????????????????: clz_rm = 6'd11; |
32'b0000000000001???????????????????: clz_rm = 6'd12; |
32'b00000000000001??????????????????: clz_rm = 6'd13; |
32'b000000000000001?????????????????: clz_rm = 6'd14; |
32'b0000000000000001????????????????: clz_rm = 6'd15; |
32'b00000000000000001???????????????: clz_rm = 6'd16; |
32'b000000000000000001??????????????: clz_rm = 6'd17; |
32'b0000000000000000001?????????????: clz_rm = 6'd18; |
32'b00000000000000000001????????????: clz_rm = 6'd19; |
32'b000000000000000000001???????????: clz_rm = 6'd20; |
32'b0000000000000000000001??????????: clz_rm = 6'd21; |
32'b00000000000000000000001?????????: clz_rm = 6'd22; |
32'b000000000000000000000001????????: clz_rm = 6'd23; |
32'b0000000000000000000000001???????: clz_rm = 6'd24; |
32'b00000000000000000000000001??????: clz_rm = 6'd25; |
32'b000000000000000000000000001?????: clz_rm = 6'd26; |
32'b0000000000000000000000000001????: clz_rm = 6'd27; |
32'b00000000000000000000000000001???: clz_rm = 6'd28; |
32'b000000000000000000000000000001??: clz_rm = 6'd29; |
32'b0000000000000000000000000000001?: clz_rm = 6'd30; |
32'b00000000000000000000000000000001: clz_rm = 6'd31; |
default: clz_rm = 6'd32; // All zeros. |
endcase |
end |
|
// Destination index about to be output. |
reg [zap_clog2(PHY_REGS)-1:0] o_destination_index_nxt; |
|
615,7 → 575,7
tmp_flags[31:28] = {n,z,c,v}; |
|
// Write out the result. |
tmp_sum = op == CLZ ? clz_rm : sum; |
tmp_sum = sum; |
end |
|
// Drive nxt pin of result register. |
/trunk/src/rtl/cpu/zap_decode.v
127,7 → 127,7
`ifndef SYNTHESIS |
|
// Debug only. |
reg bx, dp, br, mrs, msr, ls, mult, halfword_ls, swi, dp1, dp2, dp3, lmult, clz; |
reg bx, dp, br, mrs, msr, ls, mult, halfword_ls, swi, dp1, dp2, dp3, lmult; |
|
always @* |
begin |
149,7 → 149,6
// |
if ( i_instruction_valid ) |
casez ( i_instruction[31:0] ) |
CLZ_INSTRUCTION: clz = 1; |
BX_INST: bx = 1; |
MRS: mrs = 1; |
MSR,MSR_IMMEDIATE: msr = 1; |
218,8 → 217,7
end |
else if ( i_instruction_valid ) |
casez ( i_instruction[31:0] ) |
CLZ_INSTRUCTION: decode_clz ( i_instruction ); |
BX_INST: decode_bx ( i_instruction ); |
BX_INST: decode_bx ( i_instruction ); |
MRS: decode_mrs ( i_instruction ); |
MSR,MSR_IMMEDIATE: decode_msr ( i_instruction ); |
|
248,28 → 246,6
// ---------------------------------------------------------------------------- |
|
// ============================= |
// Decode CLZ |
// ============================= |
task decode_clz ( input [35:0] i_instruction ); |
begin: tskDecodeClz |
o_condition_code = i_instruction[31:28]; |
o_flag_update = 1'd0; // Instruction does not update any flags. |
o_alu_operation = CLZ; // Added. |
|
// Rn = 0. |
o_alu_source = 0; |
o_alu_source[32] = IMMED_EN; |
|
// Rm = register whose CLZ must be found. |
o_shift_source = {i_instruction[`DP_RB_EXTEND], i_instruction[`DP_RB]}; // Rm |
o_shift_source[32] = INDEX_EN; |
o_shift_operation = LSL; |
o_shift_length = 0; |
o_shift_length[32] = IMMED_EN; // Shift length is 0 of course. |
end |
endtask |
|
// ============================= |
// Decode long multiplication. |
// ============================= |
task decode_lmult ( input [35:0] i_instruction ); // Uses bit 35. rm.rs + {rh, rn} |
495,12 → 471,11
// the job of the writeback stage. |
task decode_bx( input [34:0] i_instruction ); |
begin: tskDecodeBx |
reg [34:0] temp; |
|
reg [31:0] temp; |
temp = i_instruction[31:0]; |
temp[31:4] = 0; // Zero out stuff to avoid conflicts in the function. |
temp[11:4] = 0; |
|
process_instruction_specified_shift(temp); |
process_instruction_specified_shift(temp[11:0]); |
|
// The RAW ALU source does not matter. |
o_condition_code = i_instruction[31:28]; |
/trunk/src/rtl/cpu/zap_localparams.vh
189,24 → 189,13
// CDP |
localparam [31:0] CDP = 32'b????_1110_????????_????????_????????; |
|
// CLZ |
localparam [31:0] CLZ_INSTRUCTION = 32'b????_00010110_1111_????_1111_0001_????; |
/* COMPRESSED ( Not THUMB! THIS IS NOT COMPATIBLE WITH THE THUMB(R) ISA. ) */ |
|
// BLX(1) |
localparam [31:0] BLX1 = 32'b1111_101_?_????????_????????_????????; |
|
// BLX(2) |
localparam [31:0] BLX2 = 32'b????_00010010_1111_1111_1111_0011_????; |
|
/* Thumb ISA */ |
|
//B |
localparam [15:0] T_BRANCH_COND = 16'b1101_????_????????; |
localparam [15:0] T_BRANCH_NOCOND = 16'b11100_???????????; |
localparam [15:0] T_BL = 16'b1111_?_???????????; |
localparam [15:0] T_BX = 16'b01000111_0_?_???_000; |
localparam [15:0] T_BLX1 = 16'b11101_???????????; |
localparam [15:0] T_BLX2 = 16'b010001111_?_???_000; |
|
// SWI |
localparam [15:0] T_SWI = 16'b11011111_????????; |
/trunk/src/rtl/cpu/zap_predecode_mem_fsm.v
105,12 → 105,9
wire [11:0] oc_offset; |
|
// Registers. |
reg [3:0] state_ff, state_nxt; |
reg [2:0] state_ff, state_nxt; |
reg [15:0] reglist_ff, reglist_nxt; |
|
// Const reg for BLX. |
reg [31:0] const_ff, const_nxt; |
|
/////////////////////////////////////////////////////////////////////////////// |
|
// States. |
122,13 → 119,6
localparam LMULT_BUSY = 5; |
localparam BL_S1 = 6; |
localparam SWAP3 = 7; |
localparam BLX1_ARM_S0 = 8; |
localparam BLX1_ARM_S1 = 9; |
localparam BLX1_ARM_S2 = 10; |
localparam BLX1_ARM_S3 = 11; |
localparam BLX1_ARM_S4 = 12; |
localparam BLX1_ARM_S5 = 13; |
localparam BLX2_ARM_S0 = 14; |
|
/////////////////////////////////////////////////////////////////////////////// |
|
139,8 → 129,6
// Next state and output logic. |
always @* |
begin |
const_nxt = const_ff; |
|
// Block interrupts by default. |
o_irq = 0; |
o_fiq = 0; |
153,132 → 141,10
o_stall_from_decode = 1'd0; |
|
case ( state_ff ) |
BLX1_ARM_S0: // SCONST = ($signed(constant) << 2) + ( H << 1 )) |
begin: blk3223 |
reg H; |
|
o_stall_from_decode = 1'd1; |
|
H = i_instruction[24]; |
const_nxt = ( { {8{i_instruction[23]}} , i_instruction[23:0] } << 2 ) + ( H << 1 ); |
|
// MOV DUMMY0, SCONST[7:0] ror 0 |
o_instruction[31:0] = {AL, 2'b00, 1'b1, MOV, 1'd0, 4'd0, 4'd0, 4'd0, const_nxt[7:0]}; |
{o_instruction[`DP_RD_EXTEND], o_instruction[`DP_RD]} = ARCH_DUMMY_REG0; |
end |
|
BLX1_ARM_S1: |
begin |
o_stall_from_decode = 1'd1; |
|
// ORR DUMMY0, DUMMY0, SCONST[15:8] ror 12*2 |
o_instruction[31:0] = {AL, 2'b00, 1'b1, ORR, 1'd0, 4'd0, 4'd0, 4'd12, const_nxt[15:8]}; |
{o_instruction[`DP_RD_EXTEND], o_instruction[`DP_RD]} = ARCH_DUMMY_REG0; |
{o_instruction[`DP_RA_EXTEND], o_instruction[`DP_RA]} = ARCH_DUMMY_REG0; |
end |
|
BLX1_ARM_S2: |
begin |
o_stall_from_decode = 1'd1; |
|
// ORR DUMMY0, DUMMY0, SCONST[23:16] ror 8*2 |
o_instruction[31:0] = {AL, 2'b00, 1'b1, ORR, 1'd0, 4'd0, 4'd0, 4'd8, const_nxt[23:16]}; |
{o_instruction[`DP_RD_EXTEND], o_instruction[`DP_RD]} = ARCH_DUMMY_REG0; |
{o_instruction[`DP_RA_EXTEND], o_instruction[`DP_RA]} = ARCH_DUMMY_REG0; |
end |
|
BLX1_ARM_S3: |
begin |
o_stall_from_decode = 1'd1; |
|
// ORR DUMMY0, DUMMY0, SCONST[31:24] ror 4*2 |
o_instruction[31:0] = {AL, 2'b00, 1'b1, ORR, 1'd0, 4'd0, 4'd0, 4'd4, const_nxt[31:24]}; |
{o_instruction[`DP_RD_EXTEND], o_instruction[`DP_RD]} = ARCH_DUMMY_REG0; |
{o_instruction[`DP_RA_EXTEND], o_instruction[`DP_RA]} = ARCH_DUMMY_REG0; |
end |
|
BLX1_ARM_S4: |
begin |
o_stall_from_decode = 1'd1; |
|
// ORR DUMMY0, DUMMY0, 1 - Needed to indicate a switch |
// to Thumb. |
o_instruction[31:0] = {AL, 2'b00, 1'b1, ORR, 1'd0, 4'd0, 4'd0, 4'd0, !i_cpsr_t}; |
{o_instruction[`DP_RD_EXTEND], o_instruction[`DP_RD]} = ARCH_DUMMY_REG0; |
{o_instruction[`DP_RA_EXTEND], o_instruction[`DP_RA]} = ARCH_DUMMY_REG0; |
end |
|
BLX1_ARM_S5: |
begin |
// Remove stall. |
o_stall_from_decode = 1'd0; |
|
// BX DUMMY0 |
o_instruction = 32'hE12FFF10; |
{o_instruction[`DP_RB_EXTEND], o_instruction[`DP_RB]} = ARCH_DUMMY_REG0; |
end |
|
BLX2_ARM_S0: |
begin |
// Remove stall. |
o_stall_from_decode = 1'd0; |
|
// BX Rm. Just remove the L bit. Conditional is passed |
// on. |
o_instruction = i_instruction; |
o_instruction[5] = 1'd0; |
end |
|
IDLE: |
begin |
// BLX1 detected. Unconditional!!! |
// Immediate Offset. |
if ( i_instruction[31:25] == BLX1[31:25] && i_instruction_valid ) |
begin |
`ifdef LDM_DEBUG |
$display($time, "%m: BLX1 detected!"); |
`endif |
// We must generate a SUBAL LR,PC,4 ROR 0 |
// This makes LR have the value |
// PC+8-4=PC+4 which is the address of |
// the next instruction. |
o_instruction = {AL, 2'b00, 1'b1, SUB, 1'd0, 4'd14, 4'd15, 12'd4}; |
|
// In Thumb mode, we must generate PC+4-2 |
if ( i_cpsr_t ) |
begin |
o_instruction[11:0] = 12'd2; // Modify the instruction. |
end |
|
o_stall_from_decode = 1'd1; // Stall the core. |
state_nxt = BLX1_ARM_S0; |
end |
else if ( i_instruction[27:4] == BLX2[27:4] && i_instruction_valid ) // BLX2 detected. Register offset. CONDITIONAL. |
begin |
`ifdef LDM_DEBUG |
$display($time, "%m: BLX2 detected!"); |
`endif |
// Write address of next instruction to LR. Now this |
// depends on the mode we're in. Mode in the sense |
// ARM/Thumb. We need to look at i_cpsr_t. |
|
// We need to generate a SUBcc LR,PC,4 ROR 0 |
// to store the next instruction address in |
// LR. |
o_instruction = {i_instruction[31:28], 2'b00, 1'b1, SUB, 1'd0, 4'd14, 4'd15, 12'd4}; |
|
// In Thumb mode, we need to remove 2 from PC |
// instead of 4. |
if ( i_cpsr_t ) |
begin |
o_instruction[11:0] = 12'd2; // modify instr. |
end |
|
o_stall_from_decode = 1'd1; // Stall the core. |
state_nxt = BLX2_ARM_S0; |
end |
// LDM/STM detected... |
else if ( id == 3'b100 && i_instruction_valid ) |
if ( id == 3'b100 && i_instruction_valid ) |
begin |
// Backup base register. |
// MOV DUMMY0, Base |
320,7 → 186,7
end |
else if ( i_instruction[27:23] == 5'b00010 && |
i_instruction[21:20] == 2'b00 && |
i_instruction[11:4] == 4'b1001 && i_instruction_valid ) // SWAP |
i_instruction[11:4] == 4'b1001 ) |
begin |
// Swap |
`ifdef LDM_DEBUG |
345,7 → 211,7
o_stall_from_decode = 1'd1; |
end |
else if ( i_instruction[27:23] == 5'd1 && |
i_instruction[7:4] == 4'b1001 && i_instruction_valid ) |
i_instruction[7:4] == 4'b1001 ) |
begin |
// LMULT |
state_nxt = LMULT_BUSY; |
356,7 → 222,7
o_instruction_valid = i_instruction_valid; |
end |
else if ( i_instruction[27:25] == 3'b101 && |
i_instruction[24] && i_instruction_valid ) // BL. |
i_instruction[24] ) // BL. |
begin |
// Move to new state. In that state, we will |
// generate a plain branch. |
671,7 → 537,6
begin |
state_ff <= state_nxt; |
reglist_ff <= reglist_nxt; |
const_ff <= const_nxt; |
end |
end |
|
682,7 → 547,6
begin |
state_ff <= IDLE; |
reglist_ff <= 16'd0; |
const_ff <= 32'd0; |
end |
endtask |
|
/trunk/src/scripts/makefile
30,7 → 30,7
COBJFILES := $(patsubst %.c,../../../obj/ts/$(TC)/%_c.o,$(C_FILES)) |
AOBJFILES := $(patsubst %.s,../../../obj/ts/$(TC)/%_s.o,$(S_FILES)) |
GCC_SRC := ../../../sw/gcc-arm-none-eabi-*-linux.tar.* |
CFLAGS := -c -msoft-float -mfloat-abi=soft -march=armv4t -g |
CFLAGS := -c -msoft-float -mfloat-abi=soft -mcpu=arm7tdmi -g |
SFLAGS := -mcpu=arm7tdmi -g |
LFLAGS := -T |
OFLAGS := -O binary |
/trunk/src/ts/thumb_test/makefile
File deleted
/trunk/src/ts/thumb_test/thumb.s
File deleted
/trunk/src/ts/thumb_test/Description.txt
File deleted
/trunk/src/ts/thumb_test/linker.ld
File deleted
/trunk/src/ts/thumb_test/Config.cfg
File deleted
/trunk/src/ts/thumb_test/main.c
File deleted
/trunk/src/ts/thumb_test1/Config.cfg
0,0 → 1,41
# TC config. |
|
%Config = ( |
# CPU configuration. |
DATA_CACHE_SIZE => 4096, # Data cache size in bytes |
CODE_CACHE_SIZE => 4096, # Instruction cache size in bytes |
CODE_SECTION_TLB_ENTRIES => 8, # Instruction section TLB entries. |
CODE_SPAGE_TLB_ENTRIES => 32, # Instruction small page TLB entries. |
CODE_LPAGE_TLB_ENTRIES => 16, # Instruction large page TLB entries. |
DATA_SECTION_TLB_ENTRIES => 8, # Data section TLB entries. |
DATA_SPAGE_TLB_ENTRIES => 32, # Data small page TLB entries. |
DATA_LPAGE_TLB_ENTRIES => 16, # Data large page TLB entries. |
BP_DEPTH => 1024, # Branch predictor depth. |
INSTR_FIFO_DEPTH => 4, # Instruction buffer depth. |
STORE_BUFFER_DEPTH => 16, # Store buffer depth. |
SYNTHESIS => 0, # 0 allows debug messages. |
|
# Testbench configuration. |
UART_TX_TERMINAL => 0, # 1 will open a UART TX terminal. |
EXT_RAM_SIZE => 32768, # External RAM size. |
SEED => -1, # Seed. Use -1 to use random seed. |
DUMP_START => 2000, # Starting memory address from which to dump. |
DUMP_SIZE => 200, # Length of dump in bytes. |
IRQ_EN => 0, # Make this 1 to enable IRQ signal from TB. |
FIQ_EN => 0, # Make this 1 to enable FIQ signal from TB. |
MAX_CLOCK_CYCLES => 1000, # Clock cycles to run the simulation for. |
ALLOW_STALLS => 1, # Make this 1 to allow external RAM to signal a stall. |
DEFINE_TLB_DEBUG => 0, # Make this 1 to define TLB_DEBUG. Useful for debugging the TLB. |
REG_CHECK => { |
"r0" => "32'hFFFFFFFF", |
"r1" => "32'd10", |
"r2" => "32'd10", |
"r3" => "32'd10", |
"r4" => "32'd10", |
"r5" => "32'd10", |
"r6" => "32'd10", |
"r7" => "32'd10" |
}, |
FINAL_CHECK => {} |
); |
|
/trunk/src/ts/thumb_test1/Description.txt
0,0 → 1,3
This test simply switches to thumb state (in SVC mode) and |
writes to R0 to R7. R0 should read -1 while the others should |
read 10. |
/trunk/src/ts/thumb_test1/linker.ld
0,0 → 1,16
|
/* Linker Script */ |
|
ENTRY(_Reset) /* _Reset is the entry point. This is the entry point in the bootstrap assembler */ |
|
/* Define how sections of the program are organized. */ |
SECTIONS |
{ |
. = 0x00000; /* Location Counter. */ |
.text : { *(.text) } /* Text section is expected to be starting at 0x0.*/ |
.data : { *(.data) } /* Immediately followed by data section */ |
.bss : { *(.bss) *(COMMON) } /* Immediately followed by BSS section. Common sections are also included in BSS. */ |
. = ALIGN(8); /* Align the location counter. */ |
. = . + 0x1000; /* 4kB of descending stack memory */ |
stack_top = .; /* Make stack_top same as location counter. */ |
} |
/trunk/src/ts/thumb_test1/main.c
0,0 → 1,4
int main() |
{ |
return 0; |
} |
/trunk/src/ts/thumb_test1/makefile
0,0 → 1,2
# Execute the main Makefile. |
include ../../scripts/makefile |
/trunk/src/ts/thumb_test1/thumb.s
0,0 → 1,23
.text |
.global _Reset |
|
_Reset: |
ldr sp, =#4000 |
ldr r0, =myThumbFunction+1 |
mov lr, pc |
bx r0 |
ldr r0, =#0xFFFFFFFF |
here: b here |
|
.thumb_func |
myThumbFunction: |
mov r0, #10 |
mov r1, #10 |
mov r2, #10 |
mov r3, #10 |
mov r4, #10 |
mov r5, #10 |
mov r6, #10 |
mov r7, #10 |
bx lr |
|