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

Subversion Repositories zap

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 14 to Rev 15
    Reverse comparison

Rev 14 → Rev 15

/zap/trunk/ZAP/hw/rtl/cpu/zap_core.v
469,7 → 469,59
.o_wb_cyc(o_instr_wb_cyc)
);
 
wire thumb_irq;
wire thumb_fiq;
wire thumb_iabort;
wire [34:0] thumb_instruction;
wire thumb_valid;
wire thumb_und;
wire thumb_force32;
wire [1:0] thumb_bp_state;
wire [31:0] thumb_pc_ff;
wire [31:0] thumb_pc_plus_8_ff;
 
// =========================
// COMPRESSED DECODER STAGE
// =========================
zap_thumb_decoder u_zap_thumb_decoder (
.i_clk (i_clk),
.i_reset (i_reset),
.i_code_stall (1'd0),
.i_clear_from_writeback(clear_from_writeback),
.i_data_stall (
o_data_wb_stb &&
o_data_wb_cyc &&
!i_data_wb_ack
),
.i_clear_from_alu(clear_from_alu),
.i_stall_from_shifter(stall_from_shifter),
.i_stall_from_issue(stall_from_issue),
.i_stall_from_decode(stall_from_decode),
.i_clear_from_decode(clear_from_decode),
 
.i_taken (fifo_bp_state),
.i_instruction (fifo_instruction),
.i_instruction_valid(fifo_valid),
.i_irq (fifo_valid ? irq_sync && !alu_flags_ff[I] : 1'd0), // Pass interrupt only if mask = 0 and instruction exists.
.i_fiq (fifo_valid ? fiq_sync && !alu_flags_ff[F] : 1'd0), // Pass interrupt only if mask = 0 and instruction exists.
.i_iabort (fifo_instr_abort),
.o_iabort (thumb_iabort),
.i_cpsr_ff_t (alu_flags_ff[T]),
.i_pc_ff (fifo_pc_plus_8 - 32'd8),
.i_pc_plus_8_ff (fifo_pc_plus_8),
 
.o_instruction (thumb_instruction),
.o_instruction_valid (thumb_valid),
.o_und (thumb_und),
.o_force32_align(thumb_force32),
.o_pc_ff (thumb_pc_ff),
.o_pc_plus_8_ff (thumb_pc_plus_8_ff),
.o_irq (thumb_irq),
.o_fiq (thumb_fiq),
.o_taken_ff (thumb_bp_state)
);
 
// =========================
// PREDECODE STAGE
// =========================
zap_predecode_main #(
493,22 → 545,26
.i_clear_from_alu (clear_from_alu),
.i_stall_from_shifter (stall_from_shifter),
.i_stall_from_issue (stall_from_issue),
.i_irq (irq_sync),
.i_fiq (fiq_sync),
 
.i_abt (fifo_instr_abort),
.i_pc_plus_8_ff (fifo_pc_plus_8),
.i_pc_ff (fifo_pc_plus_8 - 32'd8),
.i_irq (thumb_irq),
.i_fiq (thumb_fiq),
 
.i_abt (thumb_iabort),
.i_pc_plus_8_ff (thumb_pc_plus_8_ff),
.i_pc_ff (thumb_pc_plus_8_ff - 32'd8),
 
.i_cpu_mode_t (alu_flags_ff[T]),
.i_cpu_mode_f (alu_flags_ff[F]),
.i_cpu_mode_i (alu_flags_ff[I]),
// .i_cpu_mode_f (alu_flags_ff[F]),
// .i_cpu_mode_i (alu_flags_ff[I]),
.i_cpu_mode_mode (alu_flags_ff[`CPSR_MODE]),
 
.i_instruction (fifo_instruction),
.i_instruction_valid (fifo_valid),
.i_taken (fifo_bp_state),
.i_instruction (thumb_instruction),
.i_instruction_valid (thumb_valid),
.i_taken (thumb_bp_state),
 
.i_force32 (thumb_force32),
.i_und (thumb_und),
 
.i_copro_done (copro_done),
.i_pipeline_dav (
predecode_val ||
/zap/trunk/ZAP/hw/rtl/cpu/zap_predecode_coproc.v
32,7 → 32,7
input wire i_reset,
 
// Instruction and valid qualifier.
input wire [31:0] i_instruction,
input wire [34:0] i_instruction,
input wire i_valid,
 
// CPSR Thumb Bit.
63,7 → 63,7
output reg o_fiq,
 
// Instruction and valid qualifier.
output reg [31:0] o_instruction,
output reg [34:0] o_instruction,
output reg o_valid,
 
// We can generate stall if coprocessor is slow. We also have
108,6 → 108,12
 
///////////////////////////////////////////////////////////////////////////////
 
wire c1 = !i_cpsr_ff_t;
wire c2 = i_cpsr_ff_mode != USR;
wire c3 = i_instruction[11:8] == 4'b1111;
wire c4 = i_instruction[34:32] == 3'd0;
wire c5 = c1 & c2 & c3 & c4;
 
// Next state logic.
always @*
begin
124,7 → 130,7
case ( state_ff )
IDLE:
// Activate only if no thumb, not in USER mode and CP15 access is requested.
casez ( (!i_cpsr_ff_t && (i_cpsr_ff_mode != USR) & (i_instruction[11:8] == 4'b1111)) ? i_instruction : 32'd0 )
casez ( (!i_cpsr_ff_t && (i_cpsr_ff_mode != USR) & (i_instruction[11:8] == 4'b1111) & (i_instruction[34:32] == 3'd0)) ? i_instruction[31:0] : 35'd0 )
MRC, MCR, LDC, STC, CDP:
begin
// Send ANDNV R0, R0, R0 instruction.
/zap/trunk/ZAP/hw/rtl/cpu/zap_predecode_main.v
58,6 → 58,8
 
// Branch state.
input wire [1:0] i_taken,
input wire i_force32,
input wire i_und,
 
// Clear and stall signals. From high to low priority.
input wire i_code_stall,
84,12 → 86,10
 
// CPU mode. Taken from CPSR in the ALU.
input wire i_cpu_mode_t, // T mode.
i_cpu_mode_i, // I mask.
i_cpu_mode_f, // F mask.
input wire [4:0] i_cpu_mode_mode, // CPU mode.
 
// Instruction input.
input wire [31:0] i_instruction,
input wire [34:0] i_instruction,
input wire i_instruction_valid,
 
// Instruction output
139,11 → 139,6
 
///////////////////////////////////////////////////////////////////////////////
 
wire o_comp_und_nxt;
wire [3:0] o_condition_code_nxt;
wire o_irq_nxt;
wire o_fiq_nxt;
wire o_abt_nxt;
wire [35:0] o_instruction_nxt;
wire o_instruction_valid_nxt;
 
154,23 → 149,20
 
wire [34:0] arm_instruction;
wire arm_instruction_valid;
wire o_force32align_nxt;
 
wire cp_stall;
wire [31:0] cp_instruction;
wire [34:0] cp_instruction;
wire cp_instruction_valid;
wire cp_irq;
wire cp_fiq;
 
wire o_irq_nxt;
wire o_fiq_nxt;
 
reg [1:0] taken_nxt;
 
///////////////////////////////////////////////////////////////////////////////
 
// Abort
assign o_abt_nxt = i_abt;
 
///////////////////////////////////////////////////////////////////////////////
 
// Flop the outputs to break the pipeline at this point.
always @ (posedge i_clk)
begin
206,13 → 198,13
else
begin
// Do not pass IRQ and FIQ if mask is 1.
o_irq_ff <= o_irq_nxt & !i_cpu_mode_i;
o_fiq_ff <= o_fiq_nxt & !i_cpu_mode_f;
o_abt_ff <= o_abt_nxt;
o_und_ff <= o_comp_und_nxt && i_instruction_valid;
o_irq_ff <= i_irq;
o_fiq_ff <= i_fiq;
o_abt_ff <= i_abt;
o_und_ff <= i_und && i_instruction_valid;
o_pc_plus_8_ff <= i_pc_plus_8_ff;
o_pc_ff <= i_pc_ff;
o_force32align_ff <= o_force32align_nxt;
o_force32align_ff <= i_force32;
o_taken_ff <= taken_nxt;
o_instruction_ff <= o_instruction_nxt;
o_instruction_valid_ff <= o_instruction_valid_nxt;
238,10 → 230,6
 
///////////////////////////////////////////////////////////////////////////////
 
generate
begin: gblk1
if ( COPROCESSOR_INTERFACE_ENABLE ) begin: cm_en
 
// This unit handles coprocessor stuff.
zap_predecode_coproc
#(
252,8 → 240,8
// Inputs from outside world.
.i_clk(i_clk),
.i_reset(i_reset),
.i_irq(i_instruction_valid ? i_irq : 1'd0),
.i_fiq(i_instruction_valid ? i_fiq : 1'd0),
.i_irq(i_irq),
.i_fiq(i_fiq),
.i_instruction(i_instruction_valid ? i_instruction : 32'd0),
.i_valid(i_instruction_valid),
.i_cpsr_ff_t(i_cpu_mode_t),
287,67 → 275,15
.o_copro_word_ff(o_copro_word_ff)
);
 
end
else // Else generate block.
begin: cm_dis
 
assign cp_instruction = i_instruction_valid ? i_instruction : 32'd0;
assign cp_instruction_valid = i_instruction_valid;
assign cp_irq = i_instruction_valid ? i_irq : 1'd0;
assign cp_fiq = i_instruction_valid ? i_fiq : 1'd0;
assign cp_stall = 1'd0;
assign o_copro_dav_ff = 1'd0;
assign o_copro_word_ff = 32'd0;
 
end
 
end
endgenerate
 
///////////////////////////////////////////////////////////////////////////////
 
generate
begin: gblk2
if ( COMPRESSED_EN )
begin: cmp_en
assign arm_instruction = cp_instruction;
assign arm_instruction_valid = cp_instruction_valid;
assign arm_irq = cp_irq;
assign arm_fiq = cp_fiq;
 
// Implements a custom 16-bit compressed instruction set.
zap_predecode_compress
u_zap_predecode_compress
(
.i_clk(i_clk),
.i_reset(i_reset),
.i_irq(cp_irq),
.i_fiq(cp_fiq),
.i_instruction(cp_instruction),
.i_instruction_valid(cp_instruction_valid),
.i_cpsr_ff_t(i_cpu_mode_t),
 
.i_code_stall(i_code_stall),
.o_instruction(arm_instruction),
.o_instruction_valid(arm_instruction_valid),
.o_irq(arm_irq),
.o_fiq(arm_fiq),
.o_force32_align(o_force32align_nxt),
.o_und(o_comp_und_nxt)
);
 
end
else
begin: cmp_dis
 
assign arm_instruction = cp_instruction;
assign arm_instruction_valid = cp_instruction_valid;
assign arm_irq = cp_irq;
assign arm_fiq = cp_fiq;
assign o_force32align_nxt = 1'd0;
assign o_comp_und_nxt = 1'd0;
 
end
end
endgenerate
 
///////////////////////////////////////////////////////////////////////////////
 
always @*
/zap/trunk/ZAP/hw/rtl/cpu/zap_thumb_decoder.v
0,0 → 1,173
// ----------------------------------------------------------------------------
// The ZAP Project
// (C)2016-2017, Revanth Kamaraj.
// ----------------------------------------------------------------------------
// Filename : zap_thumb_decoder.v
// HDL : Verilog-2001
// Module : zap_thumb_decoder
// Author : Revanth Kamaraj
// License : GPL v2
// ----------------------------------------------------------------------------
// ABSTRACT
// --------
// Implements a 16-bit instruction decoder. The 16-bit instruction set is
// not logically organized so as to save on encoding and thus the functions
// seem a bit complex.
//
// ----------------------------------------------------------------------------
// INFORMATION
// ------------
// Reset method : Synchronous active high reset
// Clock : Core clock
// Depends : --
// ----------------------------------------------------------------------------
 
 
`default_nettype none
 
module zap_thumb_decoder (
// Clock and reset.
input wire i_clk,
input wire i_reset,
 
// Code stall.
input wire i_code_stall,
input wire i_clear_from_writeback,
input wire i_data_stall,
input wire i_clear_from_alu,
input wire i_stall_from_shifter,
input wire i_stall_from_issue,
input wire i_stall_from_decode,
input wire i_clear_from_decode,
 
// Predictor status.
input wire [1:0] i_taken,
 
// Input from I-cache.
// Instruction and valid qualifier.
input wire [31:0] i_instruction,
input wire i_instruction_valid,
 
// Interrupts. Active high level sensitive signals.
input wire i_irq,
input wire i_fiq,
 
// Aborts.
input wire i_iabort,
output reg o_iabort,
 
// Ensure compressed mode is active (T bit).
input wire i_cpsr_ff_t,
 
// Program counter.
input wire [31:0] i_pc_ff,
input wire [31:0] i_pc_plus_8_ff,
 
//
// Outputs to the ARM decoder.
//
// Instruction, valid, undefined by this decoder and force 32-bit
// align signals (requires memory to keep lower 2 bits as 00).
output reg [34:0] o_instruction,
output reg o_instruction_valid,
output reg o_und,
output reg o_force32_align,
 
// PCs.
output reg [31:0] o_pc_ff,
output reg [31:0] o_pc_plus_8_ff,
 
// Interrupt status output.
output reg o_irq,
output reg o_fiq,
 
// Taken
output reg [1:0] o_taken_ff
);
 
`include "zap_defines.vh"
`include "zap_localparams.vh"
`include "zap_functions.vh"
 
wire [34:0] instruction_nxt;
wire instruction_valid_nxt;
wire und_nxt;
wire force32_nxt;
wire irq_nxt;
wire fiq_nxt;
reg [1:0] taken_nxt;
 
zap_predecode_compress u_zap_predecode_compress (
.i_clk(i_clk),
.i_reset(i_reset),
.i_code_stall(i_code_stall),
.i_instruction(i_instruction),
.i_instruction_valid(i_instruction_valid),
.i_irq(i_irq),
.i_fiq(i_fiq),
.i_cpsr_ff_t(i_cpsr_ff_t),
.o_instruction(instruction_nxt),
.o_instruction_valid(instruction_valid_nxt),
.o_und(und_nxt),
.o_force32_align(force32_nxt),
.o_irq(irq_nxt),
.o_fiq(fiq_nxt)
);
 
always @ (posedge i_clk)
begin
if ( i_reset )
begin
o_instruction_valid <= 1'd0;
o_irq <= 0;
o_fiq <= 0;
o_und <= 0;
o_iabort <= 0;
end
else if ( i_clear_from_writeback )
begin
o_instruction_valid <= 1'd0;
o_irq <= 0;
o_fiq <= 0;
o_und <= 0;
o_iabort <= 0;
end
else if ( i_data_stall )
begin
end
else if ( i_clear_from_alu )
begin
o_instruction_valid <= 1'd0;
o_irq <= 0;
o_fiq <= 0;
o_und <= 0;
o_iabort <= 0;
end
else if ( i_stall_from_shifter ) begin end
else if ( i_stall_from_issue ) begin end
else if ( i_stall_from_decode ) begin end
else if ( i_clear_from_decode )
begin
o_instruction_valid <= 1'd0;
o_irq <= 0;
o_fiq <= 0;
o_und <= 0;
o_iabort <= 0;
end
else // BUG FIX.
begin
o_iabort <= i_iabort;
o_instruction_valid <= instruction_valid_nxt;
o_instruction <= instruction_nxt;
o_und <= und_nxt;
o_force32_align <= force32_nxt;
o_pc_ff <= i_pc_ff;
o_pc_plus_8_ff <= i_pc_plus_8_ff;
o_irq <= irq_nxt;
o_fiq <= fiq_nxt;
o_taken_ff <= i_taken;
end
end
 
endmodule
/zap/trunk/ZAP/hw/rtl/tlb/zap_tlb_fsm.v
96,9 → 96,10
localparam FETCH_L1_DESC = 1; /* Fetch L1 descriptor */
localparam FETCH_L2_DESC = 2; /* Fetch L2 descriptor */
localparam REFRESH_CYCLE = 3; /* Refresh TLBs and cache */
localparam FETCH_L1_DESC_0 = 4;
localparam FETCH_L2_DESC_0 = 5;
localparam NUMBER_OF_STATES = 6;
 
localparam NUMBER_OF_STATES = 4;
 
// ----------------------------------------------------------------------------
 
reg [3:0] dff_ff, dff_nxt; /* Scratchpad register */
129,6 → 130,8
 
assign o_unused_ok = 0 || i_baddr[13:0];
 
reg [31:0] dff, dnxt;
 
/* Combinational logic */
always @*
begin: blk1
155,6 → 158,8
dff_nxt = dff_ff;
state_nxt = state_ff;
 
dnxt = dff;
 
case ( state_ff )
IDLE:
begin
179,7 → 184,7
tsk_prpr_wb_rd({i_baddr[`VA__TRANSLATION_BASE],
i_address[`VA__TABLE_INDEX], 2'd0});
 
state_nxt = FETCH_L1_DESC;
state_nxt = FETCH_L1_DESC_0;
end
else if ( i_fsr[3:0] != 4'b0000 ) /* Access Violation. */
begin
203,6 → 208,17
end
end
 
FETCH_L1_DESC_0:
begin
o_busy = 1;
if ( i_wb_ack )
begin
dnxt = i_wb_dat;
state_nxt = FETCH_L1_DESC;
end
else tsk_hold_wb_access;
end
 
FETCH_L1_DESC:
begin
/*
214,13 → 230,13
 
o_busy = 1'd1;
 
if ( i_wb_ack ) /* Wait for ACK. */
if ( 1 )
begin
$display($time, "%m :: ACK received. Read data is %x", i_wb_dat);
`ifdef TLB_DEBUG
$stop;
`endif
case ( i_wb_dat[`ID] )
case ( dff[`ID] )
 
SECTION_ID:
begin
231,7 → 247,7
*/
o_setlb_wen = 1'd1;
o_setlb_wdata = {i_address[`VA__SECTION_TAG],
i_wb_dat};
dff};
state_nxt = REFRESH_CYCLE;
 
$display($time, "%m :: It is a section ID. Writing to section TLB as %x. Moving to refresh cycle...", o_setlb_wdata);
248,10 → 264,10
* reload the TLB, it would be useful. Anyway,
* we need to initiate another access.
*/
dff_nxt = i_wb_dat[`L1_PAGE__DAC_SEL];
state_nxt = FETCH_L2_DESC;
dff_nxt = dff[`L1_PAGE__DAC_SEL];
state_nxt = FETCH_L2_DESC_0;
 
tsk_prpr_wb_rd({i_wb_dat[`L1_PAGE__PTBR],
tsk_prpr_wb_rd({dff[`L1_PAGE__PTBR],
i_address[`VA__L2_TABLE_INDEX], 2'd0});
 
$display($time, "%m :: Page ID.");
263,7 → 279,7
default: /* Generate section translation fault. Fault Class II */
begin
o_fsr = FSR_SECTION_TRANSLATION_FAULT;
o_fsr = {i_wb_dat[`L1_SECTION__DAC_SEL], o_fsr[3:0]};
o_fsr = {dff[`L1_SECTION__DAC_SEL], o_fsr[3:0]};
o_far = i_address;
o_fault = 1'd1;
o_busy = 1'd0;
280,21 → 296,31
else tsk_hold_wb_access;
end
 
FETCH_L2_DESC_0:
begin
o_busy = 1;
if ( i_wb_ack )
begin
dnxt = i_wb_dat;
state_nxt = FETCH_L2_DESC;
end else tsk_hold_wb_access;
end
 
FETCH_L2_DESC:
begin
o_busy = 1'd1;
 
if ( i_wb_ack )
if ( 1 ) //i_wb_ack )
begin
case ( i_wb_dat[`ID] )
case ( dff[`ID] )
SPAGE_ID:
begin
/* Update TLB */
o_sptlb_wen = 1'd1;
 
o_sptlb_wdata = { i_wb_dat[`VA__SPAGE_TAG],
o_sptlb_wdata = { dff[`VA__SPAGE_TAG],
dff_ff[3:0], /* DAC Selector from L1 */
i_wb_dat };
dff };
 
state_nxt = REFRESH_CYCLE;
end
305,8 → 331,8
o_lptlb_wen = 1'd1;
 
/* DAC is inserted in between to save bits */
o_lptlb_wdata = {i_wb_dat[`VA__LPAGE_TAG],
i_wb_dat};
o_lptlb_wdata = {dff[`VA__LPAGE_TAG],
dff};
o_lptlb_wdata[`LPAGE_TLB__DAC_SEL] = dff_ff[3:0];
 
state_nxt = REFRESH_CYCLE;
317,7 → 343,7
o_busy = 1'd0;
o_fault = 1'd1;
o_fsr = FSR_PAGE_TRANSLATION_FAULT;
o_fsr = {i_wb_dat[`L1_PAGE__DAC_SEL], o_fsr[3:0]};
o_fsr = {dff[`L1_PAGE__DAC_SEL], o_fsr[3:0]};
o_far = i_address;
state_nxt = IDLE;
end
361,6 → 387,7
wb_adr_ff <= wb_adr_nxt;
dff_ff <= dff_nxt;
wb_sel_ff <= wb_sel_nxt;
dff <= dnxt;
end
end
 
/zap/trunk/ZAP/hw/rtl/rtl_files.list
26,6 → 26,7
${ZAP_HOME}/hw/rtl/cache/zap_cache_tag_ram.v
${ZAP_HOME}/hw/rtl/cache/zap_cache.v
${ZAP_HOME}/hw/rtl/wb/zap_wb_merger.v
${ZAP_HOME}/hw/rtl/cpu/zap_thumb_decoder.v
 
+libdir+${ZAP_HOME}/hw/rtl/lib/
+incdir+${ZAP_HOME}/hw/rtl/inc

powered by: WebSVN 2.1.0

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