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 |