OpenCores
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 36 to Rev 37
    Reverse comparison

Rev 36 → Rev 37

/trunk/src/rtl/cpu/zap_alu_main.v
266,7 → 266,47
// 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;
 
575,7 → 615,7
tmp_flags[31:28] = {n,z,c,v};
 
// Write out the result.
tmp_sum = sum;
tmp_sum = op == CLZ ? clz_rm : 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;
reg bx, dp, br, mrs, msr, ls, mult, halfword_ls, swi, dp1, dp2, dp3, lmult, clz;
 
always @*
begin
149,6 → 149,7
//
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;
217,7 → 218,8
end
else if ( i_instruction_valid )
casez ( i_instruction[31:0] )
BX_INST: decode_bx ( i_instruction );
CLZ_INSTRUCTION: decode_clz ( i_instruction );
BX_INST: decode_bx ( i_instruction );
MRS: decode_mrs ( i_instruction );
MSR,MSR_IMMEDIATE: decode_msr ( i_instruction );
 
246,6 → 248,28
// ----------------------------------------------------------------------------
 
// =============================
// 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}
471,11 → 495,12
// the job of the writeback stage.
task decode_bx( input [34:0] i_instruction );
begin: tskDecodeBx
reg [31:0] temp;
reg [34:0] temp;
 
temp = i_instruction[31:0];
temp[11:4] = 0;
temp[31:4] = 0; // Zero out stuff to avoid conflicts in the function.
 
process_instruction_specified_shift(temp[11:0]);
process_instruction_specified_shift(temp);
 
// The RAW ALU source does not matter.
o_condition_code = i_instruction[31:28];
/trunk/src/rtl/cpu/zap_localparams.vh
189,13 → 189,24
// CDP
localparam [31:0] CDP = 32'b????_1110_????????_????????_????????;
 
/* COMPRESSED ( Not THUMB! THIS IS NOT COMPATIBLE WITH THE THUMB(R) ISA. ) */
// CLZ
localparam [31:0] CLZ_INSTRUCTION = 32'b????_00010110_1111_????_1111_0001_????;
 
// 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,9 → 105,12
wire [11:0] oc_offset;
 
// Registers.
reg [2:0] state_ff, state_nxt;
reg [3:0] state_ff, state_nxt;
reg [15:0] reglist_ff, reglist_nxt;
 
// Const reg for BLX.
reg [31:0] const_ff, const_nxt;
 
///////////////////////////////////////////////////////////////////////////////
 
// States.
119,6 → 122,13
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;
 
///////////////////////////////////////////////////////////////////////////////
 
129,6 → 139,8
// Next state and output logic.
always @*
begin
const_nxt = const_ff;
 
// Block interrupts by default.
o_irq = 0;
o_fiq = 0;
141,10 → 153,132
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...
if ( id == 3'b100 && i_instruction_valid )
else if ( id == 3'b100 && i_instruction_valid )
begin
// Backup base register.
// MOV DUMMY0, Base
186,7 → 320,7
end
else if ( i_instruction[27:23] == 5'b00010 &&
i_instruction[21:20] == 2'b00 &&
i_instruction[11:4] == 4'b1001 )
i_instruction[11:4] == 4'b1001 && i_instruction_valid ) // SWAP
begin
// Swap
`ifdef LDM_DEBUG
211,7 → 345,7
o_stall_from_decode = 1'd1;
end
else if ( i_instruction[27:23] == 5'd1 &&
i_instruction[7:4] == 4'b1001 )
i_instruction[7:4] == 4'b1001 && i_instruction_valid )
begin
// LMULT
state_nxt = LMULT_BUSY;
222,7 → 356,7
o_instruction_valid = i_instruction_valid;
end
else if ( i_instruction[27:25] == 3'b101 &&
i_instruction[24] ) // BL.
i_instruction[24] && i_instruction_valid ) // BL.
begin
// Move to new state. In that state, we will
// generate a plain branch.
537,6 → 671,7
begin
state_ff <= state_nxt;
reglist_ff <= reglist_nxt;
const_ff <= const_nxt;
end
end
 
547,6 → 682,7
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 -mcpu=arm7tdmi -g
CFLAGS := -c -msoft-float -mfloat-abi=soft -march=armv4t -g
SFLAGS := -mcpu=arm7tdmi -g
LFLAGS := -T
OFLAGS := -O binary
/trunk/src/ts/thumb_test/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_test/Description.txt
0,0 → 1,41
Some thumb tests.
/trunk/src/ts/thumb_test/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_test/main.c
0,0 → 1,4
int main()
{
return 0;
}
/trunk/src/ts/thumb_test/makefile
0,0 → 1,2
# Execute the main Makefile.
include ../../scripts/makefile
/trunk/src/ts/thumb_test/thumb.s
0,0 → 1,25
.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
 

powered by: WebSVN 2.1.0

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