URL
https://opencores.org/ocsvn/zap/zap/trunk
Subversion Repositories zap
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 57 to Rev 58
- ↔ Reverse comparison
Rev 57 → Rev 58
/zap/trunk/src/ts/uart/irq_handler.c
File deleted
/zap/trunk/src/ts/uart/uart.ld
File deleted
/zap/trunk/src/ts/uart/uart.c
File deleted
/zap/trunk/src/ts/uart/uart.s
File deleted
/zap/trunk/src/ts/uart/makefile
File deleted
/zap/trunk/src/ts/uart/uart.h
File deleted
/zap/trunk/src/ts/uart/Description.txt
File deleted
/zap/trunk/src/ts/uart/Config.cfg
File deleted
/zap/trunk/src/ts/uart/main.c
File deleted
/zap/trunk/src/ts/makefile
File deleted
/zap/trunk/src/ts/thumb_test/makefile
File deleted
/zap/trunk/src/ts/thumb_test/thumb.s
File deleted
/zap/trunk/src/ts/thumb_test/Description.txt
File deleted
/zap/trunk/src/ts/thumb_test/linker.ld
File deleted
/zap/trunk/src/ts/thumb_test/Config.cfg
File deleted
/zap/trunk/src/ts/thumb_test/main.c
File deleted
/zap/trunk/src/ts/arm_test/Config.cfg
File deleted
/zap/trunk/src/ts/arm_test/arm_test.ld
File deleted
/zap/trunk/src/ts/arm_test/makefile
File deleted
/zap/trunk/src/ts/arm_test/arm_test.c
File deleted
/zap/trunk/src/ts/arm_test/arm_test.s
File deleted
/zap/trunk/src/ts/arm_test/Description.txt
File deleted
/zap/trunk/src/ts/factorial/makefile
File deleted
/zap/trunk/src/ts/factorial/Description.txt
File deleted
/zap/trunk/src/ts/factorial/factorial.ld
File deleted
/zap/trunk/src/ts/factorial/Config.cfg
File deleted
/zap/trunk/src/ts/factorial/factorial.c
File deleted
/zap/trunk/src/ts/factorial/factorial.s
File deleted
/zap/trunk/src/scripts/uart_input.bash
File deleted
/zap/trunk/src/scripts/run_sim.pl
File deleted
/zap/trunk/src/scripts/bin2vlog.pl
File deleted
/zap/trunk/src/scripts/makefile
File deleted
/zap/trunk/src/scripts/Config.cfg_template
File deleted
/zap/trunk/src/testbench/zap_tb.v
File deleted
/zap/trunk/src/testbench/ram.v
File deleted
/zap/trunk/src/testbench/timer.v
File deleted
/zap/trunk/src/testbench/vic.v
File deleted
/zap/trunk/src/testbench/uart_tx_dumper.v
File deleted
/zap/trunk/src/testbench/uart_rx_logger.v
File deleted
/zap/trunk/src/testbench/chip_top.v
File deleted
/zap/trunk/src/testbench/External_IP/uart16550/doc/src/UART_spec.doc
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
zap/trunk/src/testbench/External_IP/uart16550/doc/src/UART_spec.doc
Property changes :
Deleted: svn:mime-type
## -1 +0,0 ##
-application/octet-stream
\ No newline at end of property
Index: zap/trunk/src/testbench/External_IP/uart16550/doc/UART_spec.pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: zap/trunk/src/testbench/External_IP/uart16550/doc/UART_spec.pdf
===================================================================
--- zap/trunk/src/testbench/External_IP/uart16550/doc/UART_spec.pdf (revision 57)
+++ zap/trunk/src/testbench/External_IP/uart16550/doc/UART_spec.pdf (nonexistent)
zap/trunk/src/testbench/External_IP/uart16550/doc/UART_spec.pdf
Property changes :
Deleted: svn:mime-type
## -1 +0,0 ##
-application/octet-stream
\ No newline at end of property
Index: zap/trunk/src/rtl/cpu/zap_shifter_multiply.v
===================================================================
--- zap/trunk/src/rtl/cpu/zap_shifter_multiply.v (revision 57)
+++ zap/trunk/src/rtl/cpu/zap_shifter_multiply.v (nonexistent)
@@ -1,230 +0,0 @@
-// -----------------------------------------------------------------------------
-// -- --
-// -- (C) 2016-2018 Revanth Kamaraj. --
-// -- --
-// -- --------------------------------------------------------------------------
-// -- --
-// -- This program is free software; you can redistribute it and/or --
-// -- modify it under the terms of the GNU General Public License --
-// -- as published by the Free Software Foundation; either version 2 --
-// -- of the License, or (at your option) any later version. --
-// -- --
-// -- This program 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 General Public License for more details. --
-// -- --
-// -- You should have received a copy of the GNU General Public License --
-// -- along with this program; if not, write to the Free Software --
-// -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA --
-// -- 02110-1301, USA. --
-// -- --
-// -----------------------------------------------------------------------------
-// -- --
-// -- This unit handles 32x32=32/64 multiplication using an FSM using --
-// -- a 17x17 signed array multiplier. --
-// -- --
-// -----------------------------------------------------------------------------
-
-
-`default_nettype none
-
-module zap_shifter_multiply
-#(
- parameter PHY_REGS = 46,
- parameter ALU_OPS = 32
-)
-(
- input wire i_clk,
- input wire i_reset,
-
- // Clear and stall signals.
- input wire i_clear_from_writeback,
- input wire i_data_stall,
- input wire i_clear_from_alu,
-
- // ALU operation to perform. Activate if this is multiplication.
- input wire [$clog2(ALU_OPS)-1:0] i_alu_operation_ff,
-
- // This is not used.
- input wire i_cc_satisfied,
-
- // rm.rs + {rh,rn}. For non accumulate versions, rn = 0x0 and rh = 0x0.
- input wire [31:0] i_rm,
- input wire [31:0] i_rn,
- input wire [31:0] i_rh,
- input wire [31:0] i_rs,
-
- //
- // Outputs.
- //
-
- output reg [31:0] o_rd, // Result.
- output reg o_busy, // Unit busy.
- output reg o_nozero // Don't set zero flag.
-);
-
-`include "zap_defines.vh"
-`include "zap_localparams.vh"
-`include "zap_functions.vh"
-
-///////////////////////////////////////////////////////////////////////////////
-
-// States
-localparam IDLE = 0;
-localparam S1 = 1;
-localparam S2 = 2;
-localparam S3 = 3;
-localparam S4 = 4;
-localparam S5 = 5;
-localparam NUMBER_OF_STATES = 6;
-
-///////////////////////////////////////////////////////////////////////////////
-
-reg [31:0] buffer_nxt, buffer_ff;
-wire higher = i_alu_operation_ff[0];
-wire sign = (i_alu_operation_ff == SMLALL || i_alu_operation_ff == SMLALH);
-wire signed [16:0] a;
-wire signed [16:0] b;
-wire signed [16:0] c;
-wire signed [16:0] d;
-reg signed [63:0] x_ff, x_nxt;
-reg signed [16:0] in1;
-reg signed [16:0] in2;
-wire signed [63:0] prod;
-
-// State variable.
-reg [$clog2(NUMBER_OF_STATES)-1:0] state_ff, state_nxt;
-
-///////////////////////////////////////////////////////////////////////////////
-
-assign prod = in1 * in2; // 17x17 hard macro model.
-
-///////////////////////////////////////////////////////////////////////////////
-
-assign a = sign ? {i_rm[31], i_rm[31:16]} : {1'd0, i_rm[31:16]};
-assign b = sign ? {i_rs[31], i_rs[31:16]} : {1'd0, i_rs[31:16]};
-assign c = {1'd0, i_rm[15:0]};
-assign d = {1'd0, i_rs[15:0]};
-
-///////////////////////////////////////////////////////////////////////////////
-
-always @*
-begin
- buffer_nxt = buffer_ff;
- o_nozero = 1'd0;
- o_busy = 1'd1;
- o_rd = 32'd0;
- state_nxt = state_ff;
- x_nxt = x_ff;
- in1 = 0;
- in2 = 0;
-
- case ( state_ff )
- IDLE:
- begin
- o_busy = 1'd0;
- x_nxt = 32'd0;
-
- // If we have the go signal.
- if ( i_cc_satisfied && (i_alu_operation_ff == UMLALL ||
- i_alu_operation_ff == UMLALH ||
- i_alu_operation_ff == SMLALL ||
- i_alu_operation_ff == SMLALH) )
- begin
- o_busy = 1'd1;
- state_nxt = S1;
- end
- end
- S1:
- begin
- in1 = c;
- in2 = d;
- x_nxt = x_ff + (prod << 0);
- state_nxt = S2;
- end
- S2:
- begin
- in1 = b;
- in2 = c;
- state_nxt = S3;
- x_nxt = x_ff + (prod << 16);
- end
- S3:
- begin
- in1 = a;
- in2 = d;
- state_nxt = S4;
- x_nxt = x_ff + (prod << 16);
- end
- S4:
- begin
- in1 = a;
- in2 = b;
- state_nxt = S5;
- x_nxt = x_ff + (prod << 32);
- end
- S5:
- begin
- state_nxt = IDLE;
- x_nxt = x_ff + {i_rh, i_rn};
- o_rd = higher ? x_nxt[63:32] : x_nxt[31:0];
-
- if ( !higher )
- begin
- buffer_nxt = x_nxt[31:0];
- end
-
- o_busy = 1'd0;
-
- if ( higher && (buffer_ff != 32'd0) )
- begin
- o_nozero = 1'd1;
- end
- end
- endcase
-end
-
-///////////////////////////////////////////////////////////////////////////////
-
-always @ (posedge i_clk)
-begin
- if ( i_reset )
- begin
- x_ff <= 63'd0;
- state_ff <= IDLE;
- buffer_ff<= 32'd0;
- end
- else if ( i_clear_from_writeback )
- begin
- x_ff <= 63'd0;
- state_ff <= IDLE;
- buffer_ff <= 32'd0;
- end
- else if ( i_data_stall )
- begin
- // Hold values
- end
- else if ( i_clear_from_alu )
- begin
- x_ff <= 63'd0;
- state_ff <= IDLE;
- buffer_ff <= 32'd0;
- end
- else
- begin
- x_ff <= x_nxt;
- state_ff <= state_nxt;
- buffer_ff <= buffer_nxt;
- end
-end
-
-///////////////////////////////////////////////////////////////////////////////
-
-endmodule // zap_multiply.v
-
-`default_nettype wire
-
-// ----------------------------------------------------------------------------
-// EOF
-// ----------------------------------------------------------------------------
Index: zap/trunk/src/rtl/cpu/zap_cache.v
===================================================================
--- zap/trunk/src/rtl/cpu/zap_cache.v (revision 57)
+++ zap/trunk/src/rtl/cpu/zap_cache.v (nonexistent)
@@ -1,341 +0,0 @@
-// -----------------------------------------------------------------------------
-// -- --
-// -- (C) 2016-2018 Revanth Kamaraj. --
-// -- --
-// -- --------------------------------------------------------------------------
-// -- --
-// -- This program is free software; you can redistribute it and/or --
-// -- modify it under the terms of the GNU General Public License --
-// -- as published by the Free Software Foundation; either version 2 --
-// -- of the License, or (at your option) any later version. --
-// -- --
-// -- This program 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 General Public License for more details. --
-// -- --
-// -- You should have received a copy of the GNU General Public License --
-// -- along with this program; if not, write to the Free Software --
-// -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA --
-// -- 02110-1301, USA. --
-// -- --
-// -----------------------------------------------------------------------------
-// -- --
-// -- This is the top level cache module that contains the MMU and cache. --
-// -- This will be instantiated twice in the processor TOP, once for --
-// -- instruction and the other for data. --
-// -- --
-// -----------------------------------------------------------------------------
-
-`default_nettype none
-
-module zap_cache #(
-
-parameter [31:0] CACHE_SIZE = 1024,
-parameter [31:0] SPAGE_TLB_ENTRIES = 8,
-parameter [31:0] LPAGE_TLB_ENTRIES = 8,
-parameter [31:0] SECTION_TLB_ENTRIES = 8
-
-) /* Port List */ (
-
-// Clock and reset.
-input wire i_clk,
-input wire i_reset,
-
-// Address from processor.
-input wire [31:0] i_address,
-input wire [31:0] i_address_nxt,
-
-// Other control signals from/to processor.
-input wire i_rd,
-input wire i_wr,
-input wire [3:0] i_ben,
-input wire [31:0] i_dat,
-output wire [31:0] o_dat,
-output wire o_ack,
-output wire o_err,
-output wire [7:0] o_fsr,
-output wire [31:0] o_far,
-
-// MMU controls from/to processor.
-input wire i_mmu_en,
-input wire i_cache_en,
-input wire i_cache_inv_req,
-input wire i_cache_clean_req,
-output wire o_cache_inv_done,
-output wire o_cache_clean_done,
-input wire [31:0] i_cpsr,
-input wire [1:0] i_sr,
-input wire [31:0] i_baddr,
-input wire [31:0] i_dac_reg,
-input wire i_tlb_inv,
-
-// Wishbone. Signals from all 4 modules are ORed.
-output reg o_wb_stb, o_wb_stb_nxt,
-output reg o_wb_cyc, o_wb_cyc_nxt,
-output reg o_wb_wen, o_wb_wen_nxt,
-output reg [3:0] o_wb_sel, o_wb_sel_nxt,
-output reg [31:0] o_wb_dat, o_wb_dat_nxt,
-output reg [31:0] o_wb_adr, o_wb_adr_nxt,
-output reg [2:0] o_wb_cti, o_wb_cti_nxt,
-input wire [31:0] i_wb_dat,
-input wire i_wb_ack
-
-);
-
-`include "zap_defines.vh"
-`include "zap_localparams.vh"
-`include "zap_functions.vh"
-
-localparam S0=0;
-localparam S1=1;
-localparam S2=2;
-
-wire [2:0] wb_stb;
-wire [2:0] wb_cyc;
-wire [2:0] wb_wen;
-wire [3:0] wb_sel [2:0];
-wire [31:0] wb_dat [2:0];
-wire [31:0] wb_adr [2:0];
-wire [2:0] wb_cti [2:0];
-wire [31:0] wb_dat0_cachefsm, wb_dat1_tagram, wb_dat2_tlb;
-wire [31:0] tlb_phy_addr;
-wire [7:0] tlb_fsr;
-wire [31:0] tlb_far;
-wire tlb_fault;
-wire tlb_cacheable;
-wire tlb_busy;
-wire [127:0] tr_cache_line;
-wire [127:0] cf_cache_line;
-wire [15:0] cf_cache_line_ben;
-wire cf_cache_tag_wr_en;
-wire [`CACHE_TAG_WDT-1:0] tr_cache_tag, cf_cache_tag;
-wire tr_cache_tag_valid;
-wire tr_cache_tag_dirty, cf_cache_tag_dirty;
-wire cf_cache_clean_req, cf_cache_inv_req;
-wire tr_cache_inv_done, tr_cache_clean_done;
-reg [2:0] wb_ack;
-reg [1:0] state_ff, state_nxt;
-
-// Data from each Wishbone master.
-assign wb_dat0_cachefsm = wb_dat[0];
-assign wb_dat1_tagram = wb_dat[1];
-assign wb_dat2_tlb = wb_dat[2];
-
-// Bit 2 of Wishbone CTI is always on all CPU supported modes.
-assign wb_cti[2] = 0;
-
-// Basic cache FSM - serves as Master 0.
-zap_cache_fsm #(.CACHE_SIZE(CACHE_SIZE)) u_zap_cache_fsm (
- .i_clk (i_clk),
- .i_reset (i_reset),
- .i_address (i_address),
- .i_rd (i_rd),
- .i_wr (i_wr),
- .i_din (i_dat),
- .i_ben (i_ben),
- .o_dat (o_dat),
- .o_ack (o_ack),
- .o_err (o_err),
- .o_fsr (o_fsr),
- .o_far (o_far),
- .i_cache_en (i_cache_en),
- .i_cache_inv (i_cache_inv_req),
- .i_cache_clean (i_cache_clean_req),
- .o_cache_inv_done (o_cache_inv_done),
- .o_cache_clean_done (o_cache_clean_done),
- .i_cache_line (tr_cache_line),
- .i_cache_tag_dirty (tr_cache_tag_dirty),
- .i_cache_tag (tr_cache_tag),
- .i_cache_tag_valid (tr_cache_tag_valid),
- .o_cache_tag (cf_cache_tag),
- .o_cache_tag_dirty (cf_cache_tag_dirty),
- .o_cache_tag_wr_en (cf_cache_tag_wr_en),
- .o_cache_line (cf_cache_line),
- .o_cache_line_ben (cf_cache_line_ben),
- .o_cache_clean_req (cf_cache_clean_req),
- .i_cache_clean_done (tr_cache_clean_done),
- .o_cache_inv_req (cf_cache_inv_req),
- .i_cache_inv_done (tr_cache_inv_done),
- .i_phy_addr (tlb_phy_addr),
- .i_fsr (tlb_fsr),
- .i_far (tlb_far),
- .i_fault (tlb_fault),
- .i_cacheable (tlb_cacheable),
- .i_busy (tlb_busy),
- .o_wb_cyc_ff (),
- .o_wb_cyc_nxt (wb_cyc[0]),
- .o_wb_stb_ff (),
- .o_wb_stb_nxt (wb_stb[0]),
- .o_wb_adr_ff (),
- .o_wb_adr_nxt (wb_adr[0]),
- .o_wb_dat_ff (),
- .o_wb_dat_nxt (wb_dat[0]),
- .o_wb_sel_ff (),
- .o_wb_sel_nxt (wb_sel[0]),
- .o_wb_wen_ff (),
- .o_wb_wen_nxt (wb_wen[0]),
- .o_wb_cti_ff (),
- .o_wb_cti_nxt (wb_cti[0]),
- .i_wb_dat (i_wb_dat),
- .i_wb_ack (wb_ack[0])
-);
-
-// Cache Tag RAM - As a master - this performs cache clean - Master 1.
-zap_cache_tag_ram #(.CACHE_SIZE(CACHE_SIZE)) u_zap_cache_tag_ram (
- .i_clk (i_clk),
- .i_reset (i_reset),
- .i_address_nxt (i_address_nxt),
- .i_address (i_address),
- .i_cache_en (i_cache_en),
- .i_cache_line (cf_cache_line),
- .o_cache_line (tr_cache_line),
- .i_cache_line_ben (cf_cache_line_ben),
- .i_cache_tag_wr_en (cf_cache_tag_wr_en),
- .i_cache_tag (cf_cache_tag),
- .i_cache_tag_dirty (cf_cache_tag_dirty),
- .o_cache_tag (tr_cache_tag),
- .o_cache_tag_valid (tr_cache_tag_valid),
- .o_cache_tag_dirty (tr_cache_tag_dirty),
- .i_cache_inv_req (cf_cache_inv_req),
- .o_cache_inv_done (tr_cache_inv_done),
- .i_cache_clean_req (cf_cache_clean_req),
- .o_cache_clean_done (tr_cache_clean_done),
- .o_wb_cyc_ff (),
- .o_wb_cyc_nxt (wb_cyc[1]),
- .o_wb_stb_ff (),
- .o_wb_stb_nxt (wb_stb[1]),
- .o_wb_adr_ff (),
- .o_wb_adr_nxt (wb_adr[1]),
- .o_wb_dat_ff (),
- .o_wb_dat_nxt (wb_dat[1]),
- .o_wb_sel_ff (),
- .o_wb_sel_nxt (wb_sel[1]),
- .o_wb_wen_ff (),
- .o_wb_wen_nxt (wb_wen[1]),
- .o_wb_cti_ff (),
- .o_wb_cti_nxt (wb_cti[1]),
- .i_wb_dat (i_wb_dat),
- .i_wb_ack (wb_ack[1])
-);
-
-// ZAP TLB control module. Includes TLB RAM inside.
-zap_tlb #(
- .LPAGE_TLB_ENTRIES (LPAGE_TLB_ENTRIES),
- .SPAGE_TLB_ENTRIES (SPAGE_TLB_ENTRIES),
- .SECTION_TLB_ENTRIES (SECTION_TLB_ENTRIES))
-u_zap_tlb (
- .i_clk (i_clk),
- .i_reset (i_reset),
- .i_address (i_address),
- .i_address_nxt (i_address_nxt),
- .i_rd (i_rd),
- .i_wr (i_wr),
- .i_cpsr (i_cpsr),
- .i_sr (i_sr),
- .i_dac_reg (i_dac_reg),
- .i_baddr (i_baddr),
- .i_mmu_en (i_mmu_en),
- .i_inv (i_tlb_inv),
- .o_phy_addr (tlb_phy_addr),
- .o_fsr (tlb_fsr),
- .o_far (tlb_far),
- .o_fault (tlb_fault),
- .o_cacheable (tlb_cacheable),
- .o_busy (tlb_busy),
- .o_wb_stb_nxt (wb_stb[2]),
- .o_wb_cyc_nxt (wb_cyc[2]),
- .o_wb_adr_nxt (wb_adr[2]),
- .o_wb_wen_nxt (wb_wen[2]),
- .o_wb_sel_nxt (wb_sel[2]),
- .o_wb_dat_nxt (wb_dat[2]),
- .i_wb_dat (i_wb_dat),
- .i_wb_ack (wb_ack[2])
-);
-
-// Sequential Block
-always @ ( posedge i_clk )
-begin
- if ( i_reset )
- begin
- state_ff <= S0;
- o_wb_stb <= 1'd0;
- o_wb_cyc <= 1'd0;
- o_wb_adr <= 32'd0;
- o_wb_cti <= CTI_CLASSIC;
- o_wb_sel <= 4'd0;
- o_wb_dat <= 32'd0;
- o_wb_wen <= 1'd0;
- end
- else
- begin
- state_ff <= state_nxt;
- o_wb_stb <= o_wb_stb_nxt;
- o_wb_cyc <= o_wb_cyc_nxt;
- o_wb_adr <= o_wb_adr_nxt;
- o_wb_cti <= o_wb_cti_nxt;
- o_wb_sel <= o_wb_sel_nxt;
- o_wb_dat <= o_wb_dat_nxt;
- o_wb_wen <= o_wb_wen_nxt;
- end
-end
-
-// Next state logic.
-always @*
-begin
- state_nxt = state_ff;
-
- // Change state only if strobe is inactive or strobe has just completed.
- if ( !o_wb_stb || (o_wb_stb && i_wb_ack) )
- begin
- casez({wb_cyc[2],wb_cyc[1],wb_cyc[0]})
- 3'b1?? : state_nxt = S2; // TLB.
- 3'b01? : state_nxt = S1; // Tag.
- 3'b001 : state_nxt = S0; // Cache.
- default: state_nxt = state_ff;
- endcase
- end
-end
-
-// Route ACKs to respective masters.
-always @*
-begin
- wb_ack = 0;
-
- case(state_ff)
- S0: wb_ack[0] = i_wb_ack;
- S1: wb_ack[1] = i_wb_ack;
- S2: wb_ack[2] = i_wb_ack;
- endcase
-end
-
-// Combo signals for external MUXing.
-always @*
-begin
- o_wb_stb_nxt = wb_stb[state_nxt];
- o_wb_cyc_nxt = wb_cyc[state_nxt];
- o_wb_adr_nxt = wb_adr[state_nxt];
- o_wb_dat_nxt = wb_dat[state_nxt];
- o_wb_cti_nxt = wb_cti[state_nxt];
- o_wb_sel_nxt = wb_sel[state_nxt];
- o_wb_wen_nxt = wb_wen[state_nxt];
-end
-
-// synopsys translate_off
- reg xerr = 0;
-
- always @ (posedge i_clk)
- begin
- // Check if data delivered to processor is 'x'.
- if ( o_dat[0] === 1'dx && o_ack && i_rd )
- begin
- xerr = xerr + 1;
- $display($time, "Error : %m Data went to x when giving data to core.");
- $stop;
- end
- end
-// synopsys translate_on
-
-endmodule // zap_cache
-
-`default_nettype wire
Index: zap/trunk/src/rtl/cpu/zap_mem_inv_block.v
===================================================================
--- zap/trunk/src/rtl/cpu/zap_mem_inv_block.v (revision 57)
+++ zap/trunk/src/rtl/cpu/zap_mem_inv_block.v (nonexistent)
@@ -1,105 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////////
-// //
-// Copyright (C) 2016 - 2018 Revanth Kamaraj //
-// //
-// This program is free software; you can redistribute it and/or //
-// modify it under the terms of the GNU General Public License //
-// as published by the Free Software Foundation; either version 2 //
-// of the License, or (at your option) any later version. //
-// //
-// This program 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 General Public License for more details. //
-// //
-// You should have received a copy of the GNU General Public License //
-// along with this program; if not, write to the Free Software //
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, //
-// USA. //
-// //
-//////////////////////////////////////////////////////////////////////////////////
-// //
-// Tag RAMs with single cycle clear. Finds the greatest use in TLBs. //
-// //
-//////////////////////////////////////////////////////////////////////////////////
-
-`default_nettype none
-
-
-module zap_mem_inv_block #(
- parameter DEPTH = 32,
- parameter WIDTH = 32 // Not including valid bit.
-)(
-
-
- input wire i_clk,
- input wire i_reset,
-
- // Write data.
- input wire [WIDTH-1:0] i_wdata,
-
- // Write and read enable.
- input wire i_wen,
- input wire i_ren,
-
- // Invalidate entries in 1 cycle.
- input wire i_inv,
-
- // Read and write address.
- input wire [$clog2(DEPTH)-1:0] i_raddr,
- input wire [$clog2(DEPTH)-1:0] i_waddr,
-
- // Read data and valid.
- output wire [WIDTH-1:0] o_rdata,
- output reg o_rdav
-);
-
-
-// Flops
-reg [DEPTH-1:0] dav_ff;
-
-// Nets
-wire [$clog2(DEPTH)-1:0] addr_r;
-wire en_r;
-
-
-assign addr_r = i_raddr;
-assign en_r = i_ren;
-
-
-// Block RAM.
-zap_ram_simple #(.WIDTH(WIDTH), .DEPTH(DEPTH)) u_ram_simple (
- .i_clk ( i_clk ),
-
- .i_wr_en ( i_wen ),
- .i_rd_en ( en_r ),
-
- .i_wr_data ( i_wdata ),
- .o_rd_data ( o_rdata ),
-
- .i_wr_addr ( i_waddr ),
- .i_rd_addr ( addr_r )
-);
-
-
-// DAV flip-flop implementation.
-always @ (posedge i_clk)
-begin: flip_flops
- if ( i_reset | i_inv )
- begin
- dav_ff <= {DEPTH{1'd0}};
- o_rdav <= 1'd0;
- end
- else
- begin
- if ( i_wen )
- dav_ff [ i_waddr ] <= 1'd1;
-
- if ( en_r )
- o_rdav <= dav_ff [ addr_r ];
- end
-end
-
-
-endmodule // mem_inv_block.v
-`default_nettype wire
Index: zap/trunk/src/rtl/cpu/zap_predecode_compress.v
===================================================================
--- zap/trunk/src/rtl/cpu/zap_predecode_compress.v (revision 57)
+++ zap/trunk/src/rtl/cpu/zap_predecode_compress.v (nonexistent)
@@ -1,596 +0,0 @@
-// -----------------------------------------------------------------------------
-// -- --
-// -- (C) 2016-2018 Revanth Kamaraj. --
-// -- --
-// -- --------------------------------------------------------------------------
-// -- --
-// -- This program is free software; you can redistribute it and/or --
-// -- modify it under the terms of the GNU General Public License --
-// -- as published by the Free Software Foundation; either version 2 --
-// -- of the License, or (at your option) any later version. --
-// -- --
-// -- This program 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 General Public License for more details. --
-// -- --
-// -- You should have received a copy of the GNU General Public License --
-// -- along with this program; if not, write to the Free Software --
-// -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA --
-// -- 02110-1301, USA. --
-// -- --
-// -----------------------------------------------------------------------------
-// -- --
-// -- Implements a 16-bit instruction decoder. The 16-bit instruction set is --
-// -- not logically organized so as to save on encoding and thus the functs --
-// -- seem a bit complex. --
-// -- --
-// -----------------------------------------------------------------------------
-
-`default_nettype none
-
-module zap_predecode_compress (
- // Clock and reset.
- input wire i_clk,
-
- // Input from I-cache.
- // Instruction and valid qualifier.
- input wire [31:0] i_instruction,
- input wire i_instruction_valid,
-
- // Offset input.
- input wire [11:0] i_offset,
-
- // Interrupts. Active high level sensitive signals.
- input wire i_irq,
- input wire i_fiq,
-
- // Ensure compressed mode is active (T bit).
- input wire i_cpsr_ff_t,
-
- //
- // 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,
-
- // Interrupt status output.
- output reg o_irq,
- output reg o_fiq
-);
-
-///////////////////////////////////////////////////////////////////////////////
-
-`include "zap_defines.vh"
-`include "zap_localparams.vh"
-`include "zap_functions.vh"
-
-///////////////////////////////////////////////////////////////////////////////
-
-reg [11:0] offset_w; // Previous offset.
-
-///////////////////////////////////////////////////////////////////////////////
-
-always @*
- offset_w = i_offset;
-
-///////////////////////////////////////////////////////////////////////////////
-
-always @*
-begin
- // If you are not in compressed mode, just pass stuff on.
- o_instruction_valid = i_instruction_valid;
- o_und = 0;
- o_instruction = i_instruction;
- o_irq = i_irq;
- o_fiq = i_fiq;
- o_force32_align = 0;
-
- if ( i_cpsr_ff_t && i_instruction_valid ) // compressed mode enable
- begin
- casez ( i_instruction[15:0] )
- T_BLX1 : decode_blx1;
- T_BLX2 : decode_blx2;
- T_ADD_SUB_LO : decode_add_sub_lo;
- T_SWI : decode_swi;
- T_BRANCH_COND : decode_conditional_branch;
- T_BRANCH_NOCOND : decode_unconditional_branch;
- T_BL : decode_bl;
- T_BX : decode_bx;
- T_SHIFT : decode_shift;
- T_MCAS_IMM : decode_mcas_imm; // MOV,CMP,ADD,SUB IMM.
- T_ALU_LO : decode_alu_lo;
- T_ALU_HI : decode_alu_hi;
- T_PC_REL_LOAD : decode_pc_rel_load; // LDR Rd, [PC, {#imm8,0,0}]
- T_LDR_STR_5BIT_OFF : decode_ldr_str_5bit_off;
- T_LDRH_STRH_5BIT_OFF : decode_ldrh_strh_5bit_off;
- T_LDRH_STRH_REG : decode_ldrh_strh_reg; // Complex.
- T_SP_REL_LDR_STR : decode_sp_rel_ldr_str;
- T_LDMIA_STMIA : decode_ldmia_stmia;
- T_POP_PUSH : decode_pop_push;
- T_GET_ADDR : decode_get_addr;
- T_MOD_SP : decode_mod_sp;
- default:
- begin
- o_und = 1; // Will take UND trap.
- end
- endcase
- end
-end
-
-///////////////////////////////////////////////////////////////////////////////
-
-task decode_get_addr;
-begin: dcdGetAddr
- reg [11:0] imm;
- reg [3:0] rd;
-
- rd = i_instruction[10:8];
- imm[7:0] = i_instruction[7:0];
- imm[11:8] = 4'd15; // To achieve a left shift of 2 i.e., *4
-
- o_instruction = 0;
-
- // ADD Rd, PC, imm
- o_instruction[31:0] = {AL, 2'b00, 1'b1, ADD, 1'd0, 4'd15, rd, imm};
-
- // ADD Rd, SP, imm
- if ( i_instruction[11] ) // SP
- begin
- o_instruction[31:0] = {AL, 2'b00, 1'b1, ADD, 1'd0, 4'd13, rd, imm};
- end
-end
-endtask
-
-///////////////////////////////////////////////////////////////////////////////
-
-task decode_mod_sp;
-begin: dcdModSp
- reg [11:0] imm;
-
- imm[7:0] = i_instruction[6:0];
- imm[11:8] = 4'd15; // To achieve a left shift of 2 i.e., *4
-
- o_instruction = 0;
-
- o_instruction[31:0] = {AL, 2'b00, 1'b1, ADD, 1'd0, 4'd13, 4'd13, imm};
-
- // SUB/ADD R13, R13, imm
- if ( i_instruction[7] != 0 ) // SUB
- begin
- o_instruction[31:0] = {AL, 2'b00, 1'b1, SUB, 1'd0, 4'd13, 4'd13, imm};
- end
-end
-endtask
-
-///////////////////////////////////////////////////////////////////////////////
-
-task decode_pop_push;
-begin: decodePopPush
- //
- // Uses an FD stack. Thus it is DA type i.e., post index down by 4.
- // Writeback is implicit so make W = 0.
- //
-
- reg [3:0] base;
- reg [15:0] reglist;
-
- o_instruction = 0;
- base = 13;
-
- reglist = i_instruction[7:0];
-
- if ( i_instruction[8] == 1 && i_instruction[11] ) // Pop.
- begin
- reglist[15] = 1'd1;
- end
- else if ( i_instruction[8] == 1 && !i_instruction[11] ) // Push.
- begin
- reglist[14] = 1'd1;
- end
-
- o_instruction = {AL, 3'b100, 1'd0, 1'd0, 1'd0, 1'd1, i_instruction[11],
- base, reglist};
-end
-endtask
-
-///////////////////////////////////////////////////////////////////////////////
-
-task decode_ldmia_stmia;
-begin: dcdLdmiaStmia
- // Implicit IA type i.e., post index up by 4. Make WB = 1.
-
- reg [3:0] base;
- reg [15:0] reglist;
-
- base = i_instruction[10:8];
- reglist = i_instruction[7:0];
-
- o_instruction = 0;
- o_instruction = {AL, 3'b100, 1'd0, 1'd1, 1'd0, 1'd1, i_instruction[11],
- base, reglist};
-end
-endtask
-
-///////////////////////////////////////////////////////////////////////////////
-
-task decode_sp_rel_ldr_str;
-begin: dcdLdrRelStr
- reg [3:0] srcdest;
- reg [3:0] base;
- reg [11:0] imm;
-
- srcdest = i_instruction[10:8];
- base = ARCH_SP;
- imm = i_instruction[7:0] << 2;
-
- o_instruction = 0;
- o_instruction = {AL, 3'b010, 1'd1, 1'd0, 1'd0, 1'd0, i_instruction[11],
- base, srcdest, imm};
-end
-endtask
-
-///////////////////////////////////////////////////////////////////////////////
-
-task decode_ldrh_strh_reg;
-begin: dcdLdrhStrh
- // Use different load store format, instead of 3'b010, use 3'b011
-
- reg X,S,H;
- reg [3:0] srcdest, base;
- reg [11:0] offset;
-
- X = i_instruction[9];
- S = i_instruction[10];
- H = i_instruction[11];
- srcdest = i_instruction[2:0];
- base = i_instruction[5:3];
- offset = i_instruction[8:6];
-
- o_instruction = 0;
-
- if ( X == 0 )
- begin
- case({H,S})
- 0: o_instruction = {AL, 3'b011, 1'd1, 1'd0, 1'd0, 1'd0, 1'd0, base, srcdest, offset};// STR
- 1: o_instruction = {AL, 3'b011, 1'd1, 1'd0, 1'd1, 1'd0, 1'd0, base, srcdest, offset};// STRB
- 2: o_instruction = {AL, 3'b011, 1'd1, 1'd0, 1'd0, 1'd0, 1'd1, base, srcdest, offset};// LDR
- 3: o_instruction = {AL, 3'b011, 1'd1, 1'd0, 1'd1, 1'd0, 1'd1, base, srcdest, offset};// LDRB
- endcase
- end
- else
- begin
- case({S,H})
- 0: o_instruction = {AL, 3'b000, 1'd1, 1'd0, 1'd0, 1'd0, 1'd0, base, srcdest, 4'd0, 2'b01,offset[3:0]};// STRH
- 1: o_instruction = {AL, 3'b000, 1'd1, 1'd0, 1'd0, 1'd0, 1'd1, base, srcdest, 4'd0, 2'b01,offset[3:0]};// LDRH
- 2: o_instruction = {AL, 3'b000, 1'd1, 1'd0, 1'd0, 1'd0, 1'd1, base, srcdest, 4'd0, 2'b10,offset[3:0]};// LDSB
- 3: o_instruction = {AL, 3'b000, 1'd1, 1'd0, 1'd0, 1'd0, 1'd1, base, srcdest, 4'd0, 2'b11,offset[3:0]};// LDSH
- endcase
- end
-end
-endtask
-
-///////////////////////////////////////////////////////////////////////////////
-
-task decode_ldrh_strh_5bit_off;
-begin: dcdLdrhStrh5BitOff
-
- reg [3:0] rn;
- reg [3:0] rd;
- reg [7:0] imm;
-
- o_instruction = 0;
-
- rn = i_instruction[5:3];
- rd = i_instruction[2:0];
- imm[7:0] = i_instruction[10:6] << 1;
-
- // Unsigned halfword transfer
- o_instruction = {AL, 3'b000, 1'd1, 1'd0, 1'd1, 1'd0, i_instruction[11],
- rn, rd, imm[7:4], 2'b01,imm[3:0]};
-end
-endtask
-
-///////////////////////////////////////////////////////////////////////////////
-
-task decode_ldr_str_5bit_off;
-begin: dcLdrStr5BitOff
- reg [3:0] rn;
- reg [3:0] rd;
- reg [11:0] imm;
-
- o_instruction = 0;
-
- rn = i_instruction[5:3];
- rd = i_instruction[2:0];
-
- if ( i_instruction[12] == 1'd0 )
- imm[11:0] = i_instruction[10:6] << 2;
- else
- imm[11:0] = i_instruction[10:6];
-
- o_instruction = {AL, 3'b010, 1'd1, 1'd0, i_instruction[12], 1'd0,
- i_instruction[11], rn, rd, imm};
-end
-endtask
-
-///////////////////////////////////////////////////////////////////////////////
-
-task decode_pc_rel_load;
-begin: dcPcRelLoad
- reg [3:0] rd;
- reg [11:0] imm;
-
- rd = i_instruction[10:8];
- imm = i_instruction[7:0] << 2;
-
- o_force32_align = 1'd1;
- o_instruction = 0;
- o_instruction = {AL, 3'b010, 1'd1, 1'd0, 1'd0, 1'd0,
- 1'd1, 4'b1111, rd, imm};
-end
-endtask
-
-///////////////////////////////////////////////////////////////////////////////
-
-task decode_alu_hi;
-begin:dcAluHi
- // Performs operations on HI registers (atleast some of them).
- reg [1:0] op;
- reg [3:0] rd;
- reg [3:0] rs;
-
- o_instruction = 0;
-
- op = i_instruction[9:8];
- rd = {i_instruction[7], i_instruction[2:0]};
- rs = {i_instruction[6], i_instruction[5:3]};
-
- case(op)
- 0: o_instruction[31:0] = {AL, 2'b00, 1'b0, ADD, 1'b0, rd, rd, 8'd0, rs}; // ADD Rd, Rd, Rs
- 1: o_instruction[31:0] = {AL, 2'b00, 1'b0, CMP, 1'b1, rd, rd, 8'd0, rs}; // CMP Rd, Rs
- 2: o_instruction[31:0] = {AL, 2'b00, 1'b0, MOV, 1'b0, rd, rd, 8'd0, rs}; // MOV Rd, Rs
- 3:
- begin
- $display($time, "%m: Error: This should never happen, should be taken by BX...!");
- $finish;
- end
- endcase
-end
-endtask
-
-///////////////////////////////////////////////////////////////////////////////
-
-task decode_alu_lo;
-begin: tskDecAluLo
- reg [3:0] op;
- reg [3:0] rs, rd;
- reg [3:0] rn;
-
- op = i_instruction[9:6];
- rs = i_instruction[5:3];
- rd = i_instruction[2:0];
-
- o_instruction = 0;
-
- case(op)
- 0: o_instruction[31:0] = {AL, 2'b00, 1'b0, AND, 1'd1, rd, rd, 8'd0, rs}; // ANDS Rd, Rd, Rs
- 1: o_instruction[31:0] = {AL, 2'b00, 1'b0, EOR, 1'd1, rd, rd, 8'd0, rs}; // EORS Rd, Rd, Rs
- 2: o_instruction[31:0] = {AL, 2'b00, 1'b0, MOV, 1'd1, rd, rd, rs, 1'd0, LSL, 1'd1, rd}; // MOVS Rd, Rd, LSL Rs
- 3: o_instruction[31:0] = {AL, 2'b00, 1'b0, MOV, 1'd1, rd, rd, rs, 1'd0, LSR, 1'd1, rd}; // MOVS Rd, Rd, LSR Rs
- 4: o_instruction[31:0] = {AL, 2'b00, 1'b0, MOV, 1'd1, rd, rd, rs, 1'd0, ASR, 1'd1, rd}; // MOVS Rd, Rd, ASR Rs
- 5: o_instruction[31:0] = {AL, 2'b00, 1'b0, ADC, 1'd1, rd, rd, 8'd0, rs}; // ADCS Rd, Rd, Rs
- 6: o_instruction[31:0] = {AL, 2'b00, 1'b0, SBC, 1'd1, rd, rd, 8'd0, rs}; // SBCS Rd, Rs, Rs
- 7: o_instruction[31:0] = {AL, 2'b00, 1'b0, MOV, 1'd1, rd, rd, rs, 1'd0, ROR, 1'd1, rd}; // MOVS Rd, Rd, ROR Rs.
- 8: o_instruction[31:0] = {AL, 2'b00, 1'b0, TST, 1'd1, rd, rd, 8'd0, rs}; // TST Rd, Rs
- 9: o_instruction[31:0] = {AL, 2'b00, 1'b1, RSB, 1'd1, rs, rd, 12'd0}; // Rd = 0 - Rs
- 10: o_instruction[31:0] = {AL, 2'b00, 1'b1, CMP, 1'd1, rd, rd, 8'd0, rs}; // CMP Rd, Rs
- 11: o_instruction[31:0] = {AL, 2'b00, 1'b1, CMN, 1'd1, rd, rd, 8'd0, rs}; // CMN Rd, Rs
- 12: o_instruction[31:0] = {AL, 2'b00, 1'b1, ORR, 1'd1, rd, rd, 8'd0, rs}; // ORRS Rd, Rd, rs
- 13: o_instruction[31:0] = {AL, 4'b0000, 3'b000, 1'd1, rd, 4'd0, rd, 4'b1001, rs}; // MULS Rd, Rs, Rd
- 14: o_instruction[31:0] = {AL, 2'b00, 1'b1, BIC, 1'd1, rd, rd, 8'd0, rs}; // BICS rd, rd, rs
- 15: o_instruction[31:0] = {AL, 2'b00, 1'b1, MVN, 1'd1, rd, rd, 8'd0, rs}; // MVNS rd, rd, rs
- endcase
-end
-endtask
-
-///////////////////////////////////////////////////////////////////////////////
-
-task decode_mcas_imm;
-begin: tskDecodeMcasImm
- reg [1:0] op;
- reg [3:0] rd;
- reg [11:0] imm;
-
- o_instruction = 0;
-
- op = i_instruction[12:11];
- rd = i_instruction[10:8];
- imm =i_instruction[7:0];
-
- case (op)
- 0:
- begin
- // MOV Rd, Offset8
- o_instruction[31:0] = {AL, 2'b00, 1'b1, MOV, 1'd1, rd, rd, imm};
- end
- 1:
- begin
- // CMP Rd, Offset8
- o_instruction[31:0] = {AL, 2'b00, 1'b1, CMP, 1'd1, rd, rd, imm};
- end
- 2:
- begin
- // ADDS Rd, Rd, Offset8
- o_instruction[31:0] = {AL, 2'b00, 1'b1, ADD, 1'd1, rd, rd, imm};
- end
- 3:
- begin
- // SUBS Rd, Rd, Offset8
- o_instruction[31:0] = {AL, 2'b00, 1'b1, SUB, 1'd1, rd, rd, imm};
- end
- endcase
-end
-endtask
-
-///////////////////////////////////////////////////////////////////////////////
-
-task decode_add_sub_lo;
-begin: tskDecodeAddSubLo
- reg [3:0] rn, rd, rs;
- reg [11:0] imm;
-
- o_instruction = 0;
-
- rn = i_instruction[8:6];
- rd = i_instruction[2:0];
- rs = i_instruction[5:3];
- imm = rn;
-
- case({i_instruction[9], i_instruction[10]})
- 0:
- begin
- // Add Rd, Rs, Rn - Instr spec shift.
- o_instruction[31:0] = {AL, 2'b00, 1'b0, ADD, 1'd1, rs, rd, 8'd0, rn};
- end
- 1:
- begin
- // Adds Rd, Rs, #Offset3 - Immediate.
- o_instruction[31:0] = {AL, 2'b00, 1'b1, ADD, 1'd1, rn, rd, imm};
- end
- 2:
- begin
- // SUBS Rd, Rs, Rn - Instr spec shift.
- o_instruction[31:0] = {AL, 2'b00, 1'b0, SUB, 1'd1, rs, rd, 8'd0, rn};
- end
- 3:
- begin
- // SUBS Rd, Rs, #Offset3 - Immediate.
- o_instruction[31:0] = {AL, 2'b00, 1'b1, SUB, 1'd1, rn, rd, imm};
- end
- endcase
-end
-endtask
-
-///////////////////////////////////////////////////////////////////////////////
-
-task decode_conditional_branch;
-begin
- // An MSB of 1 indicates a left shift of 1.
- o_instruction = {1'd1, 2'b0, i_instruction[11:8], 3'b101, 1'b0, 24'd0};
- o_instruction[23:0] = $signed(i_instruction[7:0]);
-end
-endtask
-
-///////////////////////////////////////////////////////////////////////////////
-
-task decode_unconditional_branch;
-begin
- // An MSB of 1 indicates a left shift of 1.
- o_instruction = {1'd1, 2'b0, AL, 3'b101, 1'b0, 24'd0};
- o_instruction[23:0] = $signed(i_instruction[10:0]);
-end
-endtask
-
-///////////////////////////////////////////////////////////////////////////////
-
-task decode_blx1;
-begin
- o_instruction = 0; // Default value.
-
- // Generate a BLX1.
- o_instruction[31:25] = 7'b1111_101; // BLX1 identifier.
- o_instruction[24] = 1'd0; // H - bit.
- o_instruction[23:0] = ($signed(offset_w) << 12) | (i_instruction[10:0] << 1); // Corrected.
- o_irq = 1'd0;
- o_fiq = 1'd0;
-end
-endtask
-
-////////////////////////////////////////////////////////////////////////////////
-
-task decode_blx2;
-begin
- o_instruction = {4'b1110,4'b0001,4'b0010,4'b1111,4'b1111,4'b1111,4'b0011, i_instruction[6:3]};
- o_irq = 1'd0;
- o_fiq = 1'd0;
-end
-endtask
-
-///////////////////////////////////////////////////////////////////////////////
-
-task decode_bl;
-begin
- case ( i_instruction[11] )
- 1'd0:
- begin
- // Send out a dummy instruction. Preserve lower
- // 12-bits though to serve as offset. Set condition
- // code to NV.
- o_instruction = i_instruction[11:0];
- o_instruction[31:28] = 4'b1111;
- o_irq = 1'd0;
- o_fiq = 1'd0;
- end
- 1'd1:
- begin
- // Generate a full jump.
- o_instruction = {1'd1, 2'b0, AL, 3'b101, 1'b1, 24'd0};
- o_instruction[23:0] = ($signed(offset_w) << 12) | (i_instruction[10:0] << 1); // Corrected.
- o_irq = 1'd0;
- o_fiq = 1'd0;
- end
- endcase
-end
-endtask
-
-///////////////////////////////////////////////////////////////////////////////
-
-task decode_bx;
-begin
- // Generate a BX Rm.
- o_instruction = 32'b0000_0001_0010_1111_1111_1111_0001_0000;
- o_instruction[31:28] = AL;
- o_instruction[3:0] = i_instruction[6:3];
-end
-endtask
-
-///////////////////////////////////////////////////////////////////////////////
-
-task decode_swi;
-begin
- // Generate a SWI.
- o_instruction = 32'b0000_1111_0000_0000_0000_0000_0000_0000;
- o_instruction[31:28] = AL;
- o_instruction[7:0] = i_instruction[7:0];
-end
-endtask
-
-///////////////////////////////////////////////////////////////////////////////
-
-task decode_shift;
-begin
- // Compressed shift instructions. Decompress to ARM with instruction specified shift.
- o_instruction = 32'd0; // Extension -> 0.
- o_instruction[31:28] = AL; // Always execute.
- o_instruction[27:26] = 2'b00; // Data processing.
- o_instruction[25] = 1'd0; // Immediate is ZERO.
- o_instruction[24:21] = MOV; // Operation is MOV.
- o_instruction[20] = 1'd1; // Do update flags.
- o_instruction[19:16] = 4'd0; // ALU source. Doesn't matter.
- o_instruction[15:12] = i_instruction[2:0] ; // Destination.
- o_instruction[11:7] = i_instruction[10:6]; // Shamt.
- o_instruction[6:5] = i_instruction[12:11]; // Shtype.
- o_instruction[3:0] = i_instruction[5:3]; // Shifter source.
-end
-endtask
-
-///////////////////////////////////////////////////////////////////////////////
-
-endmodule
-`default_nettype wire
Index: zap/trunk/src/rtl/cpu/zap_writeback.v
===================================================================
--- zap/trunk/src/rtl/cpu/zap_writeback.v (revision 57)
+++ zap/trunk/src/rtl/cpu/zap_writeback.v (nonexistent)
@@ -1,445 +0,0 @@
-// -----------------------------------------------------------------------------
-// -- --
-// -- (C) 2016-2018 Revanth Kamaraj. --
-// -- --
-// -- --------------------------------------------------------------------------
-// -- --
-// -- This program is free software; you can redistribute it and/or --
-// -- modify it under the terms of the GNU General Public License --
-// -- as published by the Free Software Foundation; either version 2 --
-// -- of the License, or (at your option) any later version. --
-// -- --
-// -- This program 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 General Public License for more details. --
-// -- --
-// -- You should have received a copy of the GNU General Public License --
-// -- along with this program; if not, write to the Free Software --
-// -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA --
-// -- 02110-1301, USA. --
-// -- --
-// -----------------------------------------------------------------------------
-
-`default_nettype none
-
-module zap_writeback #(
- parameter FLAG_WDT = 32, // Flags width a.k.a CPSR.
- parameter PHY_REGS = 46 // Number of physical registers.
-)
-(
- // Decompile.
- input wire [64*8-1:0] i_decompile,
- output reg [64*8-1:0] o_decompile,
-
- // Shelve output.
- output wire o_shelve,
-
- // Clock and reset.
- input wire i_clk,
- input wire i_reset,
-
- // Inputs from memory unit valid signal.
- input wire i_valid,
-
- // The PC can either be frozen in place or changed based on signals
- // from other units. If a unit clears the PC, it must provide the
- // appropriate new value.
- input wire i_code_stall,
- input wire i_data_stall,
- input wire i_clear_from_alu,
- input wire [31:0] i_pc_from_alu,
- input wire i_stall_from_decode,
- input wire i_stall_from_issue,
- input wire i_stall_from_shifter,
- input wire i_clear_from_decode,
- input wire [31:0] i_pc_from_decode,
-
- // 4 read ports for high performance.
- input wire [$clog2(PHY_REGS)-1:0] i_rd_index_0,
- input wire [$clog2(PHY_REGS)-1:0] i_rd_index_1,
- input wire [$clog2(PHY_REGS)-1:0] i_rd_index_2,
- input wire [$clog2(PHY_REGS)-1:0] i_rd_index_3,
-
- // Memory load indicator.
- input wire i_mem_load_ff,
-
- // Write index and data and flag updates.
- input wire [$clog2(PHY_REGS)-1:0] i_wr_index,
- input wire [31:0] i_wr_data,
- input wire [FLAG_WDT-1:0] i_flags,
- input wire i_thumb,
- input wire [$clog2(PHY_REGS)-1:0] i_wr_index_1,
- input wire [31:0] i_wr_data_1,
-
- // Interrupt indicators.
- input wire i_irq,
- input wire i_fiq,
- input wire i_instr_abt,
- input wire i_data_abt,
- input wire i_swi,
- input wire i_und,
-
- // Program counter, PC + 8. This value is captured in the fetch
- // stage and is buffered all the way through.
- input wire [31:0] i_pc_buf_ff,
-
- // Coprocessor.
- input wire i_copro_reg_en,
- input wire [$clog2(PHY_REGS)-1:0] i_copro_reg_wr_index,
- input wire [$clog2(PHY_REGS)-1:0] i_copro_reg_rd_index,
- input wire [31:0] i_copro_reg_wr_data,
- output reg [31:0] o_copro_reg_rd_data_ff,
-
- // Read data from the register file.
- output wire [31:0] o_rd_data_0,
- output wire [31:0] o_rd_data_1,
- output wire [31:0] o_rd_data_2,
- output wire [31:0] o_rd_data_3,
-
- // Program counter (dedicated port).
- output wire [31:0] o_pc,
- output wire [31:0] o_pc_nxt,
-
- // CPSR output
- output wire [31:0] o_cpsr_nxt,
-
- // Clear from writeback
- output reg o_clear_from_writeback,
-
- // Hijack I/F
- output reg [31:0] o_hijack_op1,
- output reg [31:0] o_hijack_op2,
- output reg o_hijack_cin,
- output reg o_hijack,
- input wire [31:0] i_hijack_sum
-);
-
-`include "zap_defines.vh"
-`include "zap_localparams.vh"
-`include "zap_functions.vh"
-
-// ----------------------------------------------------------------------------
-// Localparams
-// ----------------------------------------------------------------------------
-
-`ifndef ARM_MODE
- `define ARM_MODE (cpsr_ff[T] == 1'd0)
-`endif
-
-localparam RST_VECTOR = 32'h00000000;
-localparam UND_VECTOR = 32'h00000004;
-localparam SWI_VECTOR = 32'h00000008;
-localparam PABT_VECTOR = 32'h0000000C;
-localparam DABT_VECTOR = 32'h00000010;
-localparam IRQ_VECTOR = 32'h00000018;
-localparam FIQ_VECTOR = 32'h0000001C;
-
-// ----------------------------------------------------------------------------
-// Variables
-// ----------------------------------------------------------------------------
-
-reg [31:0] cpsr_ff, cpsr_nxt;
-reg [31:0] pc_ff, pc_nxt;
-reg [$clog2(PHY_REGS)-1:0] wa1, wa2;
-reg [31:0] wdata1, wdata2;
-reg wen;
-reg [31:0] pc_shelve_ff, pc_shelve_nxt;
-reg shelve_ff, shelve_nxt;
-
-assign o_shelve = shelve_ff; // Shelve the PC until it is needed.
-assign o_pc = pc_ff;
-assign o_pc_nxt = pc_nxt & 32'hfffffffe;
-assign o_cpsr_nxt = cpsr_nxt;
-
-// ----------------------------------------------------------------------------
-// Register file
-// ----------------------------------------------------------------------------
-
-zap_register_file u_zap_register_file
-(
-.i_clk(i_clk),
- .i_reset ( i_reset ),
-
- .i_wr_addr_a ( wa1 ),
- .i_wr_addr_b ( wa2 ),
-
- .i_wr_data_a ( wdata1 ),
- .i_wr_data_b ( wdata2 ),
-
- .i_wen ( wen ),
-
- .i_rd_addr_a ( i_copro_reg_en ? i_copro_reg_rd_index : i_rd_index_0 ),
- .i_rd_addr_b ( i_rd_index_1 ),
- .i_rd_addr_c ( i_rd_index_2 ),
- .i_rd_addr_d ( i_rd_index_3 ),
-
- .o_rd_data_a ( o_rd_data_0 ),
- .o_rd_data_b ( o_rd_data_1 ),
- .o_rd_data_c ( o_rd_data_2 ),
- .o_rd_data_d ( o_rd_data_3 )
-);
-
-// ----------------------------------------------------------------------------
-// Combinational Logic
-// ----------------------------------------------------------------------------
-
-always @ (*)
-begin: blk1
-
- integer i;
-
- shelve_nxt = shelve_ff;
- pc_shelve_nxt = pc_shelve_ff;
-
- o_hijack = 0;
- o_hijack_op1 = 0;
- o_hijack_op2 = 0;
- o_hijack_cin = 0;
-
- wen = 1'd0;
- wa1 = PHY_RAZ_REGISTER;
- wa2 = PHY_RAZ_REGISTER;
- wdata1 = 32'd0;
- wdata2 = 32'd0;
-
- o_clear_from_writeback = 0;
-
- pc_nxt = pc_ff;
- cpsr_nxt = cpsr_ff;
-
-
- // Low priority PC control tree.
-
- if ( i_clear_from_alu )
- begin
- pc_shelve(i_pc_from_alu);
- end
-
- else if ( i_clear_from_decode )
- begin
- pc_shelve(i_pc_from_decode);
- end
-
- else if ( i_code_stall )
- begin
- pc_nxt = pc_ff;
- end
- else if ( shelve_ff )
- begin
-
- pc_nxt = pc_shelve_ff;
- shelve_nxt = 1'd0;
- end
- else
- begin
- pc_nxt = pc_ff + (i_thumb ? 32'd2 : 32'd4);
- end
-
-
- // The stuff below has more priority than the above. This means even in
- // a global stall, interrupts can overtake execution. Further, writes to
- // PC that reach writeback can cancel a global stall. On interrupts or
- // jumps, all units are flushed effectively clearing any global stalls.
-
- if ( i_data_abt ||
- i_fiq ||
- i_irq ||
- i_instr_abt ||
- i_swi ||
- i_und )
- begin
- o_clear_from_writeback = 1'd1;
- cpsr_nxt[I] = 1'd1; // Mask interrupts.
- cpsr_nxt[T] = 1'd0; // Go to ARM mode.
- end
-
- if ( i_data_abt )
- begin
- o_hijack = 1'd1;
- o_hijack_op1 = i_pc_buf_ff;
- o_hijack_op2 = 32'd4;
- o_hijack_cin = 1'd0;
-
- // Returns do LR - 8 to get back to the same instruction.
- pc_shelve( DABT_VECTOR );
-
- wen = 1;
- wdata1 = `ARM_MODE ? i_pc_buf_ff : i_hijack_sum[31:0];
- wa1 = PHY_ABT_R14;
- wa2 = PHY_ABT_SPSR;
- wdata2 = cpsr_ff;
- cpsr_nxt[`CPSR_MODE] = ABT;
- end
- else if ( i_fiq )
- begin
- // Returns do LR - 4 to get back to the same instruction.
- pc_shelve ( FIQ_VECTOR );
-
- wen = 1;
- wdata1 = `ARM_MODE ? i_wr_data : i_pc_buf_ff ;
- wa1 = PHY_FIQ_R14;
- wa2 = PHY_FIQ_SPSR;
- wdata2 = cpsr_ff;
- cpsr_nxt[`CPSR_MODE] = FIQ;
- cpsr_nxt[F] = 1'd1;
- end
- else if ( i_irq )
- begin
- pc_shelve (IRQ_VECTOR);
-
- wen = 1;
- wdata1 = `ARM_MODE ? i_wr_data : i_pc_buf_ff ;
- wa1 = PHY_IRQ_R14;
- wa2 = PHY_IRQ_SPSR;
- wdata2 = cpsr_ff;
- cpsr_nxt[`CPSR_MODE] = IRQ;
- // Returns do LR - 4 to get back to the same instruction.
- end
- else if ( i_instr_abt )
- begin
- // Returns do LR - 4 to get back to the same instruction.
- pc_shelve (PABT_VECTOR);
-
- wen = 1;
- wdata1 = `ARM_MODE ? i_wr_data : i_pc_buf_ff ;
- wa1 = PHY_ABT_R14;
- wa2 = PHY_ABT_SPSR;
- wdata2 = cpsr_ff;
- cpsr_nxt[`CPSR_MODE] = ABT;
- end
- else if ( i_swi )
- begin
- // Returns do LR to return to the next instruction.
- pc_shelve(SWI_VECTOR);
-
- wen = 1;
- wdata1 = `ARM_MODE ? i_wr_data : i_pc_buf_ff ;
- wa1 = PHY_SVC_R14;
- wa2 = PHY_SVC_SPSR;
- wdata2 = cpsr_ff;
- cpsr_nxt[`CPSR_MODE] = SVC;
- end
- else if ( i_und )
- begin
- // Returns do LR to return to the next instruction.
- pc_shelve(UND_VECTOR);
-
- wen = 1;
- wdata1 = `ARM_MODE ? i_wr_data : i_pc_buf_ff ;
- wa1 = PHY_UND_R14;
- wa2 = PHY_UND_SPSR;
- wdata2 = cpsr_ff;
- cpsr_nxt[`CPSR_MODE] = UND;
- end
- else if ( i_copro_reg_en )
- begin
- // Write to register (Coprocessor command).
- wen = 1;
- wa1 = i_copro_reg_wr_index;
- wdata1 = i_copro_reg_wr_data;
- end
- else if ( i_valid ) // If valid,
- begin
- // Only then execute the instruction at hand...
- cpsr_nxt = i_flags;
-
- // Dual write port.
- wen = 1;
-
- // Port from arithmetic side
- wa1 = i_wr_index;
- wdata1 = i_wr_data;
-
- // Port from memory side.
- wa2 = i_mem_load_ff ? i_wr_index_1 : PHY_RAZ_REGISTER;
- wdata2 = i_wr_data_1;
-
- // Load to PC will trigger from writeback.
- if ( i_mem_load_ff && i_wr_index_1 == ARCH_PC)
- begin
- pc_shelve (i_wr_data_1);
- o_clear_from_writeback = 1'd1;
- end
- end
-
- // Ensure lower 2 bits of PC are always tied to VSS.
- pc_nxt = pc_nxt & 32'hffff_fffe;
-end
-
-// ----------------------------------------------------------------------------
-// Sequential Logic
-// ----------------------------------------------------------------------------
-
-always @ ( posedge i_clk )
-begin
- if ( i_reset )
- begin
- // On reset, the CPU starts at 0 in
- // supervisor mode.
- shelve_ff <= 1'd0;
- pc_ff <= 32'd0;
- cpsr_ff <= SVC;
- cpsr_ff[I] <= 1'd1; // Mask IRQ.
- cpsr_ff[F] <= 1'd1; // Mask FIQ.
- cpsr_ff[T] <= 1'd0; // Start CPU in ARM mode.
- end
- else
- begin
- shelve_ff <= shelve_nxt;
- pc_shelve_ff <= pc_shelve_nxt;
- pc_ff <= pc_nxt;
- cpsr_ff <= cpsr_nxt;
- o_decompile <= i_decompile;
- o_copro_reg_rd_data_ff <= o_rd_data_0;
- end
-end
-
-// ----------------------------------------------------------------------------
-// Tasks
-// ----------------------------------------------------------------------------
-
-task pc_shelve (input [31:0] new_pc);
-begin
- if (!i_code_stall )
- begin
- pc_nxt = new_pc;
- shelve_nxt = 1'd0; // BUG FIX.
- end
- else
- begin
- shelve_nxt = 1'd1;
- pc_shelve_nxt = new_pc;
- pc_nxt = pc_ff;
- end
-end
-endtask
-
-always @ (*)
-if ( cpsr_nxt[`CPSR_MODE] != USR && cpsr_ff[`CPSR_MODE] == USR )
-begin
- if (
- i_data_abt ||
- i_fiq ||
- i_irq ||
- i_instr_abt ||
- i_swi ||
- i_und
- )
- begin
- // OKAY...
- end
- else
- begin
- $display($time, "Error : %m CPU is changing out of USR mode without an exception...");
- $stop;
- end
-end
-
-endmodule // zap_register_file.v
-
-`default_nettype wire
-
-// ----------------------------------------------------------------------------
-// END OF FILE
-// ----------------------------------------------------------------------------
Index: zap/trunk/src/rtl/cpu/zap_cp15_cb.v
===================================================================
--- zap/trunk/src/rtl/cpu/zap_cp15_cb.v (revision 57)
+++ zap/trunk/src/rtl/cpu/zap_cp15_cb.v (nonexistent)
@@ -1,542 +0,0 @@
-// -----------------------------------------------------------------------------
-// -- --
-// -- (C) 2016-2018 Revanth Kamaraj. --
-// -- --
-// -- --------------------------------------------------------------------------
-// -- --
-// -- This program is free software; you can redistribute it and/or --
-// -- modify it under the terms of the GNU General Public License --
-// -- as published by the Free Software Foundation; either version 2 --
-// -- of the License, or (at your option) any later version. --
-// -- --
-// -- This program 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 General Public License for more details. --
-// -- --
-// -- You should have received a copy of the GNU General Public License --
-// -- along with this program; if not, write to the Free Software --
-// -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA --
-// -- 02110-1301, USA. --
-// -- --
-// -----------------------------------------------------------------------------
-// -- --
-// -- This RTL describes the CP15 register block. The ports go to the MMU and --
-// -- cache unit. This block connects to the CPU core. Coprocessor operations --
-// -- supported are read from coprocessor and write to CPU registers or vice --
-// -- versa. This is integrated within the processor. The MMU unit can easily --
-// -- interface with this block. --
-// -- --
-// -----------------------------------------------------------------------------
-
-`default_nettype none
-
-module zap_cp15_cb #(
- parameter PHY_REGS = 64
-)
-(
- // ----------------------------------------------------------------
- // Clock and reset.
- // ----------------------------------------------------------------
-
- input wire i_clk,
- input wire i_reset,
-
- // ----------------------------------------------------------------
- // Coprocessor instruction and done signal.
- // ----------------------------------------------------------------
-
- input wire [31:0] i_cp_word,
- input wire i_cp_dav,
- output reg o_cp_done,
-
- // ----------------------------------------------------------------
- // CPSR from processor.
- // ----------------------------------------------------------------
-
- input wire [31:0] i_cpsr,
-
- // ----------------------------------------------------------------
- // Register file RW interface
- // ----------------------------------------------------------------
-
- // Asserted if we want to control of the register file.
- // Controls a MUX that selects signals.
- output reg o_reg_en,
-
- // Data to write to the register file.
- output reg [31:0] o_reg_wr_data,
-
- // Data read from the register file.
- input wire [31:0] i_reg_rd_data,
-
- // Write and read index for the register file.
- output reg [$clog2(PHY_REGS)-1:0] o_reg_wr_index,
- o_reg_rd_index,
-
- // ----------------------------------------------------------------
- // From MMU.
- // ----------------------------------------------------------------
-
- input wire [31:0] i_fsr,
- input wire [31:0] i_far,
-
- // -----------------------------------------------------------------
- // MMU configuration signals.
- // -----------------------------------------------------------------
-
- // Domain Access Control Register.
- output reg [31:0] o_dac,
-
- // Base address of page table.
- output reg [31:0] o_baddr,
-
- // MMU enable.
- output reg o_mmu_en,
-
- // SR register.
- output reg [1:0] o_sr,
-
- // FCSE register.
- output reg [7:0] o_pid,
-
- // -----------------------------------------------------------------
- // Invalidate and clean controls.
- // -----------------------------------------------------------------
-
- // Cache invalidate signal.
- output reg o_dcache_inv,
- output reg o_icache_inv,
-
- // Cache clean signal.
- output reg o_dcache_clean,
- output reg o_icache_clean,
-
- // TLB invalidate signal - single cycle.
- output reg o_dtlb_inv,
- output reg o_itlb_inv,
-
- // Cache enable.
- output reg o_dcache_en,
- output reg o_icache_en,
-
- // From MMU. Specify that cache invalidation is done.
- input wire i_dcache_inv_done,
- input wire i_icache_inv_done,
-
- // From MMU. Specify that cache clean is done.
- input wire i_dcache_clean_done,
- input wire i_icache_clean_done
-);
-
-`include "zap_localparams.vh"
-`include "zap_defines.vh"
-`include "zap_functions.vh"
-
-// ---------------------------------------------
-// Variables
-// ---------------------------------------------
-
-reg [31:0] r [13:0];// Coprocessor registers. R7, R8 is write-only.
-reg [3:0] state; // State variable.
-
-// ---------------------------------------------
-// Localparams
-// ---------------------------------------------
-
-// States.
-localparam IDLE = 0;
-localparam ACTIVE = 1;
-localparam DONE = 2;
-localparam READ = 3;
-localparam READ_DLY = 4;
-localparam TERM = 5;
-localparam CLR_D_CACHE_AND = 6;
-localparam CLR_D_CACHE = 7;
-localparam CLR_I_CACHE = 8;
-localparam CLEAN_D_CACHE = 9;
-localparam CLEAN_ID_CACHE = 10;
-localparam CLFLUSH_ID_CACHE = 11;
-localparam CLFLUSH_D_CACHE = 12;
-
-// Register numbers.
-localparam FSR_REG = 5;
-localparam FAR_REG = 6;
-localparam CACHE_REG = 7;
-localparam TLB_REG = 8;
-localparam FCSE_REG = 13;
-
-//{opcode_2, crm} values that are valid for this implementation.
-localparam CASE_FLUSH_ID_CACHE = 7'b000_0111;
-localparam CASE_FLUSH_I_CACHE = 7'b000_0101;
-localparam CASE_FLUSH_D_CACHE = 7'b000_0110;
-localparam CASE_CLEAN_ID_CACHE = 7'b000_1011;
-localparam CASE_CLEAN_D_CACHE = 7'b000_1010;
-localparam CASE_CLFLUSH_ID_CACHE = 7'b000_1111;
-localparam CASE_CLFLUSH_D_CACHE = 7'b000_1110;
-localparam CASE_FLUSH_ID_TLB = 7'b000_0111;
-localparam CASE_FLUSH_I_TLB = 7'b000_0101;
-localparam CASE_FLUSH_D_TLB = 7'b000_0110;
-
-// ---------------------------------------------
-// Sequential Logic
-// ---------------------------------------------
-
-// Ties registers to output ports via a register.
-always @ ( posedge i_clk )
-begin
- if ( i_reset )
- begin
- o_dcache_en <= 1'd0;
- o_icache_en <= 1'd0;
- o_mmu_en <= 1'd0;
- o_dac <= 32'dx;
- o_baddr <= 32'dx;
- o_sr <= 2'dx;
- o_pid <= 8'd0;
- end
- else
- begin
- o_dcache_en <= r[1][2]; // Data cache enable.
- o_icache_en <= r[1][12]; // Instruction cache enable.
- o_mmu_en <= r[1][0]; // MMU enable.
- o_dac <= r[3]; // DAC register.
- o_baddr <= r[2]; // Base address.
- o_sr <= {r[1][8],r[1][9]}; // SR register.
- o_pid <= {1'd0, r[13][31:25]}; // PID register.
- end
-end
-
-// Core logic.
-always @ ( posedge i_clk )
-begin
- if ( i_reset )
- begin
- state <= IDLE;
- o_dcache_inv <= 1'd0;
- o_icache_inv <= 1'd0;
- o_dcache_clean <= 1'd0;
- o_icache_clean <= 1'd0;
- o_dtlb_inv <= 1'd0;
- o_itlb_inv <= 1'd0;
- o_reg_en <= 1'd0;
- o_cp_done <= 1'd0;
- o_reg_wr_data <= 0;
- o_reg_wr_index <= 0;
- o_reg_rd_index <= 0;
- r[0] <= 32'h0;
- r[1] <= 32'd0;
- r[2] <= 32'd0;
- r[3] <= 32'd0;
- r[4] <= 32'd0;
- r[5] <= 32'd0;
- r[6] <= 32'd0;
- r[13] <= 32'd0; //FCSE
-
- // R0 override.
- generate_r0;
-
- // R1 override.
- r[1][1] <= 1'd1;
- r[1][3] <= 1'd1;
- r[1][6:4] <= 3'b111;
- r[1][11] <= 1'd1;
- end
- else
- begin
- // Default assignments.
- o_itlb_inv <= 1'd0;
- o_dtlb_inv <= 1'd0;
- o_dcache_inv <= 1'd0;
- o_icache_inv <= 1'd0;
- o_icache_clean <= 1'd0;
- o_dcache_clean <= 1'd0;
- o_reg_en <= 1'd0;
- o_cp_done <= 1'd0;
-
- case ( state )
- IDLE: // Idle state.
- begin
- o_cp_done <= 1'd0;
-
- // Keep monitoring FSR and FAR from MMU unit. If
- // produced, clock them in.
- if ( i_fsr[3:0] != 4'd0 )
- begin
- r[FSR_REG] <= i_fsr;
- r[FAR_REG] <= i_far;
- end
-
- // Coprocessor instruction.
- if ( i_cp_dav && i_cp_word[`cp_id] == 15 )
- begin
- if ( i_cpsr[4:0] != USR )
- begin
- // ACTIVATE this block.
- state <= ACTIVE;
- o_cp_done <= 1'd0;
- end
- else
- begin
- // No permissions in USR land.
- // Pretend to be done and go ahead.
- o_cp_done <= 1'd1;
- end
- end
- end
-
- DONE: // Complete transaction.
- begin
- // Tell that we are done.
- o_cp_done <= 1'd1;
- state <= TERM;
- end
-
- TERM: // Wait state before going to IDLE.
- begin
- state <= IDLE;
- end
-
- READ_DLY: // Register data is clocked out in this stage.
- begin
- state <= READ;
- end
-
- READ: // Write value read from CPU register to coprocessor.
- begin
- state <= DONE;
-
- r [ i_cp_word[`crn] ] <= i_reg_rd_data;
-
- if (
- i_cp_word[`crn] == TLB_REG // TLB control.
- )
- begin
- case({i_cp_word[`opcode_2], i_cp_word[`crm]})
-
- CASE_FLUSH_ID_TLB:
- begin
- o_itlb_inv <= 1'd1;
- o_dtlb_inv <= 1'd1;
- end
-
- CASE_FLUSH_I_TLB:
- begin
- o_itlb_inv <= 1'd1;
- end
-
- CASE_FLUSH_D_TLB:
- begin
- o_dtlb_inv <= 1'd1;
- end
-
- default:
- begin
- o_itlb_inv <= 1'd1;
- o_dtlb_inv <= 1'd1;
- end
-
- endcase
- end
- else if ( i_cp_word[`crn] == CACHE_REG ) // Cache control.
- begin
- case({i_cp_word[`opcode_2], i_cp_word[`crm]})
- CASE_FLUSH_ID_CACHE:
- begin
- // Invalidate caches.
- o_dcache_inv <= 1'd1;
- state <= CLR_D_CACHE_AND;
- end
-
- CASE_FLUSH_D_CACHE:
- begin
-
- // Invalidate data cache.
- o_dcache_inv <= 1'd1;
- state <= CLR_D_CACHE;
- end
-
- CASE_FLUSH_I_CACHE:
- begin
-
- // Invalidate instruction cache.
- o_icache_inv <= 1'd1;
- state <= CLR_I_CACHE;
- end
-
- CASE_CLEAN_ID_CACHE, CASE_CLEAN_D_CACHE:
- begin
-
- o_dcache_clean <= 1'd1;
- state <= CLEAN_D_CACHE;
- end
-
- CASE_CLFLUSH_D_CACHE:
- begin
-
- o_dcache_clean <= 1'd1;
- state <= CLFLUSH_D_CACHE;
- end
-
- CASE_CLFLUSH_ID_CACHE:
- begin
-
- o_dcache_clean <= 1'd1;
- state <= CLFLUSH_ID_CACHE;
- end
-
- default:
- begin
- o_dcache_clean <= 1'd1;
- state <= CLFLUSH_ID_CACHE;
- end
-
- endcase
- end
- end
-
- // States.
- CLEAN_D_CACHE,
- CLFLUSH_ID_CACHE,
- CLFLUSH_D_CACHE:
- begin
- o_dcache_clean <= 1'd1;
-
- if ( i_dcache_clean_done )
- begin
- o_dcache_clean <= 1'd0;
-
- if ( state == CLFLUSH_D_CACHE )
- begin
- o_dcache_inv <= 1'd1;
- state <= CLR_D_CACHE;
- end
- else if ( state == CLFLUSH_ID_CACHE )
- begin
- o_dcache_inv <= 1'd1;
- state <= CLR_D_CACHE_AND;
- end
- else // CLEAN_D_CACHE
- begin
- state <= DONE;
- end
- end
- end
-
- CLR_D_CACHE, CLR_D_CACHE_AND: // Clear data cache.
- begin
- o_dcache_inv <= 1'd1;
-
- // Wait for cache invalidation to complete.
- if ( i_dcache_inv_done && state == CLR_D_CACHE )
- begin
- o_dcache_inv <= 1'd0;
- state <= DONE;
- end
- else if ( state == CLR_D_CACHE_AND && i_dcache_inv_done )
- begin
- o_dcache_inv <= 1'd0;
- o_icache_inv <= 1'd1;
- state <= CLR_I_CACHE;
- end
- end
-
- CLR_I_CACHE: // Clear instruction cache.
- begin
- o_icache_inv <= 1'd1;
-
- if ( i_icache_inv_done )
- begin
- o_icache_inv <= 1'd0;
- state <= DONE;
- end
- end
-
- ACTIVE: // Access processor registers.
- begin
- if ( is_cc_satisfied ( i_cp_word[31:28], i_cpsr[31:28] ) )
- begin
- if ( i_cp_word[20] ) // Load to CPU reg.
- begin
- // Generate CPU Register write command. CP read.
- o_reg_en <= 1'd1;
- o_reg_wr_index <= translate( i_cp_word[15:12], i_cpsr[4:0] );
- o_reg_wr_data <= r[ i_cp_word[19:16] ];
- state <= DONE;
- end
- else // Store to CPU register.
- begin
- // Generate CPU register read command. CP write.
- o_reg_en <= 1'd1;
- o_reg_rd_index <= translate(i_cp_word[15:12], i_cpsr[4:0]);
- o_reg_wr_index <= 16;
- state <= READ_DLY;
- end
- end
- else
- begin
- state <= DONE;
- end
-
- // Process unconditional words to CP15.
- casez ( i_cp_word )
- MCR2, MRC2, LDC2, STC2:
- begin
- if ( i_cp_word[20] ) // Load to CPU reg.
- begin
- // Register write command.
- o_reg_en <= 1'd1;
- o_reg_wr_index <= translate( i_cp_word[15:12], i_cpsr[4:0] );
- o_reg_wr_data <= r[ i_cp_word[19:16] ];
- state <= DONE;
- end
- else // Store to CPU register.
- begin
- // Generate register read command.
- o_reg_en <= 1'd1;
- o_reg_rd_index <= translate(i_cp_word[15:12], i_cpsr[4:0]);
- o_reg_wr_index <= 16;
- state <= READ_DLY;
- end
- end
- endcase
- end
- endcase
-
- // Default assignments. These bits are unchangeable.
- generate_r0;
-
- r[1][1] <= 1'd1;
- r[1][3] <= 1'd1; // Write buffer always enabled.
- r[1][6:4] <= 3'b111; // 0 = Little Endian, 0 = 0, 1 = 32-bit address range,
- // 1 = 32-bit handlers enabled.
- r[1][11] <= 1'd1;
- end
-end
-
-// CPU info register.
-task generate_r0;
-begin
- r[0][3:0] <= 4'd0;
- r[0][15:4] <= 12'hAAA;
- r[0][19:16] <= 4'h4;
- r[0][23:20] <= 4'd0;
- r[0][31:24] <= 8'd0;
-end
-endtask
-
-wire [31:0] r0 = r[0];
-wire [31:0] r1 = r[1];
-wire [31:0] r2 = r[2];
-wire [31:0] r3 = r[3];
-wire [31:0] r4 = r[4];
-wire [31:0] r5 = r[5];
-wire [31:0] r6 = r[6];
-
-endmodule
-
-`default_nettype wire
-
-// ----------------------------------------------------------------------------
-// EOF
-// ----------------------------------------------------------------------------
Index: zap/trunk/src/rtl/cpu/zap_tlb_check.v
===================================================================
--- zap/trunk/src/rtl/cpu/zap_tlb_check.v (revision 57)
+++ zap/trunk/src/rtl/cpu/zap_tlb_check.v (nonexistent)
@@ -1,262 +0,0 @@
-// -----------------------------------------------------------------------------
-// -- --
-// -- (C) 2016-2018 Revanth Kamaraj. --
-// -- --
-// -- --------------------------------------------------------------------------
-// -- --
-// -- This program is free software; you can redistribute it and/or --
-// -- modify it under the terms of the GNU General Public License --
-// -- as published by the Free Software Foundation; either version 2 --
-// -- of the License, or (at your option) any later version. --
-// -- --
-// -- This program 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 General Public License for more details. --
-// -- --
-// -- You should have received a copy of the GNU General Public License --
-// -- along with this program; if not, write to the Free Software --
-// -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA --
-// -- 02110-1301, USA. --
-// -- --
-// -----------------------------------------------------------------------------
-// -- --
-// -- Examines TLB entries to authorize access. Purely combo logic. --
-// -- --
-// -----------------------------------------------------------------------------
-
-`default_nettype none
-
-module zap_tlb_check ( // ZAP TLB Processing Logic.
-
-i_mmu_en, // MMU enable.
-
-// Dynamics
-i_va, // Virtual address.
-i_rd, // WB rd.
-i_wr, // WB wr.
-
-// Static almost.
-i_cpsr,
-i_sr,
-i_dac_reg,
-
-// Data from TLB dist RAMs.
-i_sptlb_rdata, i_sptlb_rdav,
-i_lptlb_rdata, i_lptlb_rdav,
-i_setlb_rdata, i_setlb_rdav,
-
-// Outputs to other units.
-o_walk, // Need to page walk.
-o_fsr, // FSR.
-o_far, // FAR. 0 means no fault. This is a 4-bit number.
-o_cacheable, // Cacheable based on PTE.
-o_phy_addr // Physical address.
-
-);
-
-// Pass this from top.
-parameter LPAGE_TLB_ENTRIES = 8;
-parameter SPAGE_TLB_ENTRIES = 8;
-parameter SECTION_TLB_ENTRIES = 8;
-
-`include "zap_localparams.vh"
-`include "zap_defines.vh"
-`include "zap_functions.vh"
-
-input wire i_mmu_en; // MMU enable.
-
-input wire [31:0] i_va; // Virtual address.
-input wire i_rd; // Read request.
-input wire i_wr; // Write request.
-
-input wire [31:0] i_cpsr; // CPSR.
-input wire [1:0] i_sr; // Status Register.
-input wire [31:0] i_dac_reg; // Domain Access Control Register.
-
-input wire [`SPAGE_TLB_WDT -1:0] i_sptlb_rdata; // Small page TLB.
-input wire i_sptlb_rdav; // TLB entry valid.
-
-input wire [`LPAGE_TLB_WDT -1:0] i_lptlb_rdata; // Large page TLB read data.
-input wire i_lptlb_rdav; // Large page TLB valid.
-
-input wire [`SECTION_TLB_WDT-1:0] i_setlb_rdata; // Small page TLB read data.
-input wire i_setlb_rdav; // Small page TLB valid.
-
-output reg o_walk; // Signal page walk.
-output reg [7:0] o_fsr; // FSR. 0 means all OK.
-output reg [31:0] o_far; // Fault Address Register.
-output reg o_cacheable; // Cacheble stats of the PTE.
-output reg [31:0] o_phy_addr; // Physical address.
-
-// ----------------------------------------------------------------------------
-
-always @*
-begin
- // Default values. Taken for MMU disabled esp.
- o_fsr = 0; // No fault.
- o_far = i_va; // Fault address.
- o_phy_addr = i_va; // VA = PA
- o_walk = 0; // Walk disabled.
- o_cacheable = 0; // Uncacheable.
-
- if ( i_mmu_en && (i_rd|i_wr) ) // MMU enabled.
- begin
- if ( (i_sptlb_rdata[`SPAGE_TLB__TAG] == i_va[`VA__SPAGE_TAG]) && i_sptlb_rdav )
- begin
- // Entry found in small page TLB.
- o_fsr = get_fsr
- (
- 1'd0, 1'd1, 1'd0, // Small page.
- i_va[`VA__SPAGE_AP_SEL],
- i_cpsr[4:0] == USR,
- i_rd,
- i_wr,
- i_sr,
- i_dac_reg,
- i_sptlb_rdata
- ) ;
-
- o_phy_addr = {i_sptlb_rdata[`SPAGE_TLB__BASE],
- i_va[11:0]};
-
- o_cacheable = i_sptlb_rdata[`SECTION_TLB__CB] >> 1;
-
- end
- else if ( (i_lptlb_rdata[`LPAGE_TLB__TAG] == i_va[`VA__LPAGE_TAG]) && i_lptlb_rdav )
- begin
- // Entry found in large page TLB.
- o_fsr = get_fsr
- (
- 1'd0, 1'd0, 1'd1, // Large page.
- i_va[`VA__LPAGE_AP_SEL],
- i_cpsr[4:0] == USR,
- i_rd,
- i_wr,
- i_sr,
- i_dac_reg,
- i_lptlb_rdata
- ) ;
-
- o_phy_addr = {i_lptlb_rdata[`LPAGE_TLB__BASE],
- i_va[15:0]};
-
- o_cacheable = i_lptlb_rdata[`LPAGE_TLB__CB] >> 1;
- end
- else if ( (i_setlb_rdata[`SECTION_TLB__TAG] == i_va[`VA__SECTION_TAG]) && i_setlb_rdav )
- begin
- // Entry found in section TLB.
- o_fsr = get_fsr
- (
- 1'd1, 1'd0, 1'd0, // Section.
- 2'd0, // DONT CARE. Sections do not further divisions in AP SEL.
- i_cpsr[4:0] == USR,
- i_rd,
- i_wr,
- i_sr,
- i_dac_reg,
- i_setlb_rdata
- ) ;
-
- o_phy_addr = {i_setlb_rdata[`SECTION_TLB__BASE],
- i_va[19:0]};
-
- o_cacheable = i_setlb_rdata[`SECTION_TLB__CB] >> 1;
- end
- else
- begin
- // Trigger TLB walk.
- o_walk = 1'd1;
- end
- end // Else MMU disabled.
-end
-
-// ----------------------------------------------------------------------------
-
-function [7:0] get_fsr ( // Return 0 means OK to access else is a valid FSR.
-input section, spage, lpage, // Select one.
-input [1:0] ap_sel, // AP sel bits. dont care for sections.
-input user, rd, wr, // Access properties.
-input [1:0] sr, // S and R bits.
-input [31:0] dac_reg, // DAC register.
-input [63:0] tlb // TLB entry.
-);
-
-reg [3:0] apsr; // Concat of AP and SR.
-reg [1:0] dac; // DAC bits.
-
-begin
- if ( section )
- begin
- apsr = (tlb [ `SECTION_TLB__AP ]) >> (section ? 0 : (ap_sel << 1));
- dac = (dac_reg >> (tlb [ `SECTION_TLB__DAC_SEL ] << 1));
- end
- else if ( spage )
- begin
- apsr = (tlb [ `SPAGE_TLB__AP ]) >> (section ? 0 : (ap_sel << 1));
- dac = (dac_reg >> (tlb [ `SPAGE_TLB__DAC_SEL ] << 1));
- end
- else // large page.
- begin
- apsr = (tlb [ `LPAGE_TLB__AP ]) >> (section ? 0 : (ap_sel << 1));
- dac = (dac_reg >> (tlb [ `LPAGE_TLB__DAC_SEL ] << 1));
- end
-
- case(dac)
- DAC_MANAGER: get_fsr = 0; // No fault.
-
- DAC_CLIENT : get_fsr = is_apsr_ok ( user, rd, wr, apsr ) ? 0 :
- (
- section ? {tlb[`SECTION_TLB__DAC_SEL], FSR_SECTION_PERMISSION_FAULT}:
- spage ? {tlb[`SPAGE_TLB__DAC_SEL] , FSR_PAGE_PERMISSION_FAULT }:
- {tlb[`LPAGE_TLB__DAC_SEL] , FSR_PAGE_PERMISSION_FAULT }
- );
-
- default : get_fsr =
- section ? {tlb[`SECTION_TLB__DAC_SEL], FSR_SECTION_DOMAIN_FAULT} :
- spage ? {tlb[`SPAGE_TLB__DAC_SEL], FSR_PAGE_DOMAIN_FAULT } :
- {tlb[`LPAGE_TLB__DAC_SEL], FSR_PAGE_DOMAIN_FAULT } ;
- endcase
-end
-
-endfunction
-
-// ----------------------------------------------------------------------------
-
-//
-// Function to check APSR bits.
-//
-// Returns 0 for failure, 1 for okay.
-// Checks AP and SR bits.
-//
-
-localparam APSR_BAD = 1'd0;
-localparam APSR_OK = 1'd1;
-
-function is_apsr_ok ( input user, input rd, input wr, input [3:0] apsr);
-reg x;
-begin
- x = APSR_BAD; // Assume fail.
-
- casez (apsr)
- APSR_NA_NA: x = APSR_BAD; // No access.
- APSR_RO_RO: x = !wr; // Reads allowed for all.
- APSR_RO_NA: x = !user && rd; // Only kernel reads.
- APSR_RW_NA: x = !user; // Only kernel access.
- APSR_RW_RO: x = !user | (user && rd); // User RO, Kernel RW.
- APSR_RW_RW: x = APSR_OK; // Grant all the time.
- default : x = APSR_BAD; // Deny all the time.
- endcase
-
- // Assign to function. Return.
- is_apsr_ok = x;
-end
-endfunction
-
-endmodule // zap_tlb_check.v
-
-`default_nettype wire
-
-// ----------------------------------------------------------------------------
-// EOF
-// ----------------------------------------------------------------------------
Index: zap/trunk/src/rtl/cpu/zap_fifo.v
===================================================================
--- zap/trunk/src/rtl/cpu/zap_fifo.v (revision 57)
+++ zap/trunk/src/rtl/cpu/zap_fifo.v (nonexistent)
@@ -1,109 +0,0 @@
-// -----------------------------------------------------------------------------
-// -- --
-// -- (C) 2016-2018 Revanth Kamaraj. --
-// -- --
-// -- --------------------------------------------------------------------------
-// -- --
-// -- This program is free software; you can redistribute it and/or --
-// -- modify it under the terms of the GNU General Public License --
-// -- as published by the Free Software Foundation; either version 2 --
-// -- of the License, or (at your option) any later version. --
-// -- --
-// -- This program 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 General Public License for more details. --
-// -- --
-// -- You should have received a copy of the GNU General Public License --
-// -- along with this program; if not, write to the Free Software --
-// -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA --
-// -- 02110-1301, USA. --
-// -- --
-// -----------------------------------------------------------------------------
-
-`default_nettype none
-
-module zap_fifo #(parameter WDT = 32, DEPTH = 8) (
-
-input wire i_clk,
-input wire i_reset,
-
-input wire i_write_inhibit,
-
-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,
-
-input wire [WDT-1:0] i_instr, // Instruction + other bits.
-input wire i_valid, // Above is valid. Write enable basically.
-
-output reg [WDT-1:0] o_instr, // Instruction output.
-output reg o_valid, // Output valid.
-
-output wire o_wb_stb, o_wb_cyc, o_wb_stb_nxt // Wishbone request.
-);
-
-reg clear, rd_en;
-wire [WDT-1:0] instr;
-wire valid;
-
-assign o_wb_cyc = o_wb_stb;
-
-always @*
-begin
- if ( i_clear_from_writeback) clear = 1'd1;
- else if ( i_data_stall ) clear = 1'd0;
- else if ( i_clear_from_alu ) clear = 1'd1;
- else if ( i_stall_from_shifter ) clear = 1'd0;
- else if ( i_stall_from_issue ) clear = 1'd0;
- else if ( i_stall_from_decode ) clear = 1'd0;
- else if ( i_clear_from_decode ) clear = 1'd1;
- else clear = 1'd0;
-end
-
-always @*
-begin
- if ( i_clear_from_writeback) rd_en = 1'd0;
- else if ( i_data_stall ) rd_en = 1'd0;
- else if ( i_clear_from_alu ) rd_en = 1'd0;
- else if ( i_stall_from_shifter ) rd_en = 1'd0;
- else if ( i_stall_from_issue ) rd_en = 1'd0;
- else if ( i_stall_from_decode ) rd_en = 1'd0;
- else if ( i_clear_from_decode ) rd_en = 1'd0;
- else rd_en = 1'd1;
-end
-
-zap_sync_fifo #(.WIDTH(WDT), .DEPTH(DEPTH), .FWFT(1)) USF (
- .i_clk (i_clk),
- .i_reset (i_reset || clear),
- .i_ack ( rd_en ),
- .i_wr_en ( i_valid && !i_write_inhibit ),
- .i_data (i_instr),
- .o_data (instr),
- .o_empty_n (valid),
- .o_full_n (o_wb_stb),
- .o_full_n_nxt (o_wb_stb_nxt),
- .o_empty (),
- .o_full ()
-);
-
-// Pipeline register.
-always @ (posedge i_clk)
-begin
- if ( i_reset || clear )
- begin
- o_valid <= 1'd0;
- end
- else if ( rd_en )
- begin
- o_valid <= valid;
- o_instr <= instr;
- end
-end
-
-endmodule
-`default_nettype wire
Index: zap/trunk/src/rtl/cpu/zap_register_file.v
===================================================================
--- zap/trunk/src/rtl/cpu/zap_register_file.v (revision 57)
+++ zap/trunk/src/rtl/cpu/zap_register_file.v (nonexistent)
@@ -1,150 +0,0 @@
-// -----------------------------------------------------------------------------
-// -- --
-// -- (C) 2016-2018 Revanth Kamaraj. --
-// -- --
-// -- --------------------------------------------------------------------------
-// -- --
-// -- This program is free software; you can redistribute it and/or --
-// -- modify it under the terms of the GNU General Public License --
-// -- as published by the Free Software Foundation; either version 2 --
-// -- of the License, or (at your option) any later version. --
-// -- --
-// -- This program 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 General Public License for more details. --
-// -- --
-// -- You should have received a copy of the GNU General Public License --
-// -- along with this program; if not, write to the Free Software --
-// -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA --
-// -- 02110-1301, USA. --
-// -- --
-// -----------------------------------------------------------------------------
-// -- --
-// -- ZAP register file implemented using flip-flops which makes sense for an--
-// -- FPGA implementation where flip-flops are plentiful. --
-// -- --
-// -----------------------------------------------------------------------------
-
-`default_nettype none
-
-module zap_register_file
-(
- input wire i_clk,
-
- input wire i_reset,
-
- input wire i_wen,
-
- input wire [5:0] i_wr_addr_a,
- i_wr_addr_b, // 2 write addresses.
-
- input wire [31:0] i_wr_data_a,
- i_wr_data_b, // 2 write data.
-
- input wire [5:0] i_rd_addr_a,
- i_rd_addr_b,
- i_rd_addr_c,
- i_rd_addr_d,
-
- output reg [31:0] o_rd_data_a,
- o_rd_data_b,
- o_rd_data_c,
- o_rd_data_d
-);
-
-// Dual distributed RAM setup.
-reg [31:0] mem [39:0];
-reg [31:0] MEM [39:0];
-
-initial
-begin: blk1
- integer i;
-
- for(i=0;i<40;i=i+1)
- begin
- mem[i] = 0;
- MEM[i] = 0;
- end
-end
-
-reg [39:0] sel;
-
-wire [31:0] r0; assign r0 = sel[0] ? MEM[0] : mem[0];
-wire [31:0] r1; assign r1 = sel[1] ? MEM[1] : mem[1];
-wire [31:0] r2; assign r2 = sel[2] ? MEM[2] : mem[2];
-wire [31:0] r3; assign r3 = sel[3] ? MEM[3] : mem[3];
-wire [31:0] r4; assign r4 = sel[4] ? MEM[4] : mem[4];
-wire [31:0] r5; assign r5 = sel[5] ? MEM[5] : mem[5];
-wire [31:0] r6; assign r6 = sel[6] ? MEM[6] : mem[6];
-wire [31:0] r7; assign r7 = sel[7] ? MEM[7] : mem[7];
-wire [31:0] r8; assign r8 = sel[8] ? MEM[8] : mem[8];
-wire [31:0] r9; assign r9 = sel[9] ? MEM[9] : mem[9];
-wire [31:0] r10; assign r10 = sel[10] ? MEM[10] : mem[10];
-wire [31:0] r11; assign r11 = sel[11] ? MEM[11] : mem[11];
-wire [31:0] r12; assign r12 = sel[12] ? MEM[12] : mem[12];
-wire [31:0] r13; assign r13 = sel[13] ? MEM[13] : mem[13];
-wire [31:0] r14; assign r14 = sel[14] ? MEM[14] : mem[14];
-wire [31:0] r15; assign r15 = sel[15] ? MEM[15] : mem[15];
-wire [31:0] r16; assign r16 = sel[16] ? MEM[16] : mem[16];
-wire [31:0] r17; assign r17 = sel[17] ? MEM[17] : mem[17];
-wire [31:0] r18; assign r18 = sel[18] ? MEM[18] : mem[18];
-wire [31:0] r19; assign r19 = sel[19] ? MEM[19] : mem[19];
-wire [31:0] r20; assign r20 = sel[20] ? MEM[20] : mem[20];
-wire [31:0] r21; assign r21 = sel[21] ? MEM[21] : mem[21];
-wire [31:0] r22; assign r22 = sel[22] ? MEM[22] : mem[22];
-wire [31:0] r23; assign r23 = sel[23] ? MEM[23] : mem[23];
-wire [31:0] r24; assign r24 = sel[24] ? MEM[24] : mem[24];
-wire [31:0] r25; assign r25 = sel[25] ? MEM[25] : mem[25];
-wire [31:0] r26; assign r26 = sel[26] ? MEM[26] : mem[26];
-wire [31:0] r27; assign r27 = sel[27] ? MEM[27] : mem[27];
-wire [31:0] r28; assign r28 = sel[28] ? MEM[28] : mem[28];
-wire [31:0] r29; assign r29 = sel[29] ? MEM[29] : mem[29];
-wire [31:0] r30; assign r30 = sel[30] ? MEM[30] : mem[30];
-wire [31:0] r31; assign r31 = sel[31] ? MEM[31] : mem[31];
-wire [31:0] r32; assign r32 = sel[32] ? MEM[32] : mem[32];
-wire [31:0] r33; assign r33 = sel[33] ? MEM[33] : mem[33];
-wire [31:0] r34; assign r34 = sel[34] ? MEM[34] : mem[34];
-wire [31:0] r35; assign r35 = sel[35] ? MEM[35] : mem[35];
-wire [31:0] r36; assign r36 = sel[36] ? MEM[36] : mem[36];
-wire [31:0] r37; assign r37 = sel[37] ? MEM[37] : mem[37];
-wire [31:0] r38; assign r38 = sel[38] ? MEM[38] : mem[38];
-wire [31:0] r39; assign r39 = sel[39] ? MEM[39] : mem[39];
-
-always @ (posedge i_clk)
-begin
- if ( i_reset )
- begin
- sel <= 40'd0;
- end
- else
- begin
- sel [ i_wr_addr_a ] <= 1'd0;
- sel [ i_wr_addr_b ] <= 1'd1;
- end
-end
-
-always @ (posedge i_clk)
-begin
- if ( i_wen )
- begin
- mem [ i_wr_addr_a ] <= i_wr_data_a;
- MEM [ i_wr_addr_b ] <= i_wr_data_b;
- end
-end
-
-always @*
-begin
- o_rd_data_a = sel[i_rd_addr_a] ? MEM [ i_rd_addr_a ] : mem [ i_rd_addr_a ];
- o_rd_data_b = sel[i_rd_addr_b] ? MEM [ i_rd_addr_b ] : mem [ i_rd_addr_b ];
- o_rd_data_c = sel[i_rd_addr_c] ? MEM [ i_rd_addr_c ] : mem [ i_rd_addr_c ];
- o_rd_data_d = sel[i_rd_addr_d] ? MEM [ i_rd_addr_d ] : mem [ i_rd_addr_d ];
-end
-
-endmodule // bram_wrapper.v
-
-`default_nettype wire
-
-// ----------------------------------------------------------------------------
-// EOF
-// ----------------------------------------------------------------------------
Index: zap/trunk/src/rtl/cpu/zap_defines.vh
===================================================================
--- zap/trunk/src/rtl/cpu/zap_defines.vh (revision 57)
+++ zap/trunk/src/rtl/cpu/zap_defines.vh (nonexistent)
@@ -1,133 +0,0 @@
-// -----------------------------------------------------------------------------
-// -- --
-// -- (C) 2016-2018 Revanth Kamaraj. --
-// -- --
-// -- --------------------------------------------------------------------------
-// -- --
-// -- This program is free software; you can redistribute it and/or --
-// -- modify it under the terms of the GNU General Public License --
-// -- as published by the Free Software Foundation; either version 2 --
-// -- of the License, or (at your option) any later version. --
-// -- --
-// -- This program 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 General Public License for more details. --
-// -- --
-// -- You should have received a copy of the GNU General Public License --
-// -- along with this program; if not, write to the Free Software --
-// -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA --
-// -- 02110-1301, USA. --
-// -- --
-// -----------------------------------------------------------------------------
-
-`ifndef _ZAP_DEFINES_VH_
-`define _ZAP_DEFINES_VH_
-
-`define CPSR_MODE 4:0
-
-`define BASE_EXTEND 33 // Base address register for MEMOPS.
-`define BASE 19:16 // Base address extend.
-
-`define SRCDEST_EXTEND 32 // Data Src/Dest extend register for MEMOPS.
-`define SRCDEST 15:12 // Data src/dest register MEMOPS.
-
-`define DP_RD_EXTEND 33 // Destination source extend.
-`define DP_RD 15:12 // Destination source.
-
-`define DP_RB_EXTEND 32 // Shift source extend.
-`define DP_RB 3:0 // Shift source. ARM refers to this as rm.
-
-`define DP_RA 19:16 // ALU source. ARM rn.
-`define DP_RA_EXTEND 34 // ALU source extend. ARM rn.
-
-`define OPCODE_EXTEND 35 // To differentiate lower and higher ->
- // 1 means higher, 0 lower.
-
-// Instruction fields in CP15 instruction.
-`define opcode_2 7:5
-`define crm 3:0
-`define crn 19:16
-`define cp_id 11:8
-
-// ----------------------------------------------------------------------------
-
-// Generic defines.
-`define ID 1:0 // Determine type of descriptor.
-
-// Virtual Address Breakup
-`define VA__TABLE_INDEX 31:20
-`define VA__L2_TABLE_INDEX 19:12
-`define VA__4K_PAGE_INDEX 11:0
-`define VA__64K_PAGE_INDEX 15:0
-`define VA__1M_SECTION_INDEX 19:0
-
-`define VA__TRANSLATION_BASE 31:14
-
-`define VA__CACHE_INDEX 4+$clog2(CACHE_SIZE/16)-1:4
-`define VA__SECTION_INDEX 20+$clog2(SECTION_TLB_ENTRIES)-1:20
-`define VA__LPAGE_INDEX 16+$clog2(LPAGE_TLB_ENTRIES)-1:16
-`define VA__SPAGE_INDEX 12+$clog2(SPAGE_TLB_ENTRIES)-1:12
-
-`define VA__CACHE_TAG 31:4+$clog2(CACHE_SIZE/16)
-
-`define VA__SPAGE_TAG 31:12+$clog2(SPAGE_TLB_ENTRIES)
-`define VA__LPAGE_TAG 31:16+$clog2(LPAGE_TLB_ENTRIES)
-`define VA__SECTION_TAG 31:20+$clog2(SECTION_TLB_ENTRIES)
-
-`define VA__SPAGE_AP_SEL 11:10
-`define VA__LPAGE_AP_SEL 15:14
-
-// L1 Section Descriptior Breakup
-`define L1_SECTION__BASE 31:20
-`define L1_SECTION__DAC_SEL 8:5
-`define L1_SECTION__AP 11:10
-`define L1_SECTION__CB 3:2
-
-// L1 Page Descriptor Breakup
-`define L1_PAGE__PTBR 31:10
-`define L1_PAGE__DAC_SEL 8:5
-
-// L2 Page Descriptor Breakup
-`define L2_SPAGE__BASE 31:12
-`define L2_SPAGE__AP 11:4
-`define L2_SPAGE__CB 3:2
-
-`define L2_LPAGE__BASE 31:16
-`define L2_LPAGE__AP 11:4
-`define L2_LPAGE__CB 3:2
-
-// Section TLB Structure - 1:0 is undefined.
-`define SECTION_TLB__BASE 31:20
-`define SECTION_TLB__DAC_SEL 8:5
-`define SECTION_TLB__AP 11:10
-`define SECTION_TLB__CB 3:2
-`define SECTION_TLB__TAG 32+(32-$clog2(SECTION_TLB_ENTRIES)-20)-1:32
-
-// Lpage TLB Structure - 1:0 is undefined
-`define LPAGE_TLB__BASE 31:16
-`define LPAGE_TLB__DAC_SEL 15:12 // Squeezed in blank space.
-`define LPAGE_TLB__AP 11:4
-`define LPAGE_TLB__CB 3:2
-`define LPAGE_TLB__TAG 32+(32-$clog2(LPAGE_TLB_ENTRIES)-16)-1:32
-
-// Spage TLB Structure - 1:0 is undefined
-`define SPAGE_TLB__BASE 31:12
-`define SPAGE_TLB__AP 11:4
-`define SPAGE_TLB__CB 3:2
-`define SPAGE_TLB__DAC_SEL 35:32
-`define SPAGE_TLB__TAG 36+(32-$clog2(SPAGE_TLB_ENTRIES)-12)-1:36
-
-// Cache tag width. Tag consists of the tag and the physical address. valid and dirty are stored as flops.
-`define CACHE_TAG__TAG (31 - 4 - $clog2(CACHE_SIZE/16) + 1) -1 : 0
-`define CACHE_TAG__PA 27 + (31 - 4 - $clog2(CACHE_SIZE/16) + 1) : 31 - 4 - $clog2(CACHE_SIZE/16) + 1
-`define CACHE_TAG_WDT 27 + (31 - 4 - $clog2(CACHE_SIZE/16) + 1) + 1
-
-// TLB widths.
-`define SECTION_TLB_WDT (32 + (32-$clog2(SECTION_TLB_ENTRIES)-20))
-`define LPAGE_TLB_WDT (32 + (32-$clog2(LPAGE_TLB_ENTRIES)-16))
-`define SPAGE_TLB_WDT (36 + (32-$clog2(SPAGE_TLB_ENTRIES)-12))
-
-// ----------------------------------------------------------------------------
-
-`endif
Index: zap/trunk/src/rtl/cpu/zap_tlb_fsm.v
===================================================================
--- zap/trunk/src/rtl/cpu/zap_tlb_fsm.v (revision 57)
+++ zap/trunk/src/rtl/cpu/zap_tlb_fsm.v (nonexistent)
@@ -1,418 +0,0 @@
-// -----------------------------------------------------------------------------
-// -- --
-// -- (C) 2016-2018 Revanth Kamaraj. --
-// -- --
-// -- --------------------------------------------------------------------------
-// -- --
-// -- This program is free software; you can redistribute it and/or --
-// -- modify it under the terms of the GNU General Public License --
-// -- as published by the Free Software Foundation; either version 2 --
-// -- of the License, or (at your option) any later version. --
-// -- --
-// -- This program 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 General Public License for more details. --
-// -- --
-// -- You should have received a copy of the GNU General Public License --
-// -- along with this program; if not, write to the Free Software --
-// -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA --
-// -- 02110-1301, USA. --
-// -- --
-// -----------------------------------------------------------------------------
-// -- --
-// -- An automatic page fetching system. --
-// -- --
-// -----------------------------------------------------------------------------
-
-`default_nettype none
-
-`include "zap_defines.vh"
-
-module zap_tlb_fsm #(
-
-// Pass from top.
-parameter LPAGE_TLB_ENTRIES = 8,
-parameter SPAGE_TLB_ENTRIES = 8,
-parameter SECTION_TLB_ENTRIES = 8
-
-)(
-
-/* Clock and Reset */
-input wire i_clk,
-input wire i_reset,
-
-/* From CP15 */
-input wire i_mmu_en,
-input wire [31:0] i_baddr,
-
-/* From cache FSM */
-input wire [31:0] i_address,
-
-/* From TLB check unit */
-input wire i_walk,
-input wire [7:0] i_fsr,
-input wire [31:0] i_far,
-input wire i_cacheable,
-input wire [31:0] i_phy_addr,
-
-/* To main cache FSM */
-output reg [7:0] o_fsr,
-output reg [31:0] o_far,
-output reg o_fault,
-output reg [31:0] o_phy_addr,
-output reg o_cacheable,
-output reg o_busy,
-
-/* To TLBs */
-output reg [`SECTION_TLB_WDT-1:0] o_setlb_wdata,
-output reg o_setlb_wen,
-output reg [`SPAGE_TLB_WDT-1:0] o_sptlb_wdata,
-output reg o_sptlb_wen,
-output reg [`LPAGE_TLB_WDT-1:0] o_lptlb_wdata,
-output reg o_lptlb_wen,
-
-/* Wishbone signals NXT */
-output wire o_wb_cyc_nxt,
-output wire o_wb_stb_nxt,
-output wire [31:0] o_wb_adr_nxt,
-
-/* Wishbone Signals */
-output wire o_wb_cyc,
-output wire o_wb_stb,
-output wire o_wb_wen,
-output wire [3:0] o_wb_sel, o_wb_sel_nxt,
-output wire [31:0] o_wb_adr,
-input wire [31:0] i_wb_dat,
-input wire i_wb_ack,
-
-// Unused.
-output wire o_unused_ok
-
-);
-
-`include "zap_localparams.vh"
-`include "zap_defines.vh"
-`include "zap_functions.vh"
-
-// ----------------------------------------------------------------------------
-
-/* States */
-localparam IDLE = 0; /* Idle State */
-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;
-
-// ----------------------------------------------------------------------------
-
-reg [3:0] dac_ff, dac_nxt; /* Scratchpad register */
-reg [$clog2(NUMBER_OF_STATES)-1:0] state_ff, state_nxt; /* State register */
-
-/* Wishbone related */
-reg wb_stb_nxt, wb_stb_ff;
-reg wb_cyc_nxt, wb_cyc_ff;
-reg [31:0] wb_adr_nxt, wb_adr_ff;
-
-// ----------------------------------------------------------------------------
-
-/* Tie output flops to ports. */
-assign o_wb_cyc = wb_cyc_ff;
-assign o_wb_stb = wb_stb_ff;
-assign o_wb_adr = wb_adr_ff;
-
-assign o_wb_cyc_nxt = wb_cyc_nxt;
-assign o_wb_stb_nxt = wb_stb_nxt;
-assign o_wb_adr_nxt = wb_adr_nxt;
-
-reg [3:0] wb_sel_nxt, wb_sel_ff;
-
-/* Tied PORTS */
-assign o_wb_wen = 1'd0;
-assign o_wb_sel = wb_sel_ff;
-assign o_wb_sel_nxt = wb_sel_nxt;
-
-assign o_unused_ok = 0 || i_baddr[13:0];
-
-reg [31:0] dff, dnxt; /* Wishbone memory buffer. */
-
-/* Combinational logic */
-always @*
-begin: blk1
-
- o_fsr = 0;
- o_far = 0;
- o_fault = 0;
- o_busy = 0;
- o_phy_addr = i_phy_addr;
- o_cacheable = i_cacheable;
- o_setlb_wen = 0;
- o_lptlb_wen = 0;
- o_sptlb_wen = 0;
- o_setlb_wdata = 0;
- o_sptlb_wdata = 0;
- o_lptlb_wdata = 0;
-
- /* Kill wishbone access unless overridden */
- wb_stb_nxt = 0;
- wb_cyc_nxt = 0;
- wb_adr_nxt = 0;
- wb_sel_nxt = 0;
-
- dac_nxt = dac_ff;
- state_nxt = state_ff;
-
- dnxt = dff;
-
- case ( state_ff )
- IDLE:
- begin
- if ( i_mmu_en )
- begin
- if ( i_walk )
- begin
- o_busy = 1'd1;
-
- /*
- * We need to page walk to get the page table.
- * Call for access to L1 level page table.
- */
- tsk_prpr_wb_rd({i_baddr[`VA__TRANSLATION_BASE],
- i_address[`VA__TABLE_INDEX], 2'd0});
-
- state_nxt = FETCH_L1_DESC_0;
- end
- else if ( i_fsr[3:0] != 4'b0000 ) /* Access Violation. */
- begin
- o_fault = 1'd1;
- o_busy = 1'd0;
- o_fsr = i_fsr;
- o_far = i_far;
- end
- 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
- /*
- * What we would have fetched is the L1 descriptor.
- * Examine it. dff holds the L1 descriptor.
- */
-
- o_busy = 1'd1;
-
- if ( 1 )
- begin
- case ( dff[`ID] )
-
- SECTION_ID:
- begin
- /*
- * It is a section itself so there is no need
- * for another fetch. Simply reload the TLB
- * and we are good.
- */
- o_setlb_wen = 1'd1;
- o_setlb_wdata = {i_address[`VA__SECTION_TAG],
- dff};
- state_nxt = REFRESH_CYCLE;
-
- $display($time, " - %m :: #########################################################");
- $display($time, " - %m :: SECTION DESCRIPTOR DETAILS #");
- $display($time, " - %m :: #########################################################");
- $display($time, " - %m :: # BASE ADDRESS = 0x%x ", o_setlb_wdata[`SECTION_TLB__BASE]);
- $display($time, " - %m :: # DAC = 0b%b", o_setlb_wdata[`SECTION_TLB__DAC_SEL]);
- $display($time, " - %m :: # AP bits = 0b%b", o_setlb_wdata[`SECTION_TLB__AP]);
- $display($time, " - %m :: # Cacheable = 0b%b", o_setlb_wdata[`SECTION_TLB__CB] >> 1);
- $display($time, " - %m :: # Bufferable = 0b%b", o_setlb_wdata[`SECTION_TLB__CB] & 2'b01);
- $display($time, " - %m :: #########################################################");
- end
-
- PAGE_ID:
- begin
- /*
- * Page ID requires that DAC from current
- * descriptor is remembered because when we
- * reload the TLB, it would be useful. Anyway,
- * we need to initiate another access.
- */
- dac_nxt = dff[`L1_PAGE__DAC_SEL]; // dac register holds the dac sel for future use.
- state_nxt = FETCH_L2_DESC_0;
-
- tsk_prpr_wb_rd({dff[`L1_PAGE__PTBR],
- i_address[`VA__L2_TABLE_INDEX], 2'd0});
- end
-
- default: /* Generate section translation fault. Fault Class II */
- begin
- o_fsr = FSR_SECTION_TRANSLATION_FAULT;
- o_fsr = {dff[`L1_SECTION__DAC_SEL], o_fsr[3:0]};
- o_far = i_address;
- o_fault = 1'd1;
- o_busy = 1'd0;
- state_nxt = IDLE;
- end
-
- endcase
- end
- 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
- begin
- tsk_hold_wb_access;
- end
- end
-
- FETCH_L2_DESC:
- begin
- o_busy = 1'd1;
-
- if ( 1 )
- begin
- case ( dff[`ID] ) // dff holds L2 descriptor. dac_ff holds L1 descriptor DAC.
- SPAGE_ID:
- begin
- /* Update TLB */
- o_sptlb_wen = 1'd1;
-
- /* Define TLB fields to write */
- o_sptlb_wdata[`SPAGE_TLB__TAG] = i_address[`VA__SPAGE_TAG];
- o_sptlb_wdata[`SPAGE_TLB__DAC_SEL] = dac_ff; /* DAC selector from L1. */
- o_sptlb_wdata[`SPAGE_TLB__AP] = dff[`L2_SPAGE__AP];
- o_sptlb_wdata[`SPAGE_TLB__CB] = dff[`L2_SPAGE__CB];
- o_sptlb_wdata[`SPAGE_TLB__BASE] = dff[`L2_SPAGE__BASE];
-
- $display($time, " - %m :: #########################################################");
- $display($time, " - %m :: SPAGE DESCRIPTOR DETAILS #");
- $display($time, " - %m :: #########################################################");
- $display($time, " - %m :: # BASE ADDRESS = 0x%x ", o_sptlb_wdata[`SPAGE_TLB__BASE]);
- $display($time, " - %m :: # DAC = 0b%b", o_sptlb_wdata[`SPAGE_TLB__DAC_SEL]);
- $display($time, " - %m :: # AP bits = 0b%b", o_sptlb_wdata[`SPAGE_TLB__AP]);
- $display($time, " - %m :: # Cacheable = 0b%b", o_sptlb_wdata[`SPAGE_TLB__CB] >> 1);
- $display($time, " - %m :: # Bufferable = 0b%b", o_sptlb_wdata[`SPAGE_TLB__CB] & 2'b01);
- $display($time, " - %m :: #########################################################");
-
- /* Go to REFRESH */
- state_nxt = REFRESH_CYCLE;
- end
-
- LPAGE_ID:
- begin
- /* Update TLB */
- o_lptlb_wen = 1'd1;
-
- /* DAC is inserted in between to save bits */
- o_lptlb_wdata = {i_address[`VA__LPAGE_TAG], dac_ff, dff};
-
- $display($time, " - %m :: #########################################################");
- $display($time, " - %m :: LPAGE DESCRIPTOR DETAILS #");
- $display($time, " - %m :: #########################################################");
- $display($time, " - %m :: # BASE ADDRESS = 0x%x ", o_lptlb_wdata[`LPAGE_TLB__BASE]);
- $display($time, " - %m :: # DAC = 0b%b", o_lptlb_wdata[`LPAGE_TLB__DAC_SEL]);
- $display($time, " - %m :: # AP bits = 0b%b", o_lptlb_wdata[`LPAGE_TLB__AP]);
- $display($time, " - %m :: # Cacheable = 0b%b", o_lptlb_wdata[`LPAGE_TLB__CB] >> 1);
- $display($time, " - %m :: # Bufferable = 0b%b", o_lptlb_wdata[`LPAGE_TLB__CB] & 2'b01);
- $display($time, " - %m :: #########################################################");
-
- state_nxt = REFRESH_CYCLE;
- end
-
- default: /* Fault Class II */
- begin
- o_busy = 1'd0;
- o_fault = 1'd1;
- o_fsr = FSR_PAGE_TRANSLATION_FAULT;
- o_fsr = {1'd0, dac_ff, o_fsr[3:0]};
- o_far = i_address;
- state_nxt = IDLE;
- end
- endcase
- end
- else tsk_hold_wb_access;
- end
-
- REFRESH_CYCLE:
- begin
- o_busy = 1'd1;
- state_nxt = IDLE;
- end
-
- endcase
-end
-
-// ----------------------------------------------------------------------------
-
-// Clocked Logic.
-always @ (posedge i_clk)
-begin
- if ( i_reset )
- begin
- state_ff <= IDLE;
- wb_stb_ff <= 0;
- wb_cyc_ff <= 0;
- wb_adr_ff <= 0;
- wb_sel_ff <= 0;
- end
- else
- begin
- state_ff <= state_nxt;
- wb_stb_ff <= wb_stb_nxt;
- wb_cyc_ff <= wb_cyc_nxt;
- wb_adr_ff <= wb_adr_nxt;
- dac_ff <= dac_nxt;
- wb_sel_ff <= wb_sel_nxt;
- dff <= dnxt;
- end
-end
-
-// ----------------------------------------------------------------------------
-
-task tsk_hold_wb_access;
-begin
- wb_stb_nxt = wb_stb_ff;
- wb_cyc_nxt = wb_cyc_ff;
- wb_adr_nxt = wb_adr_ff;
- wb_sel_nxt = wb_sel_ff;
-end
-endtask
-
-task tsk_prpr_wb_rd ( input [31:0] adr );
-begin
- wb_stb_nxt = 1'd1;
- wb_cyc_nxt = 1'd1;
- wb_adr_nxt = adr;
- wb_sel_nxt[3:0] = 4'b1111;
-end
-endtask
-
-endmodule // zap_tlb_fsm.v
-
-`default_nettype wire
-
-// ----------------------------------------------------------------------------
-// END OF FILE
-// ----------------------------------------------------------------------------
Index: zap/trunk/src/rtl/cpu/zap_predecode_main.v
===================================================================
--- zap/trunk/src/rtl/cpu/zap_predecode_main.v (revision 57)
+++ zap/trunk/src/rtl/cpu/zap_predecode_main.v (nonexistent)
@@ -1,359 +0,0 @@
-// -----------------------------------------------------------------------------
-// -- --
-// -- (C) 2016-2018 Revanth Kamaraj. --
-// -- --
-// -- --------------------------------------------------------------------------
-// -- --
-// -- This program is free software; you can redistribute it and/or --
-// -- modify it under the terms of the GNU General Public License --
-// -- as published by the Free Software Foundation; either version 2 --
-// -- of the License, or (at your option) any later version. --
-// -- --
-// -- This program 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 General Public License for more details. --
-// -- --
-// -- You should have received a copy of the GNU General Public License --
-// -- along with this program; if not, write to the Free Software --
-// -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA --
-// -- 02110-1301, USA. --
-// -- --
-// -----------------------------------------------------------------------------
-// -- --
-// -- The pre-decode block. Does partial instruction decoding and sequencing --
-// -- before passing the instruction onto the next stage. --
-// -- --
-// -----------------------------------------------------------------------------
-
-`default_nettype none
-module zap_predecode_main #(
- //
- // For several reasons, we need more architectural registers than
- // what ARM specifies. We also need more physical registers.
- //
- parameter ARCH_REGS = 32,
-
- //
- // Although ARM mentions only 16 ALU operations, the processor
- // internally performs many more operations.
- //
- parameter ALU_OPS = 32,
-
- //
- // Apart from the 4 specified by ARM, an undocumented RORI is present
- // to help deal with immediate rotates.
- //
- parameter SHIFT_OPS = 5,
-
- // Number of physical registers.
- parameter PHY_REGS = 46,
-
- // Coprocessor IF enable.
- parameter COPROCESSOR_INTERFACE_ENABLE = 1,
-
- // Compressed ISA support.
- parameter COMPRESSED_EN = 1
-)
-///////////////////////////////////////////////////////////////////////////////
-(
- // Clock and reset.
- input wire i_clk,
- input wire i_reset,
-
- // 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_clear_from_writeback, // |Pri
- input wire i_data_stall, // |
- input wire i_clear_from_alu, // |
- input wire i_stall_from_shifter, // |
- input wire i_stall_from_issue, // V
-
- // Interrupt events.
- input wire i_irq,
- input wire i_fiq,
- input wire i_abt,
-
- // Is 0 if all pipeline is invalid. Used for coprocessor.
- input wire i_pipeline_dav,
-
- // Coprocessor done.
- input wire i_copro_done,
-
- // PC input.
- input wire [31:0] i_pc_ff,
- input wire [31:0] i_pc_plus_8_ff,
-
- // CPU mode. Taken from CPSR in the ALU.
- input wire i_cpu_mode_t, // T mode.
- input wire [4:0] i_cpu_mode_mode, // CPU mode.
-
- // Instruction input.
- input wire [34:0] i_instruction,
- input wire i_instruction_valid,
-
- // Instruction output
- output reg [35:0] o_instruction_ff,
- output reg o_instruction_valid_ff,
-
- // Stall of PC and fetch.
- output reg o_stall_from_decode,
-
- // PC output.
- output reg [31:0] o_pc_plus_8_ff,
- output reg [31:0] o_pc_ff,
-
- // Interrupts.
- output reg o_irq_ff,
- output reg o_fiq_ff,
- output reg o_abt_ff,
- output reg o_und_ff,
-
- // Force 32-bit alignment on memory accesses.
- output reg o_force32align_ff,
-
- // Coprocessor interface.
- output wire o_copro_dav_ff,
- output wire [31:0] o_copro_word_ff,
-
- // Branch.
- output reg [1:0] o_taken_ff,
-
- // Clear from decode.
- output reg o_clear_from_decode,
- output reg [31:0] o_pc_from_decode
-);
-
-
-`include "zap_defines.vh"
-`include "zap_localparams.vh"
-`include "zap_functions.vh"
-
-///////////////////////////////////////////////////////////////////////////////
-
-// Branch states.
-localparam SNT = 0; // Strongly Not Taken.
-localparam WNT = 1; // Weakly Not Taken.
-localparam WT = 2; // Weakly Taken.
-localparam ST = 3; // Strongly Taken.
-
-///////////////////////////////////////////////////////////////////////////////
-
-wire [35:0] o_instruction_nxt;
-wire o_instruction_valid_nxt;
-
-wire mem_fetch_stall;
-
-wire arm_irq;
-wire arm_fiq;
-
-wire [34:0] arm_instruction;
-wire arm_instruction_valid;
-
-wire cp_stall;
-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;
-
-///////////////////////////////////////////////////////////////////////////////
-
-// Flop the outputs to break the pipeline at this point.
-always @ (posedge i_clk)
-begin
- if ( i_reset )
- begin
- clear;
- end
- else if ( i_clear_from_writeback )
- begin
- clear;
- end
- else if ( i_data_stall )
- begin
- // Preserve state.
- end
- else if ( i_clear_from_alu )
- begin
- clear;
- end
- else if ( i_stall_from_shifter )
- begin
- // Preserve state.
- end
- else if ( i_stall_from_issue )
- begin
- // Preserve state.
- end
- // If no stall, only then update...
- else
- begin
- // Do not pass IRQ and FIQ if mask is 1.
- 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 <= i_force32;
- o_taken_ff <= taken_nxt;
- o_instruction_ff <= o_instruction_nxt;
- o_instruction_valid_ff <= o_instruction_valid_nxt;
- end
-end
-
-task clear;
-begin
- o_irq_ff <= 0;
- o_fiq_ff <= 0;
- o_abt_ff <= 0;
- o_und_ff <= 0;
- o_taken_ff <= 0;
- o_instruction_valid_ff <= 0;
-end
-endtask
-
-always @*
-begin
- o_stall_from_decode = mem_fetch_stall || cp_stall;
-end
-
-///////////////////////////////////////////////////////////////////////////////
-
-// This unit handles coprocessor stuff.
-zap_predecode_coproc
-#(
- .PHY_REGS(PHY_REGS)
-)
-u_zap_decode_coproc
-(
- // Inputs from outside world.
- .i_clk(i_clk),
- .i_reset(i_reset),
- .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),
- .i_cpsr_ff_mode(i_cpu_mode_mode),
-
- // Clear and stall signals.
- .i_clear_from_writeback(i_clear_from_writeback),
- .i_data_stall(i_data_stall),
- .i_clear_from_alu(i_clear_from_alu),
- .i_stall_from_issue(i_stall_from_issue),
- .i_stall_from_shifter(i_stall_from_shifter),
-
- // Valid signals.
- .i_pipeline_dav (i_pipeline_dav),
-
- // Coprocessor
- .i_copro_done(i_copro_done),
-
- // Output to next block.
- .o_instruction(cp_instruction),
- .o_valid(cp_instruction_valid),
- .o_irq(cp_irq),
- .o_fiq(cp_fiq),
-
- // Stall.
- .o_stall_from_decode(cp_stall),
-
- // Coprocessor interface.
- .o_copro_dav_ff(o_copro_dav_ff),
- .o_copro_word_ff(o_copro_word_ff)
-);
-
-
-
-///////////////////////////////////////////////////////////////////////////////
-
- assign arm_instruction = cp_instruction;
- assign arm_instruction_valid = cp_instruction_valid;
- assign arm_irq = cp_irq;
- assign arm_fiq = cp_fiq;
-
-///////////////////////////////////////////////////////////////////////////////
-
-always @*
-begin:bprblk1
- reg [31:0] addr;
- reg [31:0] addr_final;
-
- o_clear_from_decode = 1'd0;
- o_pc_from_decode = 32'd0;
- taken_nxt = i_taken;
- addr = $signed(arm_instruction[23:0]);
-
- if ( arm_instruction[34] ) // Indicates a shift of 1.
- addr_final = addr << 1;
- else
- addr_final = addr << 2;
-
- //
- // Perform actions as mentioned by the predictor unit in the fetch
- // stage.
- //
- if ( arm_instruction[27:25] == 3'b101 && arm_instruction_valid )
- begin
- if ( i_taken[1] || arm_instruction[31:28] == AL )
- // Taken or Strongly Taken or Always taken.
- begin
- // Take the branch. Clear pre-fetched instruction.
- o_clear_from_decode = 1'd1;
-
- // Predict new PC.
- o_pc_from_decode = i_pc_plus_8_ff + addr_final;
-
- if ( arm_instruction[31:28] == AL )
- taken_nxt = ST;
- end
- else // Not Taken or Weakly Not Taken.
- begin
- // Else dont take the branch since pre-fetched
- // instruction is correct.
- o_clear_from_decode = 1'd0;
- o_pc_from_decode = 32'd0;
- end
- end
-end
-
-///////////////////////////////////////////////////////////////////////////////
-
-// This FSM handles LDM/STM/SWAP/SWAPB/BL/LMULT
-zap_predecode_mem_fsm u_zap_mem_fsm (
- .i_clk(i_clk),
- .i_reset(i_reset),
- .i_instruction(arm_instruction),
- .i_instruction_valid(arm_instruction_valid),
- .i_fiq(arm_fiq),
- .i_irq(arm_irq),
- .i_cpsr_t(i_cpu_mode_t),
-
-
- .i_clear_from_writeback(i_clear_from_writeback),
- .i_data_stall(i_data_stall),
- .i_clear_from_alu(i_clear_from_alu),
- .i_issue_stall(i_stall_from_issue),
- .i_stall_from_shifter(i_stall_from_shifter),
-
- .o_irq(o_irq_nxt),
- .o_fiq(o_fiq_nxt),
- .o_instruction(o_instruction_nxt),
- .o_instruction_valid(o_instruction_valid_nxt),
- .o_stall_from_decode(mem_fetch_stall)
-);
-
-///////////////////////////////////////////////////////////////////////////////
-
-endmodule
-`default_nettype wire
Index: zap/trunk/src/rtl/cpu/zap_decompile.v
===================================================================
--- zap/trunk/src/rtl/cpu/zap_decompile.v (revision 57)
+++ zap/trunk/src/rtl/cpu/zap_decompile.v (nonexistent)
@@ -1,475 +0,0 @@
-// ---------------------------------------------------------------------------
-// -- --
-// -- (C) 2016-2018 Revanth Kamaraj. --
-// -- --
-// -- ------------------------------------------------------------------------
-// -- --
-// -- This program is free software; you can redistribute it and/or --
-// -- modify it under the terms of the GNU General Public License --
-// -- as published by the Free Software Foundation; either version 2 --
-// -- of the License, or (at your option) any later version. --
-// -- --
-// -- This program 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 General Public License for more details. --
-// -- --
-// -- You should have received a copy of the GNU General Public License --
-// -- along with this program; if not, write to the Free Software --
-// -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA --
-// -- 02110-1301, USA. --
-// -- --
-// ---------------------------------------------------------------------------
-// -- --
-// -- When running in simulation mode, this module will decompile binary --
-// -- ARM instructions to assembler instructions for debug purposes. --
-// -- When running in synthesis mode, the output of this module is tied --
-// -- to a constant since this module really finds use only in debug. --
-// -- --
-// ---------------------------------------------------------------------------
-
-`default_nettype none
-
-module zap_decompile #(parameter INS_WDT = 36) (
- input wire [36-1:0] i_instruction, // 36-bit instruction into decode.
- input wire i_dav, // Instruction valid.
- output reg [64*8-1:0] o_decompile // 1024 bytes max of assembler string.
- );
-
-`ifndef SYNTHESIS
-
-`include "zap_defines.vh"
-`include "zap_localparams.vh"
-`include "zap_functions.vh"
-
-`ifndef ZAP_DECOMPILE_DEFINES
- `define CCC cond_code(i_instruction[31:28])
- `define CRB arch_reg_num({i_instruction[`DP_RB_EXTEND], i_instruction[`DP_RB]})
- `define CRD arch_reg_num({i_instruction[`DP_RD_EXTEND], i_instruction[`DP_RD]})
- `define CRD1 arch_reg_num({i_instruction[`SRCDEST_EXTEND], i_instruction[`SRCDEST]})
- `define CRN arch_reg_num({i_instruction[`DP_RA_EXTEND], i_instruction[`DP_RA]})
- `define CRN1 arch_reg_num({i_instruction[`BASE_EXTEND], i_instruction[`BASE]})
- `define COPCODE get_opcode({i_instruction[`OPCODE_EXTEND], i_instruction[24:21]})
- `define CSHTYPE get_shtype(i_instruction[6:5])
- `define CRS arch_reg_num(i_instruction[11:8]);
- `define CRM arch_reg_num({i_instruction[`DP_RB_EXTEND], i_instruction[`DP_RB]});
-`endif
-
-always @*
-begin
- if ( !i_dav )
- begin
- o_decompile = "IGNORE";
- end
- else if ( i_instruction[27:24] == 4'b1110 && i_instruction[4] )
- begin
- if ( i_instruction[20] ) // R <- CPSR
- $sformat(o_decompile, "MRC%s", `CCC);
- else
- $sformat(o_decompile, "MCR%s", `CCC);
- end
- else if ( i_instruction[27:25] == 3'b100 ) // LDMSTM
- begin
- if ( i_instruction[20] ) // Load
- $sformat(o_decompile, "LDM%s %b %s %b", `CCC, i_instruction[24:20], i_instruction[19:16], i_instruction[15:0]);
- else
- $sformat(o_decompile, "STM%s %b %s %b", `CCC, i_instruction[24:20], i_instruction[19:16], i_instruction[15:0]);
- end
- else
- casez ( i_instruction[31:0] )
- BX_INST: decode_bx ( i_instruction ); //
- MRS: decode_mrs ( i_instruction ); //
- MSR_IMMEDIATE: decode_msr_immed ( i_instruction ); //
- MSR: decode_msr ( i_instruction ); //
- DATA_PROCESSING_IMMEDIATE: decode_dp_immed ( i_instruction ); //
- DATA_PROCESSING_REGISTER_SPECIFIED_SHIFT: decode_dp_rss ( i_instruction ); //
- DATA_PROCESSING_INSTRUCTION_SPECIFIED_SHIFT: decode_dp_iss ( i_instruction ); //
- BRANCH_INSTRUCTION: decode_branch ( i_instruction ); //
- LS_INSTRUCTION_SPECIFIED_SHIFT: decode_ls_iss ( i_instruction ); //
- LS_IMMEDIATE: decode_ls ( i_instruction ); //
- MULT_INST: decode_mult ( i_instruction ); //
- LMULT_INST: decode_lmult ( i_instruction ); //
- HALFWORD_LS: decode_halfword_ls ( i_instruction ); //
- SOFTWARE_INTERRUPT: decode_swi ( i_instruction ); //
-
- default:
- begin
- o_decompile = "UNRECOGNIZED INSTRUCTION!";
- end
- endcase
-end
-
-task decode_swi ( input [INS_WDT-1:0] i_instruction );
-begin
- $sformat(o_decompile, "SWIAL %0d", $unsigned(i_instruction[24:0]));
-end
-endtask
-
-task decode_branch ( input [INS_WDT-1:0] i_instruction );
-begin
- if ( !i_instruction[24] )
- $sformat(o_decompile, "B%s %0d", `CCC, $signed(i_instruction[23:0]));
- else
- $sformat(o_decompile, "BL%s %0d", `CCC, $signed(i_instruction[23:0]));
-end
-endtask
-
-task decode_bx ( input [INS_WDT-1:0] i_instruction );
-begin
- $sformat(o_decompile, "BX%s %s", `CCC, `CRB );
-end
-endtask
-
-task decode_dp_immed ( input [INS_WDT-1:0] i_instruction );
-begin:blk111
- reg [6*8-1:0] opcode; reg [4*8-1:0] cc, dest_reg, src_reg;
- integer imm_amt, ror_amt;
-
- opcode = `COPCODE;
- cc = `CCC;
- dest_reg = `CRD;
- src_reg = `CRN;
- imm_amt = $unsigned(i_instruction[7:0]);
- ror_amt = $unsigned(i_instruction[11:8]);
-
- $sformat(o_decompile, "%s%s %s,%s,%0d ROR %0d", opcode, cc, dest_reg, src_reg, imm_amt, ror_amt);
-end
-endtask
-
-task decode_dp_rss ( input [INS_WDT-1:0] i_instruction );
-begin:bk222
- reg [4*8-1:0] cc, dest_reg, src_reg, sh_src_reg, shamt_reg;
- reg [6*8-1:0] opcode;
- reg [5*8-1:0] shtype;
- integer shamt;
-
- opcode = `COPCODE;
- cc = `CCC;
- dest_reg = `CRD;
- src_reg = `CRN;
- shtype = `CSHTYPE;
- sh_src_reg = `CRM;
- shamt_reg = `CRS;
-
- $sformat(o_decompile, "%s%s %s,%s,%s %s %s", opcode, cc, dest_reg, src_reg, sh_src_reg, shtype, shamt_reg);
-end
-endtask
-
-task decode_dp_iss ( input [INS_WDT-1:0] i_instruction );
-begin:blk333
- reg [4*8-1:0] cc, dest_reg, src_reg, sh_src_reg;
- reg [6*8-1:0] opcode;
- reg [4*8-1:0] shtype;
- integer shamt;
-
- opcode = `COPCODE;
- cc = `CCC;
- dest_reg = `CRD;
- src_reg = `CRN;
- shtype = `CSHTYPE;
- sh_src_reg = `CRM;
- shamt = $unsigned(i_instruction[11:7]);
-
- $sformat(o_decompile, "%s%s %s,%s,%s %s %0d", opcode, cc, dest_reg, src_reg, sh_src_reg, shtype, shamt);
-end
-endtask
-
-task decode_mrs ( input [INS_WDT-1:0] i_instruction );
-begin
- if ( i_instruction[22] ) // SPSR
- $sformat(o_decompile, "MRS%s %s,SPSR",`CCC, `CRD);
- else // CPSR
- $sformat(o_decompile, "MRS%s %s,CPSR",`CCC, `CRD);
-end
-endtask
-
-task decode_msr ( input [INS_WDT-1:0] i_instruction );
-begin
- if ( i_instruction[22] ) // SPSR
- $sformat(o_decompile, "MSR%s SPSR,%s",`CCC, `CRB);
- else
- $sformat(o_decompile, "MSR%s CPSR,%s", `CCC, `CRB);
-end
-endtask
-
-task decode_msr_immed ( input [INS_WDT-1:0] i_instruction );
-begin
- if ( i_instruction[22] ) // SPSR
- $sformat(o_decompile, "MSR%s SPSR,%dROR%d",`CCC, $unsigned(i_instruction[7:0]), $unsigned(i_instruction[11:8]));
- else
- $sformat(o_decompile, "MSR%s CPSR,%dROR%d",`CCC, $unsigned(i_instruction[7:0]), $unsigned(i_instruction[11:8]));
-end
-endtask
-
-// LS ISS
-task decode_ls_iss ( input [INS_WDT-1:0] i_instruction );
-begin:blk2323
- reg [32*8-1:0] ls_iss_offset;
-
- $sformat(ls_iss_offset, "%s%s%d", `CRB, `CSHTYPE, $unsigned(i_instruction[11:7]));
-
- // If word load
- if ( i_instruction[20] )
- if ( !i_instruction[22] )
- begin
- case ( {i_instruction[24], i_instruction[21]} )
- {1'd1, 1'd1}: $sformat(o_decompile,"LDR%s %s[%s,%s]!", `CCC,`CRD1,`CRN1, ls_iss_offset); // Preindex with writeback
- {1'd1, 1'd0}: $sformat(o_decompile,"LDR%s %s[%s,%s]" , `CCC,`CRD1,`CRN1, ls_iss_offset); // Preindex without writeback
- {1'd0, 1'd0}: $sformat(o_decompile,"LDR%s %s[%s],%s" , `CCC,`CRD1,`CRN1, ls_iss_offset); // Post index
- {1'd1, 1'd1}: $sformat(o_decompile,"LDR%s T%s[%s],%s", `CCC,`CRD1,`CRN1, ls_iss_offset);// Force user view of memory.
- endcase
- end
- else
- begin
- case( {i_instruction[24], i_instruction[21]} )
- {1'd1, 1'd1}: $sformat(o_decompile,"LDR%sB %s[%s,%s]!", `CCC,`CRD1,`CRN1, ls_iss_offset); // Preindex with writeback
- {1'd1, 1'd0}: $sformat(o_decompile,"LDR%sB %s[%s,%s]" , `CCC,`CRD1,`CRN1, ls_iss_offset); // Preindex without writeback
- {1'd0, 1'd0}: $sformat(o_decompile,"LDR%sB %s[%s],%s" , `CCC,`CRD1,`CRN1, ls_iss_offset); // Post index
- {1'd1, 1'd1}: $sformat(o_decompile,"LDR%sB T%s[%s],%s", `CCC,`CRD1,`CRN1, ls_iss_offset);// Force user view of memory.
- endcase
- end
- else
- if ( !i_instruction[22] )
- begin
- case ( {i_instruction[24], i_instruction[21]} )
- {1'd1, 1'd1}: $sformat(o_decompile,"STR%s %s[%s,%s]!", `CCC,`CRD1,`CRN1, ls_iss_offset); // Preindex with writeback
- {1'd1, 1'd0}: $sformat(o_decompile,"STR%s %s[%s,%s]", `CCC,`CRD1,`CRN1, ls_iss_offset); // Preindex without writeback
- {1'd0, 1'd0}: $sformat(o_decompile,"STR%s %s[%s],%s", `CCC,`CRD1,`CRN1, ls_iss_offset); // Post index
- {1'd1, 1'd1}: $sformat(o_decompile,"STR%s T%s[%s],%s", `CCC,`CRD1,`CRN1, ls_iss_offset);// Force user view of memory.
- endcase
- end
- else
- begin
- case( {i_instruction[24], i_instruction[21]} )
- {1'd1, 1'd1}: $sformat(o_decompile,"STR%sB %s[%s,%s]!", `CCC,`CRD1,`CRN1, ls_iss_offset); // Preindex with writeback
- {1'd1, 1'd0}: $sformat(o_decompile,"STR%sB %s[%s,%s]", `CCC,`CRD1,`CRN1, ls_iss_offset); // Preindex without writeback
- {1'd0, 1'd0}: $sformat(o_decompile,"STR%sB %s[%s],%s", `CCC,`CRD1,`CRN1, ls_iss_offset); // Post index
- {1'd1, 1'd1}: $sformat(o_decompile,"STR%sB T%s[%s],%s", `CCC,`CRD1,`CRN1, ls_iss_offset);// Force user view of memory.
- endcase
- end
-end
-endtask
-
-// LS immediate
-task decode_ls ( input [INS_WDT-1:0] i_instruction );
-begin:blk4343
- integer ls_iss_offset; // Forgive the naming convention...
-
- ls_iss_offset = i_instruction[11:0];
-
- // If word load
- if ( i_instruction[20] )
- if ( !i_instruction[22] )
- begin
- case ( {i_instruction[24], i_instruction[21]} )
- {1'd1, 1'd1}: $sformat(o_decompile,"LDR%s %s[%s,%0d]!", `CCC,`CRD1,`CRN1, ls_iss_offset); // Preindex with writeback
- {1'd1, 1'd0}: $sformat(o_decompile,"LDR%s %s[%s,%0d]" , `CCC,`CRD1,`CRN1, ls_iss_offset); // Preindex without writeback
- {1'd0, 1'd0}: $sformat(o_decompile,"LDR%s %s[%s],%0d" , `CCC,`CRD1,`CRN1, ls_iss_offset); // Post index
- {1'd1, 1'd1}: $sformat(o_decompile,"LDR%s T%s[%s],%0d", `CCC,`CRD1,`CRN1, ls_iss_offset);// Force user view of memory.
- endcase
- end
- else
- begin
- case( {i_instruction[24], i_instruction[21]} )
- {1'd1, 1'd1}: $sformat(o_decompile,"LDR%sB %s[%s,%0d]!", `CCC,`CRD1,`CRN1, ls_iss_offset); // Preindex with writeback
- {1'd1, 1'd0}: $sformat(o_decompile,"LDR%sB %s[%s,%0d]" , `CCC,`CRD1,`CRN1, ls_iss_offset); // Preindex without writeback
- {1'd0, 1'd0}: $sformat(o_decompile,"LDR%sB %s[%s],%0d" , `CCC,`CRD1,`CRN1, ls_iss_offset); // Post index
- {1'd1, 1'd1}: $sformat(o_decompile,"LDR%sB T%s[%s],%0d", `CCC,`CRD1,`CRN1, ls_iss_offset);// Force user view of memory.
- endcase
- end
- else
- if ( !i_instruction[22] )
- begin
- case ( {i_instruction[24], i_instruction[21]} )
- {1'd1, 1'd1}: $sformat(o_decompile,"STR%s %s[%s,%0d]!", `CCC,`CRD1,`CRN1, ls_iss_offset); // Preindex with writeback
- {1'd1, 1'd0}: $sformat(o_decompile,"STR%s %s[%s,%0d]", `CCC,`CRD1,`CRN1, ls_iss_offset); // Preindex without writeback
- {1'd0, 1'd0}: $sformat(o_decompile,"STR%s %s[%s],%0d", `CCC,`CRD1,`CRN1, ls_iss_offset); // Post index
- {1'd1, 1'd1}: $sformat(o_decompile,"STR%s T%s[%s],%0d", `CCC,`CRD1,`CRN1, ls_iss_offset);// Force user view of memory.
- endcase
- end
- else
- begin
- case( {i_instruction[24], i_instruction[21]} )
- {1'd1, 1'd1}: $sformat(o_decompile,"STR%sB %s[%s,%0d]!", `CCC,`CRD1,`CRN1, ls_iss_offset); // Preindex with writeback
- {1'd1, 1'd0}: $sformat(o_decompile,"STR%sB %s[%s,%0d]", `CCC,`CRD1,`CRN1, ls_iss_offset); // Preindex without writeback
- {1'd0, 1'd0}: $sformat(o_decompile,"STR%sB %s[%s],%0d", `CCC,`CRD1,`CRN1, ls_iss_offset); // Post index
- {1'd1, 1'd1}: $sformat(o_decompile,"STR%sB T%s[%s],%0d", `CCC,`CRD1,`CRN1, ls_iss_offset);// Force user view of memory.
- endcase
- end
-
-end
-endtask
-
-// Mult. MUL, MLA
-task decode_mult ( input [INS_WDT-1:0] i_instruction );
-begin
- if ( i_instruction[21] == 1'd0 )
- $sformat(o_decompile, "MUL%s %s,%s,%s",`CCC,`CRN,`CRD,arch_reg_num(i_instruction[11:8]));
- else
- $sformat(o_decompile, "MLA%s %s,%s,%s,%s",`CCC,`CRN,`CRD,arch_reg_num(i_instruction[11:8]), arch_reg_num(i_instruction[3:0]));
-end
-endtask
-
-`ifndef XUMULL
-
- `define XUMULL 3'b100
- `define XUMLAL 3'b101
- `define XSMULL 3'b110
- `define XSMLAL 3'b111
-
-`endif
-
-// Long Mult. UMULL, UMLAL, SMULL, SMLAL
-task decode_lmult ( input [INS_WDT-1:0] i_instruction );
-begin
- case(i_instruction[23:21])
- `XUMULL: $sformat(o_decompile, "UMULL %s:%s=%s*%s" ,i_instruction[19:16], i_instruction[15:12], i_instruction[3:0], i_instruction[11:8] );
- `XUMLAL: $sformat(o_decompile, "UMLAL %s:%s+=%s*%s",i_instruction[19:16], i_instruction[15:12], i_instruction[3:0], i_instruction[11:8] );
- `XSMULL: $sformat(o_decompile, "SMULL %s:%s=%s*%s" ,i_instruction[19:16], i_instruction[15:12], i_instruction[3:0], i_instruction[11:8] );
- `XSMLAL: $sformat(o_decompile, "SMLAL %s:%s+=%s*%s",i_instruction[19:16], i_instruction[15:12], i_instruction[3:0], i_instruction[11:8] );
- endcase
-end
-endtask
-
-task decode_halfword_ls ( input [INS_WDT-1:0] i_instruction );
-begin
- o_decompile = "***HALFWORD LD/ST***";
-end
-endtask
-
-// Returns shift type.
-function [4*8-1:0] get_shtype ( input [2:0] x );
-begin
- case(x)
- 0: get_shtype = "LSL";
- 1: get_shtype = "LSR";
- 2: get_shtype = "ASR";
- 3: get_shtype = "ROR";
- 4: get_shtype = "RRC";
- 5: get_shtype = "RORI";
- 6: get_shtype = "ROR1";
- 7: get_shtype = "<-->";
- endcase
-end
-endfunction
-
-// Returns opcode in english.
-function [6*8-1:0] get_opcode ( input [4:0] x );
-begin
- case(x)
- 0: get_opcode = "AND" ; //= 0;
- 1: get_opcode = "EOR" ; //= 1;
- 2: get_opcode = "SUB" ; //= 2;
- 3: get_opcode = "RSB" ; //= 3;
- 4: get_opcode = "ADD" ; //= 4;
- 5: get_opcode = "ADC" ; //= 5;
- 6: get_opcode = "SBC" ; //= 6;
- 7: get_opcode = "RSC" ; //= 7;
- 8: get_opcode = "TST" ; //= 8;
- 9: get_opcode = "TEQ" ; //= 9;
- 10:get_opcode = "CMP" ; //= 10;
- 11:get_opcode = "CMN" ; //= 11;
- 12:get_opcode = "ORR" ; //= 12;
- 13:get_opcode = "MOV" ; //= 13;
- 14:get_opcode = "BIC" ; //= 14;
- 15:get_opcode = "MVN" ; //= 15;
- 16:get_opcode = "MUL" ; //= 16; // Multiply ( 32 x 32 = 32 ) -> Translated to MAC.
- 17:get_opcode = "MLA" ; //= 17; // Multiply-Accumulate ( 32 x 32 + 32 = 32 ).
- 18:get_opcode = "FMOV" ; //= 18;
- 19:get_opcode = "MMOV" ; //= 19;
- 20:get_opcode = "UMLALL" ; //= 20; // Unsigned multiply accumulate (Write lower reg).
- 21:get_opcode = "UMLALH" ; //= 21;
- 22:get_opcode = "SMLALL" ; //= 22; // Signed multiply accumulate (Write lower reg).
- 23:get_opcode = "SMLALH" ; //= 23;
- 24:get_opcode = "CLZ" ; //= 24; // Count Leading zeros.
- default: get_opcode = "<-->";
- endcase
-end
-endfunction
-
-// Returns arch reg number (5 bit number as input.)
-function [4*8-1:0] arch_reg_num ( input [4:0] reg_num );
-begin:blk434234
- reg [4*8-1:0] x;
-
- case(reg_num)
- 5'd0 : x = "R0 ";
- 5'd1 : x = "R1 ";
- 5'd2 : x = "R2 ";
- 5'd3 : x = "R3 ";
- 5'd4 : x = "R4 ";
- 5'd5 : x = "R5 ";
- 5'd6 : x = "R6 ";
- 5'd7 : x = "R7 ";
- 5'd8 : x = "R8 ";
- 5'd9 : x = "R9 ";
- 5'd10 : x = "R10 ";
- 5'd11 : x = "R11 ";
- 5'd12 : x = "R12 ";
- 5'd13 : x = "SP ";
- 5'd14 : x = "LR ";
- 5'd15 : x = "PC ";
- 5'd16 : x = "RAZ ";
- 5'd17 : x = "CPSR";
- 5'd18 : x = "R8x ";
- 5'd19 : x = "R9x ";
- 5'd20 : x = "R10x";
- 5'd21 : x = "R11x";
- 5'd22 : x = "R12x";
- 5'd23 : x = "R13x";
- 5'd24 : x = "R14x";
- 5'd25 : x = "DMY0";
- 5'd26 : x = "DMY1";
- 5'd27 : x = "SPSR";
- 5'd28 : x = "<-->";
- 5'd29 : x = "<-->";
- 5'd30 : x = "<-->";
- 5'd31 : x = "<-->";
- endcase
-
- arch_reg_num = x;
-end
-endfunction
-
-// Returns a text version of the condition code.
-function [2*8-1:0] cond_code ( input [3:0] cond );
-begin: blk49329483
- reg [2*8-1:0] ok;
-
- case(cond)
- EQ: ok = "EQ";
- NE: ok = "NE";
- CS: ok = "CS";
- CC: ok = "CC";
- MI: ok = "MI";
- PL: ok = "PL";
- VS: ok = "VS";
- VC: ok = "VC";
- HI: ok = "HI";
- LS: ok = "LS";
- GE: ok = "GE";
- LT: ok = "LT";
- GT: ok = "GT";
- LE: ok = "LE";
- AL: ok = "AL";
- NV: ok = "NV";
- endcase
-
- cond_code = ok;
-end
-endfunction
-
-`else
-
-always @*
- o_decompile = 0; // In synthesis mode.
-
-`endif
-
-endmodule // zap_decompile.v
-
-`default_nettype wire
-
-// ----------------------------------------------------------------------------
-// EOF
-// ----------------------------------------------------------------------------
Index: zap/trunk/src/rtl/cpu/zap_shift_shifter.v
===================================================================
--- zap/trunk/src/rtl/cpu/zap_shift_shifter.v (revision 57)
+++ zap/trunk/src/rtl/cpu/zap_shift_shifter.v (nonexistent)
@@ -1,108 +0,0 @@
-// -----------------------------------------------------------------------------
-// -- --
-// -- (C) 2016-2018 Revanth Kamaraj. --
-// -- --
-// -- --------------------------------------------------------------------------
-// -- --
-// -- This program is free software; you can redistribute it and/or --
-// -- modify it under the terms of the GNU General Public License --
-// -- as published by the Free Software Foundation; either version 2 --
-// -- of the License, or (at your option) any later version. --
-// -- --
-// -- This program 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 General Public License for more details. --
-// -- --
-// -- You should have received a copy of the GNU General Public License --
-// -- along with this program; if not, write to the Free Software --
-// -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA --
-// -- 02110-1301, USA. --
-// -- --
-// -----------------------------------------------------------------------------
-
-`default_nettype none
-
-module zap_shift_shifter
-#(
- parameter SHIFT_OPS = 5
-)
-(
- // Source value.
- input wire [31:0] i_source,
-
- // Shift amount.
- input wire [7:0] i_amount,
-
- // Carry in.
- input wire i_carry,
-
- // Shift type.
- input wire [$clog2(SHIFT_OPS)-1:0] i_shift_type,
-
- // Output result and output carry.
- output reg [31:0] o_result,
- output reg o_carry
-);
-
-`include "zap_defines.vh"
-`include "zap_localparams.vh"
-`include "zap_functions.vh"
-
-///////////////////////////////////////////////////////////////////////////////
-
-always @*
-begin
- // Prevent latch inference.
- o_result = i_source;
- o_carry = 0;
-
- case ( i_shift_type )
-
- // Logical shift left, logical shift right and
- // arithmetic shift right.
- LSL: {o_carry, o_result} = {i_carry, i_source} << i_amount;
- LSR: {o_result, o_carry} = {i_source, i_carry} >> i_amount;
- ASR:
- begin:blk1111
- reg signed [32:0] res, res1;
- res = {i_source, i_carry};
- res1 = $signed(res) >>> i_amount;
- {o_result, o_carry} = res1;
- end
-
- ROR: // Rotate right.
- begin
- o_result = ( i_source >> i_amount[4:0] ) |
- ( i_source << (32 - i_amount[4:0] ) );
- o_carry = ( i_amount[7:0] == 0) ?
- i_carry : ( (i_amount[4:0] == 0) ?
- i_source[31] : o_result[31] );
- end
-
- RORI, ROR_1:
- begin
- // ROR #n (ROR_1)
- o_result = ( i_source >> i_amount[4:0] ) |
- (i_source << (32 - i_amount[4:0] ) );
- o_carry = i_amount ? o_result[31] : i_carry;
- end
-
- // ROR #0 becomes this.
- RRC: {o_result, o_carry} = {i_carry, i_source};
-
- default: // For lint.
- begin
- end
- endcase
-end
-
-///////////////////////////////////////////////////////////////////////////////
-
-endmodule // zap_shift_shifter.v
-
-`default_nettype wire
-
-// ----------------------------------------------------------------------------
-// EOF
-// ----------------------------------------------------------------------------
Index: zap/trunk/src/rtl/cpu/zap_top.v
===================================================================
--- zap/trunk/src/rtl/cpu/zap_top.v (revision 57)
+++ zap/trunk/src/rtl/cpu/zap_top.v (nonexistent)
@@ -1,414 +0,0 @@
-// -----------------------------------------------------------------------------
-// -- --
-// -- (C) 2016-2018 Revanth Kamaraj. --
-// -- --
-// -- --------------------------------------------------------------------------
-// -- --
-// -- This program is free software; you can redistribute it and/or --
-// -- modify it under the terms of the GNU General Public License --
-// -- as published by the Free Software Foundation; either version 2 --
-// -- of the License, or (at your option) any later version. --
-// -- --
-// -- This program 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 General Public License for more details. --
-// -- --
-// -- You should have received a copy of the GNU General Public License --
-// -- along with this program; if not, write to the Free Software --
-// -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA --
-// -- 02110-1301, USA. --
-// -- --
-// -----------------------------------------------------------------------------
-// -- --
-// -- This is the top module of the ZAP processor. It contains instances of --
-// -- processor core and the memory management units. I and D WB busses --
-// -- are provided. --
-// -- --
-// ----------------------------------------------------------------------------
-
-`default_nettype none
-
-module zap_top #(
-
-// -----------------------------------
-// BP entries, FIFO depths
-// -----------------------------------
-
-parameter BP_ENTRIES = 1024, // Predictor depth.
-parameter FIFO_DEPTH = 4, // FIFO depth.
-parameter STORE_BUFFER_DEPTH = 16, // Depth of the store buffer.
-
-// ----------------------------------
-// Data MMU/Cache configuration.
-// ----------------------------------
-parameter [31:0] DATA_SECTION_TLB_ENTRIES = 32'd4, // Section TLB entries.
-parameter [31:0] DATA_LPAGE_TLB_ENTRIES = 32'd8, // Large page TLB entries.
-parameter [31:0] DATA_SPAGE_TLB_ENTRIES = 32'd16, // Small page TLB entries.
-parameter [31:0] DATA_CACHE_SIZE = 32'd1024, // Cache size in bytes.
-
-// ----------------------------------
-// Code MMU/Cache configuration.
-// ----------------------------------
-parameter [31:0] CODE_SECTION_TLB_ENTRIES = 32'd4, // Section TLB entries.
-parameter [31:0] CODE_LPAGE_TLB_ENTRIES = 32'd8, // Large page TLB entries.
-parameter [31:0] CODE_SPAGE_TLB_ENTRIES = 32'd16, // Small page TLB entries.
-parameter [31:0] CODE_CACHE_SIZE = 32'd1024 // Cache size in bytes.
-
-)(
- // --------------------------------------
- // Clock and reset
- // --------------------------------------
-
- input wire i_clk,
- input wire i_reset,
-
- // ---------------------------------------
- // Interrupts.
- // Both of them are active high and level
- // trigerred.
- // ---------------------------------------
-
- input wire i_irq,
- input wire i_fiq,
-
- // ---------------------
- // Wishbone interface.
- // ---------------------
-
- output wire o_wb_cyc,
- output wire o_wb_stb,
- output wire o_wb_stb_nxt,
- output wire o_wb_cyc_nxt,
- output wire [31:0] o_wb_adr_nxt,
- output wire [31:0] o_wb_adr,
- output wire o_wb_we,
- output wire [31:0] o_wb_dat,
- output wire [3:0] o_wb_sel,
- output wire [2:0] o_wb_cti,
- output wire [1:0] o_wb_bte,
- input wire i_wb_ack,
- input wire [31:0] i_wb_dat
-);
-
-assign o_wb_bte = 2'b00; // Linear Burst.
-
-localparam COMPRESSED_EN = 1'd1;
-
-`include "zap_defines.vh"
-`include "zap_localparams.vh"
-`include "zap_functions.vh"
-
-wire wb_cyc, wb_stb, wb_we;
-wire [3:0] wb_sel;
-wire [31:0] wb_dat, wb_idat;
-wire [31:0] wb_adr;
-wire [2:0] wb_cti;
-wire wb_ack;
-reg reset;
-
-// Synchronous reset signal flopped.
-always @ (posedge i_clk)
- reset <= i_reset;
-
-wire cpu_mmu_en;
-wire [31:0] cpu_cpsr;
-wire cpu_mem_translate;
-
-wire [31:0] cpu_daddr, cpu_daddr_nxt;
-wire [31:0] cpu_iaddr, cpu_iaddr_nxt;
-
-wire [7:0] dc_fsr;
-wire [31:0] dc_far;
-
-wire cpu_dc_en, cpu_ic_en;
-
-wire [1:0] cpu_sr;
-wire [7:0] cpu_pid;
-wire [31:0] cpu_baddr, cpu_dac_reg;
-
-wire cpu_dc_inv, cpu_ic_inv;
-wire cpu_dc_clean, cpu_ic_clean;
-
-wire dc_inv_done, ic_inv_done, dc_clean_done, ic_clean_done;
-
-wire cpu_dtlb_inv, cpu_itlb_inv;
-
-wire data_ack, data_err, instr_ack, instr_err;
-
-wire [31:0] ic_data, dc_data, cpu_dc_dat;
-wire cpu_instr_stb;
-wire cpu_dc_we, cpu_dc_stb;
-wire [3:0] cpu_dc_sel;
-
-wire c_wb_stb;
-wire c_wb_cyc;
-wire c_wb_wen;
-wire [3:0] c_wb_sel;
-wire [31:0] c_wb_dat;
-wire [31:0] c_wb_adr;
-wire [2:0] c_wb_cti;
-wire c_wb_ack;
-
-wire d_wb_stb;
-wire d_wb_cyc;
-wire d_wb_wen;
-wire [3:0] d_wb_sel;
-wire [31:0] d_wb_dat;
-wire [31:0] d_wb_adr;
-wire [2:0] d_wb_cti;
-wire d_wb_ack;
-
-zap_core #(
- .BP_ENTRIES(BP_ENTRIES),
- .FIFO_DEPTH(FIFO_DEPTH)
-) u_zap_core
-(
-// Clock and reset.
-.i_clk (i_clk),
-.i_reset (reset),
-
-// Code related.
-.o_instr_wb_adr (cpu_iaddr),
-.o_instr_wb_cyc (),
-.o_instr_wb_stb (cpu_instr_stb),
-.o_instr_wb_we (),
-.o_instr_wb_sel (),
-
-// Code related.
-.i_instr_wb_dat (ic_data),
-
-.i_instr_wb_ack (instr_ack),
-.i_instr_wb_err (instr_err),
-
-// Data related.
-.o_data_wb_we (cpu_dc_we),
-.o_data_wb_adr (cpu_daddr),
-.o_data_wb_sel (cpu_dc_sel),
-.o_data_wb_dat (cpu_dc_dat),
-.o_data_wb_cyc (),
-.o_data_wb_stb (cpu_dc_stb),
-
-// Data related.
-.i_data_wb_ack (data_ack),
-.i_data_wb_err (data_err),
-.i_data_wb_dat (dc_data),
-
-// Interrupts.
-.i_fiq (i_fiq),
-.i_irq (i_irq),
-
-// MMU/cache is present.
-.o_mem_translate (cpu_mem_translate),
-.i_fsr ({24'd0,dc_fsr}),
-.i_far (dc_far),
-.o_dac (cpu_dac_reg),
-.o_baddr (cpu_baddr),
-.o_mmu_en (cpu_mmu_en),
-.o_sr (cpu_sr),
-.o_pid (cpu_pid),
-.o_dcache_inv (cpu_dc_inv),
-.o_icache_inv (cpu_ic_inv),
-.o_dcache_clean (cpu_dc_clean),
-.o_icache_clean (cpu_ic_clean),
-.o_dtlb_inv (cpu_dtlb_inv),
-.o_itlb_inv (cpu_itlb_inv),
-.i_dcache_inv_done (dc_inv_done),
-.i_icache_inv_done (ic_inv_done),
-.i_dcache_clean_done (dc_clean_done),
-.i_icache_clean_done (ic_clean_done),
-.o_dcache_en (cpu_dc_en),
-.o_icache_en (cpu_ic_en),
-
-// Data IF nxt.
-.o_data_wb_adr_nxt (cpu_daddr_nxt), // Data addr nxt. Used to drive address of data tag RAM.
-.o_data_wb_we_nxt (),
-.o_data_wb_cyc_nxt (),
-.o_data_wb_stb_nxt (),
-.o_data_wb_dat_nxt (),
-.o_data_wb_sel_nxt (),
-
-// Code access prpr.
-.o_instr_wb_adr_nxt (cpu_iaddr_nxt), // PC addr nxt. Drives read address of code tag RAM.
-.o_instr_wb_stb_nxt (),
-
-.o_cpsr (cpu_cpsr)
-
-);
-
-zap_cache #(
- .CACHE_SIZE(DATA_CACHE_SIZE),
- .SPAGE_TLB_ENTRIES(DATA_SPAGE_TLB_ENTRIES),
- .LPAGE_TLB_ENTRIES(DATA_LPAGE_TLB_ENTRIES),
- .SECTION_TLB_ENTRIES(DATA_SECTION_TLB_ENTRIES))
-u_data_cache (
-.i_clk (i_clk),
-.i_reset (reset),
-.i_address (cpu_daddr + (cpu_pid << 25)),
-.i_address_nxt (cpu_daddr_nxt + (cpu_pid << 25)),
-
-.i_rd (!cpu_dc_we && cpu_dc_stb),
-.i_wr (cpu_dc_we),
-.i_ben (cpu_dc_sel),
-.i_dat (cpu_dc_dat),
-.o_dat (dc_data),
-.o_ack (data_ack),
-.o_err (data_err),
-
-.o_fsr (dc_fsr),
-.o_far (dc_far),
-.i_mmu_en (cpu_mmu_en),
-.i_cache_en (cpu_dc_en),
-.i_cache_inv_req (cpu_dc_inv),
-.i_cache_clean_req (cpu_dc_clean),
-.o_cache_inv_done (dc_inv_done),
-.o_cache_clean_done (dc_clean_done),
-.i_cpsr (cpu_mem_translate ? USR : cpu_cpsr),
-.i_sr (cpu_sr),
-.i_baddr (cpu_baddr),
-.i_dac_reg (cpu_dac_reg),
-.i_tlb_inv (cpu_dtlb_inv),
-
-.o_wb_stb (),
-.o_wb_cyc (),
-.o_wb_wen (),
-.o_wb_sel (),
-.o_wb_dat (),
-.o_wb_adr (),
-.o_wb_cti (),
-
-.i_wb_dat (wb_dat),
-.i_wb_ack (d_wb_ack),
-
-.o_wb_stb_nxt (d_wb_stb),
-.o_wb_cyc_nxt (d_wb_cyc),
-.o_wb_wen_nxt (d_wb_wen),
-.o_wb_sel_nxt (d_wb_sel),
-.o_wb_dat_nxt (d_wb_dat),
-.o_wb_adr_nxt (d_wb_adr),
-.o_wb_cti_nxt (d_wb_cti)
-);
-
-zap_cache #(
-.CACHE_SIZE(CODE_CACHE_SIZE),
-.SPAGE_TLB_ENTRIES(CODE_SPAGE_TLB_ENTRIES),
-.LPAGE_TLB_ENTRIES(CODE_LPAGE_TLB_ENTRIES),
-.SECTION_TLB_ENTRIES(CODE_SECTION_TLB_ENTRIES))
-u_code_cache (
-.i_clk (i_clk),
-.i_reset (reset),
-.i_address ((cpu_iaddr & 32'hFFFF_FFFC) + (cpu_pid << 25)), // Cut off lower 2 bits.
-.i_address_nxt ((cpu_iaddr_nxt & 32'hFFFF_FFFC) + (cpu_pid << 25)), // Cut off lower 2 bits.
-
-.i_rd (cpu_instr_stb),
-.i_wr (1'd0),
-.i_ben (4'b1111),
-.i_dat (32'd0),
-.o_dat (ic_data),
-.o_ack (instr_ack),
-.o_err (instr_err),
-
-.o_fsr (),
-.o_far (),
-.i_mmu_en (cpu_mmu_en),
-.i_cache_en (cpu_ic_en),
-.i_cache_inv_req (cpu_ic_inv),
-.i_cache_clean_req (cpu_ic_clean),
-.o_cache_inv_done (ic_inv_done),
-.o_cache_clean_done(ic_clean_done),
-.i_cpsr (cpu_mem_translate ? USR : cpu_cpsr),
-.i_sr (cpu_sr),
-.i_baddr (cpu_baddr),
-.i_dac_reg (cpu_dac_reg),
-.i_tlb_inv (cpu_itlb_inv),
-
-.o_wb_stb (),
-.o_wb_cyc (),
-.o_wb_wen (),
-.o_wb_sel (),
-.o_wb_dat (),
-.o_wb_adr (),
-.o_wb_cti (),
-
-.i_wb_dat (wb_dat),
-.i_wb_ack (c_wb_ack),
-
-.o_wb_stb_nxt (c_wb_stb),
-.o_wb_cyc_nxt (c_wb_cyc),
-.o_wb_wen_nxt (c_wb_wen),
-.o_wb_sel_nxt (c_wb_sel),
-.o_wb_dat_nxt (c_wb_dat),
-.o_wb_adr_nxt (c_wb_adr),
-.o_wb_cti_nxt (c_wb_cti)
-);
-
-zap_wb_merger u_zap_wb_merger (
-
-.i_clk(i_clk),
-.i_reset(i_reset),
-
-.i_c_wb_stb(c_wb_stb),
-.i_c_wb_cyc(c_wb_cyc),
-.i_c_wb_wen(c_wb_wen),
-.i_c_wb_sel(c_wb_sel),
-.i_c_wb_dat(c_wb_dat),
-.i_c_wb_adr(c_wb_adr),
-.i_c_wb_cti(c_wb_cti),
-.o_c_wb_ack(c_wb_ack),
-
-.i_d_wb_stb(d_wb_stb),
-.i_d_wb_cyc(d_wb_cyc),
-.i_d_wb_wen(d_wb_wen),
-.i_d_wb_sel(d_wb_sel),
-.i_d_wb_dat(d_wb_dat),
-.i_d_wb_adr(d_wb_adr),
-.i_d_wb_cti(d_wb_cti),
-.o_d_wb_ack(d_wb_ack),
-
-.o_wb_cyc(wb_cyc),
-.o_wb_stb(wb_stb),
-.o_wb_wen(wb_we),
-.o_wb_sel(wb_sel),
-.o_wb_dat(wb_idat),
-.o_wb_adr(wb_adr),
-.o_wb_cti(wb_cti),
-.i_wb_ack(wb_ack)
-
-);
-
-zap_wb_adapter #(.DEPTH(STORE_BUFFER_DEPTH)) u_zap_wb_adapter (
-.i_clk(i_clk),
-.i_reset(i_reset),
-
-.I_WB_CYC(wb_cyc),
-.I_WB_STB(wb_stb),
-.I_WB_WE(wb_we),
-.I_WB_DAT(wb_idat),
-.I_WB_SEL(wb_sel),
-.I_WB_CTI(wb_cti),
-.O_WB_ACK(wb_ack),
-.O_WB_DAT(wb_dat),
-.I_WB_ADR(wb_adr),
-
-.o_wb_cyc(o_wb_cyc),
-.o_wb_stb(o_wb_stb),
-.o_wb_we(o_wb_we),
-.o_wb_sel(o_wb_sel),
-.o_wb_dat(o_wb_dat),
-.o_wb_adr(o_wb_adr),
-.o_wb_cti(o_wb_cti),
-.i_wb_dat(i_wb_dat),
-.i_wb_ack(i_wb_ack),
-
-// CYC and STB nxt.
-.o_wb_stb_nxt (o_wb_stb_nxt),
-.o_wb_cyc_nxt (o_wb_cyc_nxt),
-.o_wb_adr_nxt (o_wb_adr_nxt),
-.o_wb_sel_nxt (),
-.o_wb_dat_nxt (),
-.o_wb_we_nxt ()
-);
-
-endmodule // zap_top.v
-
-`default_nettype wire
Index: zap/trunk/src/rtl/cpu/zap_thumb_decoder.v
===================================================================
--- zap/trunk/src/rtl/cpu/zap_thumb_decoder.v (revision 57)
+++ zap/trunk/src/rtl/cpu/zap_thumb_decoder.v (nonexistent)
@@ -1,189 +0,0 @@
-// -----------------------------------------------------------------------------
-// -- --
-// -- (C) 2016-2018 Revanth Kamaraj. --
-// -- --
-// -- --------------------------------------------------------------------------
-// -- --
-// -- This program is free software; you can redistribute it and/or --
-// -- modify it under the terms of the GNU General Public License --
-// -- as published by the Free Software Foundation; either version 2 --
-// -- of the License, or (at your option) any later version. --
-// -- --
-// -- This program 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 General Public License for more details. --
-// -- --
-// -- You should have received a copy of the GNU General Public License --
-// -- along with this program; if not, write to the Free Software --
-// -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA --
-// -- 02110-1301, USA. --
-// -- --
-// -----------------------------------------------------------------------------
-// -- --
-// -- Implements a 16-bit instruction decoder. The 16-bit instruction set is --
-// -- not logically organized so as to save on encoding and thus the code --
-// -- seem a bit complex. --
-// -- --
-// -----------------------------------------------------------------------------
-
-`default_nettype none
-
-module zap_thumb_decoder (
- // Clock and reset.
- input wire i_clk,
- input wire i_reset,
-
- // 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_instruction(i_instruction),
- .i_instruction_valid(i_instruction_valid),
- .i_irq(i_irq),
- .i_fiq(i_fiq),
- .i_offset(o_instruction[11:0]),
- .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
-
-// Helpful for debug.
-zap_decompile u_zap_decompile (
- .i_instruction ({1'd0, o_instruction}),
- .i_dav (o_instruction_valid),
- .o_decompile ()
-);
-
-
-endmodule // zap_thumb_decoder
-
-`default_nettype wire
-
-// ----------------------------------------------------------------------------
-// EOF
-// ----------------------------------------------------------------------------
Index: zap/trunk/src/rtl/cpu/zap_localparams.vh
===================================================================
--- zap/trunk/src/rtl/cpu/zap_localparams.vh (revision 57)
+++ zap/trunk/src/rtl/cpu/zap_localparams.vh (nonexistent)
@@ -1,367 +0,0 @@
-// -----------------------------------------------------------------------------
-// -- --
-// -- (C) 2016-2018 Revanth Kamaraj. --
-// -- --
-// -- --------------------------------------------------------------------------
-// -- --
-// -- This program is free software; you can redistribute it and/or --
-// -- modify it under the terms of the GNU General Public License --
-// -- as published by the Free Software Foundation; either version 2 --
-// -- of the License, or (at your option) any later version. --
-// -- --
-// -- This program 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 General Public License for more details. --
-// -- --
-// -- You should have received a copy of the GNU General Public License --
-// -- along with this program; if not, write to the Free Software --
-// -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA --
-// -- 02110-1301, USA. --
-// -- --
-// -----------------------------------------------------------------------------
-
-// Identifier for L1
-localparam [1:0] SECTION_ID = 2'b10;
-localparam [1:0] PAGE_ID = 2'b01;
-
-// Identifier for L2
-localparam [1:0] SPAGE_ID = 2'b10;
-localparam [1:0] LPAGE_ID = 2'b01;
-
-// APSR bits.
-// K U (kernel user) permissions.
-localparam APSR_NA_NA = 4'b00_00;
-localparam APSR_RO_RO = 4'b00_01;
-localparam APSR_RO_NA = 4'b00_10;
-localparam APSR_RW_NA = 4'b01_??;
-localparam APSR_RW_RO = 4'b10_??;
-localparam APSR_RW_RW = 4'b11_??;
-
-// DAC bits.
-localparam DAC_MANAGER = 2'b11;
-localparam DAC_CLIENT = 2'b01;
-
-// FSR related.
-// These localparams relate to FSR values. Notice how
-// only some FSR values make sense in this implementation.
-
-//Section.
-localparam [3:0] FSR_SECTION_DOMAIN_FAULT = 4'b1001;
-localparam [3:0] FSR_SECTION_TRANSLATION_FAULT = 4'b0101;
-localparam [3:0] FSR_SECTION_PERMISSION_FAULT = 4'b1101;
-
-//Page.
-localparam [3:0] FSR_PAGE_TRANSLATION_FAULT = 4'b0111;
-localparam [3:0] FSR_PAGE_DOMAIN_FAULT = 4'b1011;
-localparam [3:0] FSR_PAGE_PERMISSION_FAULT = 4'b1111;
-
-
-
-///////////////////////////////////////////////////////////////////////////////
-
-// Standard opcodes.
-// These map to the opcode map in the spec.
-localparam [3:0] AND = 0;
-localparam [3:0] EOR = 1;
-localparam [3:0] SUB = 2;
-localparam [3:0] RSB = 3;
-localparam [3:0] ADD = 4;
-localparam [3:0] ADC = 5;
-localparam [3:0] SBC = 6;
-localparam [3:0] RSC = 7;
-localparam [3:0] TST = 8;
-localparam [3:0] TEQ = 9;
-localparam [3:0] CMP = 10;
-localparam [3:0] CMN = 11;
-localparam [3:0] ORR = 12;
-localparam [3:0] MOV = 13;
-localparam [3:0] BIC = 14;
-localparam [3:0] MVN = 15;
-
-// Internal opcodes used to
-// implement some instructions.
-localparam [4:0] MUL = 16; // Multiply ( 32 x 32 = 32 ) -> Translated to MAC.
-localparam [4:0] MLA = 17; // Multiply-Accumulate ( 32 x 32 + 32 = 32 ).
-
-// Flag MOV. Will write upper 4-bits to flags if mask bit [3] is set to 1.
-// Also writes to target register similarly.
-// Mask bit comes from non-shift operand.
-localparam [4:0] FMOV = 18;
-
-// Same as FMOV but does not touch the flags in the ALU. This is MASK MOV.
-// Set to 1 will update, 0 will not
-// (0000 -> No updates, 0001 -> [7:0] update) and so on.
-localparam [4:0] MMOV = 19;
-
-localparam [4:0] UMLALL = 20; // Unsigned multiply accumulate (Write lower reg).
-localparam [4:0] UMLALH = 21;
-
-localparam [4:0] SMLALL = 22; // Signed multiply accumulate (Write lower reg).
-localparam [4:0] SMLALH = 23;
-
-localparam [4:0] CLZ = 24; // Count Leading zeros.
-
-// Conditionals defined as per v5T spec.
-localparam EQ = 4'h0;
-localparam NE = 4'h1;
-localparam CS = 4'h2;
-localparam CC = 4'h3;
-localparam MI = 4'h4;
-localparam PL = 4'h5;
-localparam VS = 4'h6;
-localparam VC = 4'h7;
-localparam HI = 4'h8;
-localparam LS = 4'h9;
-localparam GE = 4'hA;
-localparam LT = 4'hB;
-localparam GT = 4'hC;
-localparam LE = 4'hD;
-localparam AL = 4'hE;
-localparam NV = 4'hF; // NeVer execute!
-
-// CPSR flags.
-localparam N = 31;
-localparam Z = 30;
-localparam C = 29;
-localparam V = 28;
-localparam I = 7;
-localparam F = 6;
-localparam T = 5;
-
-// For transferring indices/immediates across stages.
-localparam INDEX_EN = 1'd0;
-localparam IMMED_EN = 1'd1;
-
-// Processor Modes
-localparam FIQ = 5'b10_001;
-localparam IRQ = 5'b10_010;
-localparam ABT = 5'b10_111;
-localparam SVC = 5'b10_011;
-localparam USR = 5'b10_000;
-localparam SYS = 5'b11_111;
-localparam UND = 5'b11_011;
-
-// Instruction definitions.
-/* ARM */
-
-localparam [31:0] DATA_PROCESSING_IMMEDIATE = 32'b????_00_1_????_?_????_????_????????????;
-localparam [31:0] DATA_PROCESSING_REGISTER_SPECIFIED_SHIFT = 32'b????_00_0_????_?_????_????_????0??1????;
-localparam [31:0] DATA_PROCESSING_INSTRUCTION_SPECIFIED_SHIFT = 32'b????_00_0_????_?_????_????_???????0????;
-
-// BL never reaches the unit.
-localparam [31:0] BRANCH_INSTRUCTION = 32'b????_101?_????_????_????_????_????_????;
-
-localparam [31:0] MRS = 32'b????_00010_?_001111_????_????_????_????;
-localparam [31:0] MSR_IMMEDIATE = 32'b????_00_1_10?10_????_1111_????_????_????;
-
-localparam [31:0] MSR = 32'b????_00_0_10?10_????_1111_????_????_????;
-
-localparam [31:0] LS_INSTRUCTION_SPECIFIED_SHIFT = 32'b????_01_1_?????_????_????_????_????_????;
-localparam [31:0] LS_IMMEDIATE = 32'b????_01_0_?????_????_????_????_????_????;
-
-localparam [31:0] BX_INST = 32'b????_0001_0010_1111_1111_1111_0001_????;
-
-localparam [31:0] MULT_INST = 32'b????_0000_00?_?_????_????_????_1001_????;
-
-// M MULT INST - UMULL, UMLAL, SMULL, SMLAL.
-localparam [31:0] LMULT_INST = 32'b????_0000_1??_?_????_????_????_1001_????;
-
-// Halfword memory.
-localparam [31:0] HALFWORD_LS = 32'b????_000_?????_????_????_????_1??1_????;
-
-// Software interrupt.
-localparam [31:0] SOFTWARE_INTERRUPT = 32'b????_1111_????_????_????_????_????_????;
-
-// Swap.
-localparam [31:0] SWAP = 32'b????_00010_?_00_????_????_00001001_????;
-
-// Write to coprocessor.
-localparam [31:0] MCR = 32'b????_1110_???_0_????_????_1111_???_1_????;
-localparam [31:0] MCR2 = 32'b1111_1110???0_????????????_???1_????;
-
-// Read from coprocessor.
-localparam [31:0] MRC = 32'b????_1110_???_1_????_????_1111_???_1_????;
-localparam [31:0] MRC2 = 32'b1111_1110???1_????????????_???1_????;
-
-// LDC, STC
-localparam [31:0] LDC = 32'b????_110_????1_????_????_????_????????;
-localparam [31:0] STC = 32'b????_110_????0_????_????_????_????????;
-
-// LDC2, STC2
-localparam [31:0] LDC2 = 32'b1111_110????1_????????????_????_????;
-localparam [31:0] STC2 = 32'b1111_110????0_????????????_????_????;
-
-// CDP
-localparam [31:0] CDP = 32'b????_1110_????????_????????_????????;
-
-// 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_????????;
-
-// Shifts.
-localparam [15:0] T_SHIFT = 16'b000_??_?????_???_???;
-
-// Add sub LO.
-localparam [15:0] T_ADD_SUB_LO = 16'b00011_?_?_???_???_???;
-
-// MCAS Imm.
-localparam [15:0] T_MCAS_IMM = 16'b001_??_???_????????;
-
-// ALU Lo.
-localparam [15:0] T_ALU_LO = 16'b010000_????_???_???;
-
-// ALU hi.
-localparam [15:0] T_ALU_HI = 16'b010001_??_?_?_???_???;
-
-// *Get address.
-localparam [15:0] T_GET_ADDR = 16'b1010_?_???_????????;
-
-// *Add offset to SP.
-localparam [15:0] T_MOD_SP = 16'b10110000_?_????_???;
-
-// PC relative load.
-localparam [15:0] T_PC_REL_LOAD = 16'b01001_???_????????;
-
-// LDR_STR_5BIT_OFF
-localparam [15:0] T_LDR_STR_5BIT_OFF = 16'b011_?_?_?????_???_???;
-
-// LDRH_STRH_5BIT_OFF
-localparam [15:0] T_LDRH_STRH_5BIT_OFF = 16'b1000_?_?????_???_???;
-
-// Signed LDR/STR
-localparam [15:0] T_LDRH_STRH_REG = 16'b0101_???_???_???_???;
-
-// SP relative LDR/STR
-localparam [15:0] T_SP_REL_LDR_STR = 16'b1001_?_???_????????;
-
-// LDMIA/STMIA
-localparam [15:0] T_LDMIA_STMIA = 16'b1100_?_???_????????;
-
-// PUSH POP
-localparam [15:0] T_POP_PUSH = 16'b1011_?_10_?_????????;
-
-//
-// Architectural Registers.
-// Architectural registers are registered defined by the architecture plus
-// a few more. Basically instructions index into architectural registers.
-//
-localparam [3:0] ARCH_SP = 13;
-localparam [3:0] ARCH_LR = 14;
-localparam [3:0] ARCH_PC = 15;
-localparam RAZ_REGISTER = 16; // Serves as $0 does on MIPS.
-
-// These always point to user registers irrespective of mode.
-localparam ARCH_USR2_R8 = 18;
-localparam ARCH_USR2_R9 = 19;
-localparam ARCH_USR2_R10 = 20;
-localparam ARCH_USR2_R11 = 21;
-localparam ARCH_USR2_R12 = 22;
-localparam ARCH_USR2_R13 = 23;
-localparam ARCH_USR2_R14 = 24;
-
-// Dummy architectural registers.
-localparam ARCH_DUMMY_REG0 = 25;
-localparam ARCH_DUMMY_REG1 = 26;
-
-// CPSR and SPSR.
-localparam ARCH_CPSR = 17;
-localparam ARCH_CURR_SPSR = 27; // Alias to real SPSR.
-
-// Total architectural registers.
-localparam TOTAL_ARCH_REGS = 28;
-
-//
-// Physical registers.
-// Physical registers can be mapped directly into the internal
-// register file.
-//
-localparam PHY_PC = 15; // DO NOT CHANGE!
-localparam PHY_RAZ_REGISTER = 16; // DO NOT CHANGE!
-localparam PHY_CPSR = 17; // DO NOT CHANGE!
-
-localparam PHY_USR_R0 = 0;
-localparam PHY_USR_R1 = 1;
-localparam PHY_USR_R2 = 2;
-localparam PHY_USR_R3 = 3;
-localparam PHY_USR_R4 = 4;
-localparam PHY_USR_R5 = 5;
-localparam PHY_USR_R6 = 6;
-localparam PHY_USR_R7 = 7;
-localparam PHY_USR_R8 = 8;
-localparam PHY_USR_R9 = 9;
-localparam PHY_USR_R10 = 10;
-localparam PHY_USR_R11 = 11;
-localparam PHY_USR_R12 = 12;
-localparam PHY_USR_R13 = 13;
-localparam PHY_USR_R14 = 14;
-
-localparam PHY_FIQ_R8 = 18;
-localparam PHY_FIQ_R9 = 19;
-localparam PHY_FIQ_R10 = 20;
-localparam PHY_FIQ_R11 = 21;
-localparam PHY_FIQ_R12 = 22;
-localparam PHY_FIQ_R13 = 23;
-localparam PHY_FIQ_R14 = 24;
-
-localparam PHY_IRQ_R13 = 25;
-localparam PHY_IRQ_R14 = 26;
-
-localparam PHY_SVC_R13 = 27;
-localparam PHY_SVC_R14 = 28;
-
-localparam PHY_UND_R13 = 29;
-localparam PHY_UND_R14 = 30;
-
-localparam PHY_ABT_R13 = 31;
-localparam PHY_ABT_R14 = 32;
-
-// Dummy registers for various purposes.
-localparam PHY_DUMMY_REG0 = 33;
-localparam PHY_DUMMY_REG1 = 34;
-
-// SPSRs.
-localparam PHY_FIQ_SPSR = 35;
-localparam PHY_IRQ_SPSR = 36;
-localparam PHY_SVC_SPSR = 37;
-localparam PHY_UND_SPSR = 38;
-localparam PHY_ABT_SPSR = 39;
-
-//
-// Count of total registers
-// (Can go up to 64 with no problems). Used to set register index widths of
-// the control signals.
-//
-localparam TOTAL_PHY_REGS = 40;
-
-// Shift type.
-localparam [1:0] LSL = 0;
-localparam [1:0] LSR = 1;
-localparam [1:0] ASR = 2;
-localparam [1:0] ROR = 3;
-localparam [2:0] RRC = 4; // Encoded as ROR #0.
-localparam [2:0] RORI = 5;
-localparam [2:0] ROR_1= 6; // ROR with instruction specified shift.
-
-// Wishbone CTI.
-localparam CTI_CLASSIC = 3'b000;
-localparam CTI_BURST = 3'b010;
-localparam CTI_EOB = 3'b111;
Index: zap/trunk/src/rtl/cpu/zap_wb_adapter.v
===================================================================
--- zap/trunk/src/rtl/cpu/zap_wb_adapter.v (revision 57)
+++ zap/trunk/src/rtl/cpu/zap_wb_adapter.v (nonexistent)
@@ -1,307 +0,0 @@
-// -----------------------------------------------------------------------------
-// -- --
-// -- (C) 2016-2018 Revanth Kamaraj. --
-// -- --
-// -- --------------------------------------------------------------------------
-// -- --
-// -- This program is free software; you can redistribute it and/or --
-// -- modify it under the terms of the GNU General Public License --
-// -- as published by the Free Software Foundation; either version 2 --
-// -- of the License, or (at your option) any later version. --
-// -- --
-// -- This program 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 General Public License for more details. --
-// -- --
-// -- You should have received a copy of the GNU General Public License --
-// -- along with this program; if not, write to the Free Software --
-// -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA --
-// -- 02110-1301, USA. --
-// -- --
-// -----------------------------------------------------------------------------
-// -- --
-// -- Implements store FIFO. Serves as a bridge between the processor core & --
-// -- the memory interface. --
-// -- --
-// -----------------------------------------------------------------------------
-
-`default_nettype none
-
-module zap_wb_adapter #(parameter DEPTH = 32) (
-
-// Clock.
-input wire i_clk,
-input wire i_reset,
-
-// Processor Wishbone interface. These come from the Wishbone registered
-// interface.
-input wire I_WB_CYC,
-input wire I_WB_STB,
-input wire [3:0] I_WB_SEL,
-input wire [2:0] I_WB_CTI,
-input wire [31:0] I_WB_ADR,
-input wire [31:0] I_WB_DAT,
-input wire I_WB_WE,
-output reg [31:0] O_WB_DAT,
-output reg O_WB_ACK,
-
-// Wishbone interface.
-output reg o_wb_cyc,
-output reg o_wb_stb,
-output wire [31:0] o_wb_dat,
-output wire [31:0] o_wb_adr,
-output wire [3:0] o_wb_sel,
-output wire [2:0] o_wb_cti,
-output wire o_wb_we,
-input wire [31:0] i_wb_dat,
-input wire i_wb_ack,
-
-output reg o_wb_stb_nxt,
-output reg o_wb_cyc_nxt,
-output wire [3:0] o_wb_sel_nxt,
-output wire [31:0] o_wb_dat_nxt,
-output wire [31:0] o_wb_adr_nxt,
-output wire o_wb_we_nxt
-
-);
-
-`include "zap_defines.vh"
-`include "zap_localparams.vh"
-
-reg fsm_write_en;
-reg [69:0] fsm_write_data;
-wire w_eob;
-wire w_full;
-wire w_eob_nxt;
-
-assign o_wb_cti = {w_eob, 1'd1, w_eob};
-
-wire w_emp;
-
-// {SEL, DATA, ADDR, EOB, WEN} = 4 + 64 + 1 + 1 = 70 bit.
-zap_sync_fifo #(.WIDTH(70), .DEPTH(DEPTH), .FWFT(1'd0), .PROVIDE_NXT_DATA(1)) U_STORE_FIFO (
-.i_clk (i_clk),
-.i_reset (i_reset),
-.i_ack ((i_wb_ack && o_wb_stb) || emp_ff),
-.i_wr_en (fsm_write_en),
-.i_data (fsm_write_data),
-.o_data ({o_wb_sel, o_wb_dat, o_wb_adr, w_eob, o_wb_we}),
-.o_data_nxt ({o_wb_sel_nxt, o_wb_dat_nxt, o_wb_adr_nxt, w_eob_nxt, o_wb_we_nxt}),
-.o_empty (w_emp),
-.o_full (w_full),
-.o_empty_n (),
-.o_full_n (),
-.o_full_n_nxt ()
-);
-
-reg emp_nxt;
-reg emp_ff;
-reg [31:0] ctr_nxt, ctr_ff;
-reg [31:0] dff, dnxt;
-reg ack; // ACK write channel.
-reg ack_ff; // Read channel.
-
-localparam IDLE = 0;
-localparam PRPR_RD_SINGLE = 1;
-localparam PRPR_RD_BURST = 2;
-localparam WRITE = 3;
-localparam WAIT1 = 5;
-localparam WAIT2 = 6;
-localparam NUMBER_OF_STATES = 7;
-
-reg [$clog2(NUMBER_OF_STATES)-1:0] state_ff, state_nxt;
-
-// FIFO pipeline register and nxt state logic.
-always @ (*)
-begin
- emp_nxt = emp_ff;
- o_wb_stb_nxt = o_wb_stb;
- o_wb_cyc_nxt = o_wb_cyc;
-
- if ( i_reset )
- begin
- emp_nxt = 1'd1;
- o_wb_stb_nxt = 1'd0;
- o_wb_cyc_nxt = 1'd0;
- end
- else if ( emp_ff || (i_wb_ack && o_wb_stb) )
- begin
- emp_nxt = w_emp;
- o_wb_stb_nxt = !w_emp;
- o_wb_cyc_nxt = !w_emp;
- end
-end
-
-always @ (posedge i_clk)
-begin
- emp_ff <= emp_nxt;
- o_wb_stb <= o_wb_stb_nxt;
- o_wb_cyc <= o_wb_cyc_nxt;
-end
-
-// Flip flop clocking block.
-always @ (posedge i_clk)
-begin
- if ( i_reset )
- begin
- state_ff <= IDLE;
- ctr_ff <= 0;
- dff <= 0;
- end
- else
- begin
- state_ff <= state_nxt;
- ctr_ff <= ctr_nxt;
- dff <= dnxt;
- end
-end
-
-// Reads from the Wishbone bus are flopped.
-always @ (posedge i_clk)
-begin
- if ( i_reset )
- begin
- ack_ff <= 1'd0;
- end
- else if ( !o_wb_we && o_wb_cyc && o_wb_stb && i_wb_ack )
- begin
- ack_ff <= 1'd1;
- O_WB_DAT <= i_wb_dat;
- end
- else
- begin
- ack_ff <= 1'd0;
- end
-end
-
-localparam BURST_LEN = 4;
-
-// OR from flop and mealy FSM output.
-always @* O_WB_ACK = ack_ff | ack;
-
-// State machine.
-always @*
-begin
- state_nxt = state_ff;
- ctr_nxt = ctr_ff;
- ack = 0;
- dnxt = dff;
- fsm_write_en = 0;
- fsm_write_data = 0;
-
- case(state_ff)
- IDLE:
- begin
- ctr_nxt = 0;
- dnxt = 0;
-
- if ( I_WB_STB && I_WB_WE && !o_wb_stb ) // Wishbone write request
- begin
- // Simply buffer stores into the FIFO.
- state_nxt = WRITE;
- end
- else if ( I_WB_STB && !I_WB_WE && !o_wb_stb ) // Wishbone read request
- begin
- // Write a set of reads into the FIFO.
- if ( I_WB_CTI == CTI_BURST ) // Burst of 4 words. Each word is 4 byte.
- begin
- state_nxt = PRPR_RD_BURST;
- end
- else // Single.
- begin
- state_nxt = PRPR_RD_SINGLE;
- end
- end
- end
-
- PRPR_RD_SINGLE: // Write a single read token into the FIFO.
- begin
- if ( !w_full )
- begin
- state_nxt = WAIT1;
- fsm_write_en = 1'd1;
- fsm_write_data = { I_WB_SEL,
- I_WB_DAT,
- I_WB_ADR,
- I_WB_CTI != CTI_BURST ? 1'd1 : 1'd0,
- 1'd0};
- end
- end
-
- PRPR_RD_BURST: // Write burst read requests into the FIFO.
- begin
- if ( O_WB_ACK )
- begin
- dnxt = dff + 1'd1;
- end
-
- if ( ctr_ff == BURST_LEN * 4 )
- begin
- ctr_nxt = 0;
- state_nxt = WAIT2; // FIFO prep done.
- end
- else if ( !w_full )
- begin: blk1
- reg [31:0] adr;
- adr = {I_WB_ADR[31:4], 4'd0} + ctr_ff; // Ignore lower 4-bits.
-
- fsm_write_en = 1'd1;
- fsm_write_data = { I_WB_SEL,
- I_WB_DAT,
- adr,
- ctr_ff == 12 ? 1'd1 : 1'd0,
- 1'd0 };
- ctr_nxt = ctr_ff + 4;
- end
- end
-
- WRITE:
- begin
- // As long as requests exist, write them out to the FIFO.
- if ( I_WB_STB && I_WB_WE )
- begin
- if ( !w_full )
- begin
- fsm_write_en = 1'd1;
- fsm_write_data = {I_WB_SEL, I_WB_DAT, I_WB_ADR, I_WB_CTI != CTI_BURST ? 1'd1 : 1'd0, 1'd1};
- ack = 1'd1;
- end
- end
- else // Writes done!
- begin
- state_nxt = IDLE;
- end
- end
-
- WAIT1: // Wait for single read to complete.
- begin
- if ( O_WB_ACK )
- begin
- state_nxt = IDLE;
- end
- end
-
- WAIT2: // Wait for burst reads to complete.
- begin
- if ( O_WB_ACK )
- begin
- dnxt = dff + 1;
- end
-
- if ( dff == BURST_LEN && !o_wb_stb )
- begin
- state_nxt = IDLE;
- end
- end
-
- endcase
-end
-
-endmodule
-
-`default_nettype wire
-
-// ----------------------------------------------------------------------------
-// EOF
-// ----------------------------------------------------------------------------
Index: zap/trunk/src/rtl/cpu/zap_cache_fsm.v
===================================================================
--- zap/trunk/src/rtl/cpu/zap_cache_fsm.v (revision 57)
+++ zap/trunk/src/rtl/cpu/zap_cache_fsm.v (nonexistent)
@@ -1,578 +0,0 @@
-// -----------------------------------------------------------------------------
-// -- --
-// -- (C) 2016-2018 Revanth Kamaraj. --
-// -- --
-// -- --------------------------------------------------------------------------
-// -- --
-// -- This program is free software; you can redistribute it and/or --
-// -- modify it under the terms of the GNU General Public License --
-// -- as published by the Free Software Foundation; either version 2 --
-// -- of the License, or (at your option) any later version. --
-// -- --
-// -- This program 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 General Public License for more details. --
-// -- --
-// -- You should have received a copy of the GNU General Public License --
-// -- along with this program; if not, write to the Free Software --
-// -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA --
-// -- 02110-1301, USA. --
-// -- --
-// -----------------------------------------------------------------------------
-// -- --
-// -- This is the core state machine for the memory subsystem. Talks to both --
-// -- processor and the TLB controller. Cache uploads and downloads are done --
-// -- using an incrementing burst on the Wishbone bus for maximum efficiency --
-// -- --
-// -----------------------------------------------------------------------------
-
-`default_nettype none
-
-`include "zap_defines.vh"
-
-module zap_cache_fsm #(
- parameter CACHE_SIZE = 1024 // Bytes.
-)
-
-// ----------------------------------------------
-// Port List
-// ----------------------------------------------
-
-(
-
-/* Clock and reset */
-input wire i_clk,
-input wire i_reset,
-
-/* From/to processor */
-input wire [31:0] i_address,
-input wire i_rd,
-input wire i_wr,
-input wire [31:0] i_din,
-input wire [3:0] i_ben, /* Valid only for writes. */
-output reg [31:0] o_dat,
-output reg o_ack,
-output reg o_err,
-output reg [7:0] o_fsr,
-output reg [31:0] o_far,
-
-/* From/To CP15 unit */
-input wire i_cache_en,
-input wire i_cache_inv,
-input wire i_cache_clean,
-output reg o_cache_inv_done,
-output reg o_cache_clean_done,
-
-/* From/to cache. */
-input wire [127:0] i_cache_line,
-
-input wire i_cache_tag_dirty,
-input wire [`CACHE_TAG_WDT-1:0] i_cache_tag, // Tag
-input wire i_cache_tag_valid,
-
-output reg [`CACHE_TAG_WDT-1:0] o_cache_tag,
-output reg o_cache_tag_dirty,
-output reg o_cache_tag_wr_en,
-
-output reg [127:0] o_cache_line,
-output reg [15:0] o_cache_line_ben, /* Write + Byte enable */
-
-output reg o_cache_clean_req,
-input wire i_cache_clean_done,
-
-output reg o_cache_inv_req,
-input wire i_cache_inv_done,
-
-/* From/to TLB unit */
-input wire [31:0] i_phy_addr,
-input wire [7:0] i_fsr,
-input wire [31:0] i_far,
-input wire i_fault,
-input wire i_cacheable,
-input wire i_busy,
-
-/* Memory access ports, both NXT and FF. Usually you'll be connecting NXT ports */
-output reg o_wb_cyc_ff, o_wb_cyc_nxt,
-output reg o_wb_stb_ff, o_wb_stb_nxt,
-output reg [31:0] o_wb_adr_ff, o_wb_adr_nxt,
-output reg [31:0] o_wb_dat_ff, o_wb_dat_nxt,
-output reg [3:0] o_wb_sel_ff, o_wb_sel_nxt,
-output reg o_wb_wen_ff, o_wb_wen_nxt,
-output reg [2:0] o_wb_cti_ff, o_wb_cti_nxt,/* Cycle Type Indicator - 010, 111 */
-input wire i_wb_ack,
-input wire [31:0] i_wb_dat
-
-);
-
-// ----------------------------------------------------------------------------
-// Includes and Localparams
-// ----------------------------------------------------------------------------
-
-`include "zap_localparams.vh"
-`include "zap_defines.vh"
-`include "zap_functions.vh"
-
-/* States */
-localparam IDLE = 0; /* Resting state. */
-localparam UNCACHEABLE = 1; /* Uncacheable access. */
-localparam REFRESH_1 = 2; /* Cache write hit state. Unused. */
-localparam CLEAN_SINGLE = 3; /* Ultimately cleans up cache line. Parent state */
-localparam FETCH_SINGLE = 4; /* Ultimately validates cache line. Parent state */
-localparam REFRESH = 5; /* Cache refresh parent state */
-localparam INVALIDATE = 6; /* Cache invalidate parent state */
-localparam CLEAN = 7; /* Cache clean parent state */
-localparam NUMBER_OF_STATES = 8;
-
-// ----------------------------------------------------------------------------
-// Signal aliases
-// ----------------------------------------------------------------------------
-
-wire cache_cmp = (i_cache_tag[`CACHE_TAG__TAG] == i_address[`VA__CACHE_TAG]);
-wire cache_dirty = i_cache_tag_dirty;
-
-// ----------------------------------------------------------------------------
-// Variables
-// ----------------------------------------------------------------------------
-
-reg [$clog2(NUMBER_OF_STATES)-1:0] state_ff, state_nxt;
-reg [31:0] buf_ff [3:0];
-reg [31:0] buf_nxt[3:0];
-reg cache_clean_req_nxt,
- cache_clean_req_ff;
-reg cache_inv_req_nxt,
- cache_inv_req_ff;
-reg [2:0] adr_ctr_ff, adr_ctr_nxt; // Needs to take on 0,1,2,3 AND 4(nxt).
-reg hit; // For debug only.
-
-// ----------------------------------------------------------------------------
-// Logic
-// ----------------------------------------------------------------------------
-
-/* Tie flops to the output */
-always @* o_cache_clean_req = cache_clean_req_ff; // Tie req flop to output.
-always @* o_cache_inv_req = cache_inv_req_ff; // Tie inv flop to output.
-
-/* Sequential Block */
-always @ (posedge i_clk)
-begin
- if ( i_reset )
- begin
- o_wb_cyc_ff <= 0;
- o_wb_stb_ff <= 0;
- o_wb_wen_ff <= 0;
- o_wb_sel_ff <= 0;
- o_wb_dat_ff <= 0;
- o_wb_cti_ff <= CTI_CLASSIC;
- o_wb_adr_ff <= 0;
- cache_clean_req_ff <= 0;
- cache_inv_req_ff <= 0;
- adr_ctr_ff <= 0;
- state_ff <= IDLE;
- end
- else
- begin
- o_wb_cyc_ff <= o_wb_cyc_nxt;
- o_wb_stb_ff <= o_wb_stb_nxt;
- o_wb_wen_ff <= o_wb_wen_nxt;
- o_wb_sel_ff <= o_wb_sel_nxt;
- o_wb_dat_ff <= o_wb_dat_nxt;
- o_wb_cti_ff <= o_wb_cti_nxt;
- o_wb_adr_ff <= o_wb_adr_nxt;
- cache_clean_req_ff <= cache_clean_req_nxt;
- cache_inv_req_ff <= cache_inv_req_nxt;
- adr_ctr_ff <= adr_ctr_nxt;
- state_ff <= state_nxt;
- buf_ff[0] <= buf_nxt[0];
- buf_ff[1] <= buf_nxt[1];
- buf_ff[2] <= buf_nxt[2];
- buf_ff[3] <= buf_nxt[3];
- end
-end
-
-/* Combo block */
-always @*
-begin
- /* Default values */
- state_nxt = state_ff;
- adr_ctr_nxt = adr_ctr_ff;
- o_wb_cyc_nxt = o_wb_cyc_ff;
- o_wb_stb_nxt = o_wb_stb_ff;
- o_wb_adr_nxt = o_wb_adr_ff;
- o_wb_dat_nxt = o_wb_dat_ff;
- o_wb_cti_nxt = o_wb_cti_ff;
- o_wb_wen_nxt = o_wb_wen_ff;
- o_wb_sel_nxt = o_wb_sel_ff;
- cache_clean_req_nxt = cache_clean_req_ff;
- cache_inv_req_nxt = cache_clean_req_ff;
- o_fsr = 0;
- o_far = 0;
- o_cache_tag = 0;
- o_cache_inv_done = 0;
- o_cache_clean_done = 0;
- o_cache_tag_dirty = 0;
- o_cache_tag_wr_en = 0;
- o_cache_line = 0;
- o_cache_line_ben = 0;
- o_dat = 0;
- o_ack = 0;
- o_err = 0;
- buf_nxt[0] = buf_ff[0];
- buf_nxt[1] = buf_ff[1];
- buf_nxt[2] = buf_ff[2];
- buf_nxt[3] = buf_ff[3];
- hit = 0;
-
- case(state_ff)
-
- IDLE:
- begin
- kill_access;
-
- if ( i_cache_inv )
- begin
- o_ack = 1'd0;
- state_nxt = INVALIDATE;
- end
- else if ( i_cache_clean )
- begin
- o_ack = 1'd0;
- state_nxt = CLEAN;
- end
- else if ( i_fault )
- begin
- /* MMU access fault. */
- o_err = 1'd1;
- o_ack = 1'd1;
- o_fsr = i_fsr;
- o_far = i_far;
- end
- else if ( i_busy )
- begin
- /* Wait it out */
- end
- else if ( i_rd || i_wr )
- begin
- if ( i_cacheable && i_cache_en )
- begin
- case ({cache_cmp,i_cache_tag_valid})
-
- 2'b11: /* Cache hit */
- begin
- if ( i_rd ) /* Read request. */
- begin
- /*
- * Accelerate performance
- * Read throughput at 80MHz
- * clock is 80M operations per
- * second (Hit).
- */
- o_dat = adapt_cache_data(i_address[3:2], i_cache_line);
- hit = 1'd1;
- o_ack = 1'd1;
- end
- else if ( i_wr ) /* Write request */
- begin
- state_nxt = REFRESH_1;
- o_ack = 1'd0;
-
- /*
- * Each write to cache takes
- * 3 cycles. Write throuput at
- * 80MHz is 26.6M operations per
- * second (Hit).
- */
- o_cache_line =
- {i_din,i_din,i_din,i_din};
-
- o_cache_line_ben = ben_comp ( i_address[3:2], i_ben );
-
- /* Write to tag and also write out physical address. */
- o_cache_tag_wr_en = 1'd1;
- o_cache_tag[`CACHE_TAG__TAG] = i_address[`VA__CACHE_TAG];
- o_cache_tag_dirty = 1'd1;
- o_cache_tag[`CACHE_TAG__PA] = i_phy_addr >> 4;
-
-
- end
- end
-
- 2'b01: /* Unrelated tag, possibly dirty. */
- begin
- /* CPU should wait */
- o_ack = 1'd0;
-
- if ( cache_dirty )
- begin
- /* Set up counter */
- adr_ctr_nxt = 0;
-
- /* Clean a single cache line */
- state_nxt = CLEAN_SINGLE;
- end
- else if ( i_rd | i_wr )
- begin
- /* Set up counter */
- adr_ctr_nxt = 0;
-
- /* Fetch a single cache line */
- state_nxt = FETCH_SINGLE;
- end
- end
-
- default: /* Need to generate a new tag. */
- begin
- /* CPU should wait. */
- o_ack = 1'd0;
-
- /* Set up counter */
- adr_ctr_nxt = 0;
-
- /* Fetch a single cache line */
- state_nxt = FETCH_SINGLE;
- end
- endcase
- end
- else /* Decidedly non cacheable. */
- begin
- state_nxt = UNCACHEABLE;
- o_ack = 1'd0; /* Wait...*/
- o_wb_stb_nxt = 1'd1;
- o_wb_cyc_nxt = 1'd1;
- o_wb_adr_nxt = i_phy_addr;
- o_wb_dat_nxt = i_din;
- o_wb_wen_nxt = i_wr;
- o_wb_sel_nxt = i_ben; // Was i_wr ? i_ben : 4'b1111
- o_wb_cti_nxt = CTI_CLASSIC;
- end
- end
- end
-
- UNCACHEABLE: /* Uncacheable reads and writes definitely go through this. */
- begin
- if ( i_wb_ack )
- begin
- o_dat = i_wb_dat;
- o_ack = 1'd1;
- state_nxt = IDLE;
- kill_access;
- end
- end
-
- REFRESH_1: /* A single wait state is needed to handle B2B write-read */
- begin
- kill_access;
- state_nxt = REFRESH;
- o_ack = 1'd0;
- end
-
- CLEAN_SINGLE: /* Clean single cache line */
- begin
- o_ack = 1'd0;
-
- /* Generate address */
- adr_ctr_nxt = adr_ctr_ff + (o_wb_stb_ff && i_wb_ack);
-
- if ( adr_ctr_nxt <= 3 )
- begin
- /* Sync up with memory. Use PA in cache tag itself. */
- wb_prpr_write( clean_single_d (i_cache_line, adr_ctr_nxt),
- {i_cache_tag[`CACHE_TAG__PA], 4'd0} + (adr_ctr_nxt << 2),
- adr_ctr_nxt != 3 ? CTI_BURST : CTI_EOB, 4'b1111);
- end
- else
- begin
- /* Move to wait state */
- kill_access;
- state_nxt = REFRESH_1;
-
- /* Update tag. Remove dirty bit. */
- o_cache_tag_wr_en = 1'd1; // Implicitly sets valid (redundant).
- o_cache_tag[`CACHE_TAG__TAG] = i_cache_tag[`VA__CACHE_TAG]; // Preserve.
- o_cache_tag_dirty = 1'd0;
- o_cache_tag[`CACHE_TAG__PA] = i_cache_tag[`CACHE_TAG__PA]; // Preserve.
- end
- end
-
- FETCH_SINGLE: /* Fetch a single cache line */
- begin
-
- o_ack = 1'd0;
-
- /* Generate address */
- adr_ctr_nxt = adr_ctr_ff + (o_wb_stb_ff && i_wb_ack);
-
- /* Write to buffer */
- buf_nxt[adr_ctr_ff] = i_wb_ack ? i_wb_dat : buf_ff[adr_ctr_ff];
-
- /* Manipulate buffer as needed */
- if ( i_wr )
- begin
- buf_nxt[i_address[3:2]][7:0] = i_ben[0] ? i_din[7:0] : buf_nxt[i_address[3:2]][7:0];
- buf_nxt[i_address[3:2]][15:8] = i_ben[1] ? i_din[15:8] : buf_nxt[i_address[3:2]][15:8];
- buf_nxt[i_address[3:2]][23:16] = i_ben[2] ? i_din[23:16] : buf_nxt[i_address[3:2]][23:16];
- buf_nxt[i_address[3:2]][31:24] = i_ben[3] ? i_din[31:24] : buf_nxt[i_address[3:2]][31:24];
- end
-
- if ( adr_ctr_nxt <= 3 )
- begin
-
- /* Fetch line from memory */
- wb_prpr_read({i_phy_addr[31:4], 4'd0} + (adr_ctr_nxt << 2),
- adr_ctr_nxt != 3 ? CTI_BURST : CTI_EOB);
- end
- else
- begin
-
- /* Update cache */
- o_cache_line = {buf_nxt[3], buf_ff[2], buf_ff[1], buf_ff[0]};
- o_cache_line_ben = 16'b1111111111111111;
-
- /* Update tag. Remove dirty and set valid */
- o_cache_tag_wr_en = 1'd1; // Implicitly sets valid.
- o_cache_tag[`CACHE_TAG__TAG] = i_address[`VA__CACHE_TAG];
- o_cache_tag[`CACHE_TAG__PA] = i_phy_addr >> 4;
- o_cache_tag_dirty = !i_wr ? 1'd0 : 1'd1; // BUG FIX.
-
- /* Move to wait state */
- kill_access;
- state_nxt = REFRESH_1;
- end
- end
-
- REFRESH: /* One extra cycle for cache and tag to update. */
- begin
- kill_access;
- o_ack = i_wr && cache_cmp;
- state_nxt = IDLE;
- end
-
- INVALIDATE: /* Invalidate the cache - Almost Single Cycle */
- begin
- cache_inv_req_nxt = 1'd1;
- cache_clean_req_nxt = 1'd0;
-
- if ( i_cache_inv_done )
- begin
- cache_inv_req_nxt = 1'd0;
- state_nxt = IDLE;
- o_cache_inv_done = 1'd1;
- end
- end
-
- CLEAN: /* Force cache to clean itself */
- begin
- cache_clean_req_nxt = 1'd1;
- cache_inv_req_nxt = 1'd0;
-
- if ( i_cache_clean_done )
- begin
- cache_clean_req_nxt = 1'd0;
- state_nxt = IDLE;
- o_cache_clean_done = 1'd1;
- end
- end
-
- endcase
-end
-
-// ----------------------------------------------------------------------------
-// Tasks and functions.
-// ----------------------------------------------------------------------------
-
-function [31:0] adapt_cache_data
-(input [1:0] shift, input [127:0] cd);
-begin: blk1
- reg [31:0] shamt;
- shamt = shift << 5;
- adapt_cache_data = cd >> shamt;
-end
-endfunction
-
-function [15:0] ben_comp ( input [1:0] shift, input [3:0] bv );
-begin:fblk2
- reg [31:0] shamt;
- shamt = shift << 2;
- ben_comp = bv << shamt;
-end
-endfunction
-
-function [31:0] clean_single_d ( input [127:0] cl, input [31:0] sh );
-reg [31:0] shamt;
-begin
- shamt = sh << 5;
- clean_single_d = cl >> shamt; // Select specific 32-bit.
-end
-endfunction
-
-/* Function to generate Wishbone read signals. */
-task wb_prpr_read;
-input [31:0] i_address;
-input [2:0] i_cti;
-begin
- o_wb_cyc_nxt = 1'd1;
- o_wb_stb_nxt = 1'd1;
- o_wb_wen_nxt = 1'd0;
- o_wb_sel_nxt = 4'b1111;
- o_wb_adr_nxt = i_address;
- o_wb_cti_nxt = i_cti;
- o_wb_dat_nxt = 0;
-end
-endtask
-
-/* Function to generate Wishbone write signals */
-task wb_prpr_write;
-input [31:0] i_data;
-input [31:0] i_address;
-input [2:0] i_cti;
-input [3:0] i_ben;
-begin
- o_wb_cyc_nxt = 1'd1;
- o_wb_stb_nxt = 1'd1;
- o_wb_wen_nxt = 1'd1;
- o_wb_sel_nxt = i_ben;
- o_wb_adr_nxt = i_address;
- o_wb_cti_nxt = i_cti;
- o_wb_dat_nxt = i_data;
-end
-endtask
-
-/* Disables Wishbone */
-task kill_access;
-begin
- o_wb_cyc_nxt = 0;
- o_wb_stb_nxt = 0;
- o_wb_wen_nxt = 0;
- o_wb_adr_nxt = 0;
- o_wb_dat_nxt = 0;
- o_wb_sel_nxt = 0;
- o_wb_cti_nxt = CTI_CLASSIC;
-end
-endtask
-
-// ----------------------------------------------------------------------------
-
-wire [31:0] buf0_ff, buf1_ff, buf2_ff;
-
-assign buf0_ff = buf_ff[0];
-assign buf1_ff = buf_ff[1];
-assign buf2_ff = buf_ff[2];
-
-wire [31:0] buf3_ff = buf_ff[3];
-wire [31:0] buf0_nxt = buf_nxt[0];
-wire [31:0] buf1_nxt = buf_nxt[1];
-wire [31:0] buf2_nxt = buf_nxt[2];
-wire [31:0] buf3_nxt = buf_nxt[3];
-
-wire [31:0] dbg_addr_tag = i_address[`VA__CACHE_TAG];
-wire [31:0] dbg_addr_pa = i_phy_addr >> 4;
-wire [31:0] dbg_ct_tag = o_cache_tag[`CACHE_TAG__TAG];
-wire [31:0] dbg_ct_pa = o_cache_tag[`CACHE_TAG__PA];
-
-endmodule // zap_cache_fsm
-
-`default_nettype wire
-
-// ----------------------------------------------------------------------------
-// END OF FILE
-// ----------------------------------------------------------------------------
Index: zap/trunk/src/rtl/cpu/zap_shifter_main.v
===================================================================
--- zap/trunk/src/rtl/cpu/zap_shifter_main.v (revision 57)
+++ zap/trunk/src/rtl/cpu/zap_shifter_main.v (nonexistent)
@@ -1,405 +0,0 @@
-// -----------------------------------------------------------------------------
-// -- --
-// -- (C) 2016-2018 Revanth Kamaraj. --
-// -- --
-// -- --------------------------------------------------------------------------
-// -- --
-// -- This program is free software; you can redistribute it and/or --
-// -- modify it under the terms of the GNU General Public License --
-// -- as published by the Free Software Foundation; either version 2 --
-// -- of the License, or (at your option) any later version. --
-// -- --
-// -- This program 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 General Public License for more details. --
-// -- --
-// -- You should have received a copy of the GNU General Public License --
-// -- along with this program; if not, write to the Free Software --
-// -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA --
-// -- 02110-1301, USA. --
-// -- --
-// -----------------------------------------------------------------------------
-// --
-// -- The ZAP shift unit. Apart from shift, it does value restoration and
-// -- multiplication. Value restoration is needed since the ALU (Shift+Op) is
-// -- pipelined and we want back to back instructions to execute correctly without
-// -- losing throughput. Note that there are 3 execution pathways in this unit
-// -- but a given time, only one pathway may be active. The 3 execution pathways
-// -- are: shifter, multiplier, value feedback network.
-// --
-// ----------------------------------------------------------------------------
-
-
-`default_nettype none
-module zap_shifter_main
-#(
- parameter PHY_REGS = 46,
- parameter ALU_OPS = 32,
- parameter SHIFT_OPS = 5
-)
-(
- // For debug
- input wire [64*8-1:0] i_decompile,
- output reg [64*8-1:0] o_decompile,
-
- // Clock and reset.
- input wire i_clk,
- input wire i_reset,
-
- // PC
- input wire [31:0] i_pc_ff,
- output reg [31:0] o_pc_ff,
-
- // Taken.
- input wire [1:0] i_taken_ff,
- output reg [1:0] o_taken_ff,
-
- // Stall and clear. Hi to low priority.
- input wire i_clear_from_writeback, // | High Priority.
- input wire i_data_stall, // |
- input wire i_clear_from_alu, // V Low Priority.
-
- // Next CPSR and FF CPSR.
- input wire [31:0] i_cpsr_nxt, i_cpsr_ff,
-
- //
- // Things from Issue. Please see issue stage for signal details.
- //
-
- input wire [3:0] i_condition_code_ff,
- input wire [$clog2(PHY_REGS )-1:0] i_destination_index_ff,
- input wire [$clog2(ALU_OPS)-1:0] i_alu_operation_ff,
- input wire [$clog2(SHIFT_OPS)-1:0] i_shift_operation_ff,
- input wire i_flag_update_ff,
-
- input wire [$clog2(PHY_REGS )-1:0] i_mem_srcdest_index_ff,
- input wire i_mem_load_ff,
- input wire i_mem_store_ff,
- input wire i_mem_pre_index_ff,
- input wire i_mem_unsigned_byte_enable_ff,
- input wire i_mem_signed_byte_enable_ff,
- input wire i_mem_signed_halfword_enable_ff,
- input wire i_mem_unsigned_halfword_enable_ff,
- input wire i_mem_translate_ff,
-
- input wire i_irq_ff,
- input wire i_fiq_ff,
- input wire i_abt_ff,
- input wire i_swi_ff,
-
- // Indices/immediates enter here.
- input wire [32:0] i_alu_source_ff,
- input wire i_alu_dav_nxt,
- input wire [32:0] i_shift_source_ff,
-
- // Values are obtained here.
- input wire [31:0] i_alu_source_value_ff,
- input wire [31:0] i_shift_source_value_ff,
- input wire [31:0] i_shift_length_value_ff,
- input wire [31:0] i_mem_srcdest_value_ff, // This too has to be resolved.
- // For stores.
-
- // The PC value.
- input wire [31:0] i_pc_plus_8_ff,
-
- // Shifter disable indicator. In the next stage, the output
- // will bypass the shifter. Not actually bypass it but will
- // go to the ALU value corrector unit via a MUX.
- input wire i_disable_shifter_ff,
-
- // undefined instr.
- input wire i_und_ff,
- output reg o_und_ff,
-
- // Value from ALU for resolver.
- input wire [31:0] i_alu_value_nxt,
-
- // Force 32.
- input wire i_force32align_ff,
- output reg o_force32align_ff,
-
- // ARM <-> Compressed switch indicator.
- input wire i_switch_ff,
- output reg o_switch_ff,
-
- //
- // Outputs.
- //
-
- // Specific to this stage.
- output reg [31:0] o_mem_srcdest_value_ff,
- output reg [31:0] o_alu_source_value_ff,
- output reg [31:0] o_shifted_source_value_ff,
- output reg o_shift_carry_ff,
- output reg o_nozero_ff,
-
- // Send all other outputs.
-
- // PC+8
- output reg [31:0] o_pc_plus_8_ff,
-
- // Interrupts.
- output reg o_irq_ff,
- output reg o_fiq_ff,
- output reg o_abt_ff,
- output reg o_swi_ff,
-
- // Memory related outputs.
- output reg [$clog2(PHY_REGS )-1:0] o_mem_srcdest_index_ff,
- output reg o_mem_load_ff,
- output reg o_mem_store_ff,
- output reg o_mem_pre_index_ff,
- output reg o_mem_unsigned_byte_enable_ff,
- output reg o_mem_signed_byte_enable_ff,
- output reg o_mem_signed_halfword_enable_ff,
- output reg o_mem_unsigned_halfword_enable_ff,
- output reg o_mem_translate_ff,
-
- // Other stuff.
- output reg [3:0] o_condition_code_ff,
- output reg [$clog2(PHY_REGS )-1:0] o_destination_index_ff,
- output reg [$clog2(ALU_OPS)-1:0] o_alu_operation_ff,
- output reg o_flag_update_ff,
-
- // Stall from shifter.
- output wire o_stall_from_shifter
-);
-
-///////////////////////////////////////////////////////////////////////////////
-
-`include "zap_defines.vh"
-`include "zap_localparams.vh"
-`include "zap_functions.vh"
-
-///////////////////////////////////////////////////////////////////////////////
-
-wire nozero_nxt;
-wire [31:0] shout;
-wire shcarry;
-reg [31:0] mem_srcdest_value;
-reg [31:0] rm, rn;
-reg shift_carry_nxt;
-wire shifter_enabled = !i_disable_shifter_ff;
-
-wire [31:0] mult_out;
-
-///////////////////////////////////////////////////////////////////////////////
-
-// The MAC unit.
-zap_shifter_multiply
-#(
- .PHY_REGS(PHY_REGS),
- .ALU_OPS(ALU_OPS)
-)
-u_zap_multiply
-(
- .i_clk(i_clk),
- .i_reset(i_reset),
-
- .i_data_stall(i_data_stall),
- .i_clear_from_writeback(i_clear_from_writeback),
- .i_clear_from_alu(i_clear_from_alu),
-
- .i_alu_operation_ff(i_alu_operation_ff),
-
- .i_cc_satisfied (i_condition_code_ff == 4'd15 ? 1'd0 : 1'd1),
- // ( is_cc_satisfied ( i_condition_code_ff, i_cpsr_nxt[31:28] ) )
- // -- Causing timing issues in Xilinx ISE.
-
- .i_rm(i_alu_source_value_ff),
- .i_rn(i_shift_length_value_ff),
- .i_rs(i_shift_source_value_ff), // rm.rs + {rh,rn}
- .i_rh(i_mem_srcdest_value_ff),
-
- .o_rd(mult_out),
- .o_busy(o_stall_from_shifter),
- .o_nozero(nozero_nxt)
-);
-
-///////////////////////////////////////////////////////////////////////////////
-
-task clear; // Clear the unit out.
-begin
- o_condition_code_ff <= NV;
- o_irq_ff <= 0;
- o_fiq_ff <= 0;
- o_abt_ff <= 0;
- o_swi_ff <= 0;
- o_und_ff <= 0;
-end
-endtask
-
-///////////////////////////////////////////////////////////////////////////////
-
-always @ (posedge i_clk)
-begin
- if ( i_reset )
- begin
- clear;
- end
- else if ( i_clear_from_writeback )
- begin
- clear;
- end
- else if ( i_data_stall )
- begin
- // Preserve values.
- end
- else if ( i_clear_from_alu )
- begin
- clear;
- end
- else
- begin
- o_condition_code_ff <= i_condition_code_ff;
- o_destination_index_ff <= i_destination_index_ff;
- o_alu_operation_ff <= (i_alu_operation_ff == UMLALL ||
- i_alu_operation_ff == UMLALH ||
- i_alu_operation_ff == SMLALL ||
- i_alu_operation_ff == SMLALH) ?
- MOV : i_alu_operation_ff;
- o_flag_update_ff <= i_flag_update_ff;
- o_mem_srcdest_index_ff <= i_mem_srcdest_index_ff;
- o_mem_load_ff <= i_mem_load_ff;
- o_mem_store_ff <= i_mem_store_ff;
- o_mem_pre_index_ff <= i_mem_pre_index_ff;
- o_mem_unsigned_byte_enable_ff <= i_mem_unsigned_byte_enable_ff;
- o_mem_signed_byte_enable_ff <= i_mem_signed_byte_enable_ff;
- o_mem_signed_halfword_enable_ff <= i_mem_signed_halfword_enable_ff;
- o_mem_unsigned_halfword_enable_ff <= i_mem_unsigned_halfword_enable_ff;
- o_mem_translate_ff <= i_mem_translate_ff;
- o_irq_ff <= i_irq_ff;
- o_fiq_ff <= i_fiq_ff;
- o_abt_ff <= i_abt_ff;
- o_swi_ff <= i_swi_ff;
- o_pc_plus_8_ff <= i_pc_plus_8_ff;
- o_mem_srcdest_value_ff <= mem_srcdest_value;
- o_alu_source_value_ff <= rn;
- o_shifted_source_value_ff <= rm;
- o_shift_carry_ff <= shift_carry_nxt;
- o_switch_ff <= i_switch_ff;
- o_und_ff <= i_und_ff;
- o_force32align_ff <= i_force32align_ff;
- o_taken_ff <= i_taken_ff;
- o_pc_ff <= i_pc_ff;
- o_nozero_ff <= nozero_nxt;
-
- // For debug
- o_decompile <= i_decompile;
- end
-end
-
-///////////////////////////////////////////////////////////////////////////////
-
-// Barrel shifter.
-zap_shift_shifter #(
- .SHIFT_OPS(SHIFT_OPS)
-)
-U_SHIFT
-(
- .i_source ( i_shift_source_value_ff ),
- .i_amount ( i_shift_length_value_ff[7:0] ),
- .i_shift_type ( i_shift_operation_ff ),
- .i_carry ( i_cpsr_ff[29] ),
- .o_result ( shout ),
- .o_carry ( shcarry )
-);
-
-///////////////////////////////////////////////////////////////////////////////
-
-// Resolve conflict for ALU source value (rn)
-always @*
-begin
-
- rn = resolve_conflict ( i_alu_source_ff, i_alu_source_value_ff,
- o_destination_index_ff, i_alu_value_nxt, i_alu_dav_nxt );
-
-
-end
-
-///////////////////////////////////////////////////////////////////////////////
-
-// Resolve conflict for shifter source value.
-always @*
-begin
- // If we issue a multiply.
- if ( i_alu_operation_ff == UMLALL || i_alu_operation_ff == UMLALH ||
- i_alu_operation_ff == SMLALL || i_alu_operation_ff == SMLALH )
- begin
- // Get result from multiplier.
- rm = mult_out;
-
- // Carry is set to a MEANINGLESS value. Zero in this case.
- shift_carry_nxt = 1'd0;
- end
- else if( shifter_enabled ) // Shifter enabled if valid shift is asked for.
- begin
- // Get result from shifter.
- rm = shout;
-
- // Get carry from shifter
- shift_carry_nxt = shcarry;
- end
- else
- begin
- // Resolve conflict.
- rm = resolve_conflict ( i_shift_source_ff, i_shift_source_value_ff,
- o_destination_index_ff, i_alu_value_nxt, i_alu_dav_nxt );
-
- // Do not touch the carry. Get from _nxt for back2back execution.
- shift_carry_nxt = i_cpsr_nxt[29];
- end
-end
-
-///////////////////////////////////////////////////////////////////////////////
-
-// Mem srcdest index. Used for
-// stores. Resolve conflict.
-always @*
-begin
- mem_srcdest_value = resolve_conflict ( i_mem_srcdest_index_ff, i_mem_srcdest_value_ff,
- o_destination_index_ff, i_alu_value_nxt, i_alu_dav_nxt );
-end
-
-///////////////////////////////////////////////////////////////////////////////
-
-// This will resolve conflicts for back to back instruction execution.
-// The function entirely depends only on the inputs to the function.
-function [31:0] resolve_conflict (
- input [32:0] index_from_issue, // Index from issue stage. Could have immed too.
- input [31:0] value_from_issue, // Issue speculatively read value.
- input [$clog2(PHY_REGS)-1:0] index_from_this_stage, // From shift (This) stage output flops.
- input [31:0] result_from_alu, // From ALU output directly.
- input result_from_alu_valid // Result from ALU is VALID.
-);
-begin
-
- if ( index_from_issue[32] == IMMED_EN )
- begin
- resolve_conflict = index_from_issue[31:0];
- end
- else if ( index_from_issue == PHY_PC )
- begin
- resolve_conflict = i_pc_plus_8_ff;
- end
- else if ( index_from_this_stage == index_from_issue[$clog2(PHY_REGS)-1:0] && result_from_alu_valid )
- begin
- resolve_conflict = result_from_alu;
- end
- else
- begin
- resolve_conflict = value_from_issue[31:0];
- end
-end
-endfunction
-
-///////////////////////////////////////////////////////////////////////////////
-
-endmodule // zap_shifter_main.v
-
-`default_nettype wire
-
-// ----------------------------------------------------------------------------
-// EOF
-// ----------------------------------------------------------------------------
Index: zap/trunk/src/rtl/cpu/zap_wb_merger.v
===================================================================
--- zap/trunk/src/rtl/cpu/zap_wb_merger.v (revision 57)
+++ zap/trunk/src/rtl/cpu/zap_wb_merger.v (nonexistent)
@@ -1,165 +0,0 @@
-// -----------------------------------------------------------------------------
-// -- --
-// -- (C) 2016-2018 Revanth Kamaraj. --
-// -- --
-// -- --------------------------------------------------------------------------
-// -- --
-// -- This program is free software; you can redistribute it and/or --
-// -- modify it under the terms of the GNU General Public License --
-// -- as published by the Free Software Foundation; either version 2 --
-// -- of the License, or (at your option) any later version. --
-// -- --
-// -- This program 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 General Public License for more details. --
-// -- --
-// -- You should have received a copy of the GNU General Public License --
-// -- along with this program; if not, write to the Free Software --
-// -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA --
-// -- 02110-1301, USA. --
-// -- --
-// -----------------------------------------------------------------------------
-// -- --
-// -- Merges two Wishbone busses onto a single bus. One side can from the --
-// -- instruction cache while the other from data cache. This module can --
-// -- be used to connect any 2 generic Wishbone devices. --
-// -- --
-// -----------------------------------------------------------------------------
-
-`default_nettype none
-
-module zap_wb_merger (
-
-// Clock and reset
-input wire i_clk,
-input wire i_reset,
-
-// Wishbone bus 1
-input wire i_c_wb_stb,
-input wire i_c_wb_cyc,
-input wire i_c_wb_wen,
-input wire [3:0] i_c_wb_sel,
-input wire [31:0] i_c_wb_dat,
-input wire [31:0] i_c_wb_adr,
-input wire [2:0] i_c_wb_cti,
-output reg o_c_wb_ack,
-
-// Wishbone bus 2
-input wire i_d_wb_stb,
-input wire i_d_wb_cyc,
-input wire i_d_wb_wen,
-input wire [3:0] i_d_wb_sel,
-input wire [31:0] i_d_wb_dat,
-input wire [31:0] i_d_wb_adr,
-input wire [2:0] i_d_wb_cti,
-output reg o_d_wb_ack,
-
-// Common bus
-output reg o_wb_cyc,
-output reg o_wb_stb,
-output reg o_wb_wen,
-output reg [3:0] o_wb_sel,
-output reg [31:0] o_wb_dat,
-output reg [31:0] o_wb_adr,
-output reg [2:0] o_wb_cti,
-input wire i_wb_ack
-
-);
-
-`include "zap_defines.vh"
-`include "zap_localparams.vh"
-
-localparam CODE = 1'd0;
-localparam DATA = 1'd1;
-
-reg sel_ff, sel_nxt;
-
-always @ (posedge i_clk)
-begin
- if ( i_reset )
- sel_ff <= CODE;
- else
- sel_ff <= sel_nxt;
-end
-
-always @*
-begin
- if ( sel_ff == CODE )
- begin
- o_c_wb_ack = i_wb_ack;
- o_d_wb_ack = 1'd0;
- end
- else
- begin
- o_d_wb_ack = i_wb_ack;
- o_c_wb_ack = 1'd0;
- end
-end
-
-always @*
-begin
- case(sel_ff)
- CODE:
- begin
- if ( i_wb_ack && (o_wb_cti == CTI_CLASSIC || o_wb_cti == CTI_EOB) && i_d_wb_stb )
- sel_nxt = DATA;
- else if ( !i_c_wb_stb && i_d_wb_stb )
- sel_nxt = DATA;
- else
- sel_nxt = sel_ff;
- end
-
- DATA:
- begin
- if ( i_wb_ack && (o_wb_cti == CTI_CLASSIC || o_wb_cti == CTI_EOB) && i_c_wb_stb )
- sel_nxt = CODE;
- else if ( i_c_wb_stb && !i_d_wb_stb )
- sel_nxt = CODE;
- else
- sel_nxt = sel_ff;
- end
- endcase
-end
-
-always @ (posedge i_clk)
-begin
- if ( i_reset )
- begin
- o_wb_cyc <= 0;
- o_wb_stb <= 0;
- o_wb_wen <= 0;
- o_wb_sel <= 0;
- o_wb_dat <= 0;
- o_wb_adr <= 0;
- o_wb_cti <= 0;
- end
- else if ( sel_nxt == CODE )
- begin
- o_wb_cyc <= i_c_wb_cyc;
- o_wb_stb <= i_c_wb_stb;
- o_wb_wen <= i_c_wb_wen;
- o_wb_sel <= i_c_wb_sel;
- o_wb_dat <= i_c_wb_dat;
- o_wb_adr <= i_c_wb_adr;
- o_wb_cti <= i_c_wb_cti;
- end
- else
- begin
- o_wb_cyc <= i_d_wb_cyc;
- o_wb_stb <= i_d_wb_stb;
- o_wb_wen <= i_d_wb_wen;
- o_wb_sel <= i_d_wb_sel;
- o_wb_dat <= i_d_wb_dat;
- o_wb_adr <= i_d_wb_adr;
- o_wb_cti <= i_d_wb_cti;
- end
-end
-
-endmodule
-
-`default_nettype wire
-
-// ----------------------------------------------------------------------------
-// EOF
-// ----------------------------------------------------------------------------
Index: zap/trunk/src/rtl/cpu/zap_memory_main.v
===================================================================
--- zap/trunk/src/rtl/cpu/zap_memory_main.v (revision 57)
+++ zap/trunk/src/rtl/cpu/zap_memory_main.v (nonexistent)
@@ -1,289 +0,0 @@
-// ------------------------------------------------------------------------------
-// -- --
-// -- (C) 2016-2018 Revanth Kamaraj. --
-// -- --
-// -- ---------------------------------------------------------------------------
-// -- --
-// -- This program is free software; you can redistribute it and/or --
-// -- modify it under the terms of the GNU General Public License --
-// -- as published by the Free Software Foundation; either version 2 --
-// -- of the License, or (at your option) any later version. --
-// -- --
-// -- This program 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 General Public License for more details. --
-// -- --
-// -- You should have received a copy of the GNU General Public License --
-// -- along with this program; if not, write to the Free Software --
-// -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA --
-// -- 02110-1301, USA. --
-// -- --
-// ------------------------------------------------------------------------------
-// -- --
-// -- This stage merely acts as a buffer in between the ALU stage and the reg.--
-// -- file (i.e., writeback stage). 32-bit data received from the cache is --
-// -- is rotated appropriately here in case of byte reads or halfword reads. --
-// -- Otherwise, this stage is simply a buffer. --
-// -- --
-// ------------------------------------------------------------------------------
-
-`default_nettype none
-module zap_memory_main
-#(
- // Width of CPSR.
- parameter FLAG_WDT = 32,
-
- // Number of physical registers.
- parameter PHY_REGS = 46
-)
-(
- // Debug
- input wire [64*8-1:0] i_decompile,
- output reg [64*8-1:0] o_decompile,
-
- // Clock and reset.
- input wire i_clk,
- input wire i_reset,
-
- // Pipeline control signals.
- input wire i_clear_from_writeback,
- input wire i_data_stall,
-
- // Memory stuff.
- input wire i_mem_load_ff,
- input wire [31:0] i_mem_address_ff, // Access Address.
-
- // Data read from memory.
- input wire [31:0] i_mem_rd_data,
-
- // Memory fault transfer. i_mem_fault comes from the cache unit.
- input wire i_mem_fault, // Fault in.
- output reg o_mem_fault, // Fault out.
-
- // Data valid and buffered PC.
- input wire i_dav_ff,
- input wire [31:0] i_pc_plus_8_ff,
-
- // ALU value, flags,and where to write the value.
- input wire [31:0] i_alu_result_ff,
- input wire [FLAG_WDT-1:0] i_flags_ff,
- input wire [$clog2(PHY_REGS)-1:0] i_destination_index_ff,
-
- // Interrupts.
- input wire i_irq_ff,
- input wire i_fiq_ff,
- input wire i_instr_abort_ff,
- input wire i_swi_ff,
-
- // Memory SRCDEST index. For loads, this tells the register file where
- // to put the read data. Set to point to RAZ if invalid.
- input wire [$clog2(PHY_REGS)-1:0] i_mem_srcdest_index_ff,
-
- // SRCDEST value.
- input wire [31:0] i_mem_srcdest_value_ff,
-
- // Memory size and type.
- input wire i_sbyte_ff,
- i_ubyte_ff,
- i_shalf_ff,
- i_uhalf_ff,
-
- // Undefined instr.
- input wire i_und_ff,
- output reg o_und_ff,
-
- // ALU result and flags.
- output reg [31:0] o_alu_result_ff,
- output reg [FLAG_WDT-1:0] o_flags_ff,
-
- // Where to write ALU and memory read target register.
- output reg [$clog2(PHY_REGS)-1:0] o_destination_index_ff,
-
- // Set to point to the RAZ register if invalid.
- output reg [$clog2(PHY_REGS)-1:0] o_mem_srcdest_index_ff,
-
- // Outputs valid and PC buffer.
- output reg o_dav_ff,
- output reg [31:0] o_pc_plus_8_ff,
-
- // The whole interrupt signaling scheme.
- output reg o_irq_ff,
- output reg o_fiq_ff,
- output reg o_swi_ff,
- output reg o_instr_abort_ff,
-
- // Memory load information is passed down.
- output reg o_mem_load_ff,
- output reg [31:0] o_mem_rd_data
-);
-
-`include "zap_defines.vh"
-`include "zap_localparams.vh"
-`include "zap_functions.vh"
-
-reg i_mem_load_ff2 ;
-reg [31:0] i_mem_srcdest_value_ff2 ;
-reg [31:0] i_mem_address_ff2 ;
-reg i_sbyte_ff2 ;
-reg i_ubyte_ff2 ;
-reg i_shalf_ff2 ;
-reg i_uhalf_ff2 ;
-reg [31:0] mem_rd_data ;
-
-// Invalidates the outptus of this stage.
-task clear;
-begin
- // Invalidate stage.
- o_dav_ff <= 0;
-
- // Clear interrupts.
- o_irq_ff <= 0;
- o_fiq_ff <= 0;
- o_swi_ff <= 0;
- o_instr_abort_ff <= 0;
- o_und_ff <= 0;
- o_mem_fault <= 0;
-end
-endtask
-
-// On reset or on a clear from WB, we will disable the vectors
-// in this unit. Else, we will just flop everything out.
-always @ (posedge i_clk)
-if ( i_reset )
-begin
- clear;
-end
-else if ( i_clear_from_writeback )
-begin
- clear;
-end
-else if ( i_data_stall )
-begin
- // Stall unit. Outputs do not change.
- o_dav_ff <= 1'd0;
-end
-else
-begin
- // Just flop everything out.
- o_alu_result_ff <= i_alu_result_ff;
- o_flags_ff <= i_flags_ff;
- o_mem_srcdest_index_ff<= i_mem_srcdest_index_ff;
- o_dav_ff <= i_dav_ff;
- o_destination_index_ff<= i_destination_index_ff;
- o_pc_plus_8_ff <= i_pc_plus_8_ff;
- o_irq_ff <= i_irq_ff;
- o_fiq_ff <= i_fiq_ff;
- o_swi_ff <= i_swi_ff;
- o_instr_abort_ff <= i_instr_abort_ff;
- o_mem_load_ff <= i_mem_load_ff;
- o_und_ff <= i_und_ff;
- o_mem_fault <= i_mem_fault;
- mem_rd_data <= i_mem_rd_data;
-
- // Debug.
- o_decompile <= i_decompile;
-end
-
-// Manual Pipeline Retiming.
-always @ (posedge i_clk)
-begin
- if ( !i_data_stall )
- begin
- i_mem_load_ff2 <= i_mem_load_ff;
- i_mem_srcdest_value_ff2 <= i_mem_srcdest_value_ff;
- i_mem_address_ff2 <= i_mem_address_ff;
- i_sbyte_ff2 <= i_sbyte_ff;
- i_ubyte_ff2 <= i_ubyte_ff;
- i_shalf_ff2 <= i_shalf_ff;
- i_uhalf_ff2 <= i_uhalf_ff;
- end
-end
-
-always @*
-o_mem_rd_data = transform((i_mem_load_ff2 ? mem_rd_data :
- i_mem_srcdest_value_ff2), i_mem_address_ff2[1:0],
- i_sbyte_ff2, i_ubyte_ff2, i_shalf_ff2, i_uhalf_ff2,
- i_mem_load_ff2);
-
-// Memory always loads 32-bit to processor.
-// We will rotate that here as we wish.
-
-function [31:0] transform (
-
- // Data and address.
- input [31:0] data,
- input [1:0] address,
-
- // Memory access data type.
- input sbyte,
- input ubyte,
- input shalf,
- input uhalf,
-
- // Memory load.
- input mem_load_ff
-);
-begin: transform_function
- reg [31:0] d; // Data shorthand.
-
- transform = 32'd0;
- d = data;
-
- // Unsigned byte. Take only lower byte.
- if ( ubyte == 1'd1 )
- begin
- case ( address[1:0] )
- 0: transform = (d >> 0) & 32'h000000ff;
- 1: transform = (d >> 8) & 32'h000000ff;
- 2: transform = (d >> 16) & 32'h000000ff;
- 3: transform = (d >> 24) & 32'h000000ff;
- endcase
- end
- // Signed byte. Sign extend lower byte.
- else if ( sbyte == 1'd1 )
- begin
- // Take lower byte.
- case ( address[1:0] )
- 0: transform = (d >> 0) & 32'h000000ff;
- 1: transform = (d >> 8) & 32'h000000ff;
- 2: transform = (d >> 16) & 32'h000000ff;
- 3: transform = (d >> 24) & 32'h000000ff;
- endcase
-
- // Sign extend.
- transform = $signed(transform[7:0]);
- end
- // Signed half word. Sign extend lower 16-bit.
- else if ( shalf == 1'd1 )
- begin
- case ( address[1] )
- 0: transform = (d >> 0) & 32'h0000ffff;
- 1: transform = (d >> 16) & 32'h0000ffff;
- endcase
-
- transform = $signed(transform[15:0]);
- end
- // Unsigned half word. Take only lower 16-bit.
- else if ( uhalf == 1'd1 )
- begin
- case ( address[1] )
- 0: transform = (d >> 0) & 32'h0000ffff;
- 1: transform = (d >> 16) & 32'h0000ffff;
- endcase
- end
- else // Default. Typically, a word.
- begin
- transform = data;
- end
-
- // Override above computation if not a memory load.
- if ( !mem_load_ff )
- begin
- transform = data; // No memory load means pass data on.
- end
-end
-endfunction
-
-endmodule
-`default_nettype wire
Index: zap/trunk/src/rtl/cpu/zap_sync_fifo.v
===================================================================
--- zap/trunk/src/rtl/cpu/zap_sync_fifo.v (revision 57)
+++ zap/trunk/src/rtl/cpu/zap_sync_fifo.v (nonexistent)
@@ -1,163 +0,0 @@
-// -----------------------------------------------------------------------------
-// -- --
-// -- (C) 2016-2018 Revanth Kamaraj. --
-// -- --
-// -- --------------------------------------------------------------------------
-// -- --
-// -- This program is free software; you can redistribute it and/or --
-// -- modify it under the terms of the GNU General Public License --
-// -- as published by the Free Software Foundation; either version 2 --
-// -- of the License, or (at your option) any later version. --
-// -- --
-// -- This program 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 General Public License for more details. --
-// -- --
-// -- You should have received a copy of the GNU General Public License --
-// -- along with this program; if not, write to the Free Software --
-// -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA --
-// -- 02110-1301, USA. --
-// -- --
-// -----------------------------------------------------------------------------
-// -- This is a simple synchronous FIFO. --
-// -----------------------------------------------------------------------------
-
-`default_nettype none
-
-// FWFT means "First Word Fall Through".
-module zap_sync_fifo #(
- parameter WIDTH = 32,
- parameter DEPTH = 32,
- parameter FWFT = 1,
- parameter PROVIDE_NXT_DATA = 0
-)
-(
- // Clock and reset
- input wire i_clk,
- input wire i_reset,
-
- // Flow control
- input wire i_ack,
- input wire i_wr_en,
-
- // Data busses
- input wire [WIDTH-1:0] i_data,
- output reg [WIDTH-1:0] o_data,
- output reg [WIDTH-1:0] o_data_nxt,
-
- // Flags
- output wire o_empty,
- output wire o_full,
- output wire o_empty_n,
- output wire o_full_n,
- output wire o_full_n_nxt
-);
-
-// Xilinx ISE does not allow $CLOG2 in localparams.
-parameter PTR_WDT = $clog2(DEPTH) + 32'd1;
-parameter [PTR_WDT-1:0] DEFAULT = {PTR_WDT{1'd0}};
-
-// Variables
-reg [PTR_WDT-1:0] rptr_ff;
-reg [PTR_WDT-1:0] rptr_nxt;
-reg [PTR_WDT-1:0] wptr_ff;
-reg empty, nempty;
-reg full, nfull;
-reg [PTR_WDT-1:0] wptr_nxt;
-reg [WIDTH-1:0] mem [DEPTH-1:0];
-wire [WIDTH-1:0] dt;
-reg [WIDTH-1:0] dt1;
-reg sel_ff;
-reg [WIDTH-1:0] bram_ff;
-reg [WIDTH-1:0] dt_ff;
-
-// Assigns
-assign o_empty = empty;
-assign o_full = full;
-assign o_empty_n = nempty;
-assign o_full_n = nfull;
-assign o_full_n_nxt = i_reset ? 1 :
- !( ( wptr_nxt[PTR_WDT-2:0] == rptr_nxt[PTR_WDT-2:0] ) &&
- ( wptr_nxt != rptr_nxt ) );
-
-
-// FIFO write logic.
-always @ (posedge i_clk)
- if ( i_wr_en && !o_full )
- mem[wptr_ff[PTR_WDT-2:0]] <= i_data;
-
-// FIFO read logic
-generate
-begin:gb1
- if ( FWFT == 1 )
- begin:f1
- // Retimed output data compared to normal FIFO.
- always @ (posedge i_clk)
- begin
- dt_ff <= i_data;
- sel_ff <= ( i_wr_en && (wptr_ff == rptr_nxt) );
- bram_ff <= mem[rptr_nxt[PTR_WDT-2:0]];
- end
-
- // Output signal steering MUX.
- always @*
- begin
- o_data = sel_ff ? dt_ff : bram_ff;
- o_data_nxt = 0; // Tied off.
- end
- end
- else
- begin:f0
- always @ (posedge i_clk)
- begin
- if ( i_ack && nempty ) // Read request and not empty.
- begin
- o_data <= mem [ rptr_ff[PTR_WDT-2:0] ];
- end
- end
-
- if ( PROVIDE_NXT_DATA )
- begin: f11
- always @ (*)
- begin
- if ( i_ack && nempty )
- o_data_nxt = mem [ rptr_ff[PTR_WDT-2:0] ];
- else
- o_data_nxt = o_data;
- end
- end
- else
- begin: f22
- always @* o_data_nxt = 0;
- end
- end
-end
-endgenerate
-
-// Flip-flop update.
-always @ (posedge i_clk)
-begin
- dt1 <= i_reset ? 0 : i_data;
- rptr_ff <= i_reset ? 0 : rptr_nxt;
- wptr_ff <= i_reset ? 0 : wptr_nxt;
- empty <= i_reset ? 1 : ( wptr_nxt == rptr_nxt );
- nempty <= i_reset ? 0 : ( wptr_nxt != rptr_nxt );
- nfull <= o_full_n_nxt;
- full <= !o_full_n_nxt;
-end
-
-// Pointer updates.
-always @*
-begin
- wptr_nxt = wptr_ff + (i_wr_en && !o_full);
- rptr_nxt = rptr_ff + (i_ack && !o_empty);
-end
-
-endmodule // zap_sync_fifo
-
-`default_nettype wire
-
-// ----------------------------------------------------------------------------
-// EOF
-// ----------------------------------------------------------------------------
Index: zap/trunk/src/rtl/cpu/zap_functions.vh
===================================================================
--- zap/trunk/src/rtl/cpu/zap_functions.vh (revision 57)
+++ zap/trunk/src/rtl/cpu/zap_functions.vh (nonexistent)
@@ -1,195 +0,0 @@
-// -----------------------------------------------------------------------------
-// -- --
-// -- (C) 2016-2018 Revanth Kamaraj. --
-// -- --
-// -- --------------------------------------------------------------------------
-// -- --
-// -- This program is free software; you can redistribute it and/or --
-// -- modify it under the terms of the GNU General Public License --
-// -- as published by the Free Software Foundation; either version 2 --
-// -- of the License, or (at your option) any later version. --
-// -- --
-// -- This program 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 General Public License for more details. --
-// -- --
-// -- You should have received a copy of the GNU General Public License --
-// -- along with this program; if not, write to the Free Software --
-// -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA --
-// -- 02110-1301, USA. --
-// -- --
-// -----------------------------------------------------------------------------
-
-// ----------------------------------------------------------------------------
-
-//
-// Function to generate clog2. $clog2 used instead in most places.
-//
-function [31:0] zap_clog2 ( input [31:0] x );
- for(zap_clog2 = 0 ; 2**zap_clog2 < x ; zap_clog2 = zap_clog2 + 1)
- begin
- // Some compilers do not support empty loops.
- end
-endfunction
-
-// ----------------------------------------------------------------------------
-
-//
-// Function to check if condition is satisfied for instruction
-// execution. Returns 1 if satisfied, 0 if not.
-//
-
-function is_cc_satisfied
-(
- input [3:0] cc, // 31:28 of the instruction.
- input [3:0] fl // CPSR flags.
-);
-reg ok,n,z,c,v;
-begin: blk1
- {n,z,c,v} = fl;
-
- case(cc)
- EQ: ok = z;
- NE: ok = !z;
- CS: ok = c;
- CC: ok = !c;
- MI: ok = n;
- PL: ok = !n;
- VS: ok = v;
- VC: ok = !v;
- HI: ok = c && !z;
- LS: ok = !c || z;
- GE: ok = (n == v);
- LT: ok = (n != v);
- GT: ok = (n == v) && !z;
- LE: ok = (n != v) || z;
- AL: ok = 1'd1;
- NV: ok = 1'd0;
- endcase
-
- is_cc_satisfied = ok;
-end
-endfunction
-
-// ----------------------------------------------------------------------------
-
-
-// ----------------------------------------------------------------------------
-
-//
-// Translate function.
-//
-//
-// Used to implement ARM modes. The register file is basically a flat array
-// of registers. Based on mode, we select some of those to implement banking.
-//
-
-function [5:0] translate (
-
- input [5:0] index, // Requested instruction index.
- input [4:0] cpu_mode // Current CPU mode.
-
-);
-begin
- translate = index; // Avoid latch inference.
-
- // User/System mode assignments.
- case ( index )
- 0: translate = PHY_USR_R0;
- 1: translate = PHY_USR_R1;
- 2: translate = PHY_USR_R2;
- 3: translate = PHY_USR_R3;
- 4: translate = PHY_USR_R4;
- 5: translate = PHY_USR_R5;
- 6: translate = PHY_USR_R6;
- 7: translate = PHY_USR_R7;
- 8: translate = PHY_USR_R8;
- 9: translate = PHY_USR_R9;
- 10: translate = PHY_USR_R10;
- 11: translate = PHY_USR_R11;
- 12: translate = PHY_USR_R12;
- 13: translate = PHY_USR_R13;
- 14: translate = PHY_USR_R14;
- 15: translate = PHY_PC;
-
- RAZ_REGISTER: translate = PHY_RAZ_REGISTER;
- ARCH_CPSR: translate = PHY_CPSR;
- ARCH_CURR_SPSR: translate = PHY_CPSR;
-
- // USR2 registers are looped back to USER registers.
- ARCH_USR2_R8: translate = PHY_USR_R8;
- ARCH_USR2_R9: translate = PHY_USR_R9;
- ARCH_USR2_R10: translate = PHY_USR_R10;
- ARCH_USR2_R11: translate = PHY_USR_R11;
- ARCH_USR2_R12: translate = PHY_USR_R12;
- ARCH_USR2_R13: translate = PHY_USR_R13;
- ARCH_USR2_R14: translate = PHY_USR_R14;
-
- ARCH_DUMMY_REG0:translate = PHY_DUMMY_REG0;
- ARCH_DUMMY_REG1:translate = PHY_DUMMY_REG1;
- endcase
-
- // Override per specific mode.
- case ( cpu_mode )
- FIQ:
- begin
- case ( index )
- 8: translate = PHY_FIQ_R8;
- 9: translate = PHY_FIQ_R9;
- 10: translate = PHY_FIQ_R10;
- 11: translate = PHY_FIQ_R11;
- 12: translate = PHY_FIQ_R12;
- 13: translate = PHY_FIQ_R13;
- 14: translate = PHY_FIQ_R14;
- ARCH_CURR_SPSR: translate = PHY_FIQ_SPSR;
- endcase
- end
-
- IRQ:
- begin
- case ( index )
- 13: translate = PHY_IRQ_R13;
- 14: translate = PHY_IRQ_R14;
- ARCH_CURR_SPSR: translate = PHY_IRQ_SPSR;
- endcase
- end
-
- ABT:
- begin
- case ( index )
- 13: translate = PHY_ABT_R13;
- 14: translate = PHY_ABT_R14;
- ARCH_CURR_SPSR: translate = PHY_ABT_SPSR;
- endcase
- end
-
- UND:
- begin
- case ( index )
- 13: translate = PHY_UND_R13;
- 14: translate = PHY_UND_R14;
- ARCH_CURR_SPSR: translate = PHY_UND_SPSR;
- endcase
- end
-
- SVC:
- begin
- case ( index )
- 13: translate = PHY_SVC_R13;
- 14: translate = PHY_SVC_R14;
- ARCH_CURR_SPSR: translate = PHY_SVC_SPSR;
- endcase
- end
-
- default: // To avoid lint warnings.
- begin
- end
- endcase
-end
-endfunction
-
-// ----------------------------------------------------------------------------
-
-
-
Index: zap/trunk/src/rtl/cpu/zap_tlb.v
===================================================================
--- zap/trunk/src/rtl/cpu/zap_tlb.v (revision 57)
+++ zap/trunk/src/rtl/cpu/zap_tlb.v (nonexistent)
@@ -1,243 +0,0 @@
-// -----------------------------------------------------------------------------
-// -- --
-// -- (C) 2016-2018 Revanth Kamaraj. --
-// -- --
-// -- --------------------------------------------------------------------------
-// -- --
-// -- This program is free software; you can redistribute it and/or --
-// -- modify it under the terms of the GNU General Public License --
-// -- as published by the Free Software Foundation; either version 2 --
-// -- of the License, or (at your option) any later version. --
-// -- --
-// -- This program 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 General Public License for more details. --
-// -- --
-// -- You should have received a copy of the GNU General Public License --
-// -- along with this program; if not, write to the Free Software --
-// -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA --
-// -- 02110-1301, USA. --
-// -- --
-// -----------------------------------------------------------------------------
-// --
-// TLB management unit for the ZAP processor. The TLB units use single cycle --
-// clearing memories since TLBs are shallow. --
-// --
-// -----------------------------------------------------------------------------
-
-`default_nettype none
-module zap_tlb #(
-
-parameter LPAGE_TLB_ENTRIES = 8,
-parameter SPAGE_TLB_ENTRIES = 8,
-parameter SECTION_TLB_ENTRIES = 8
-
-) (
-
-// Clock and reset.
-input wire i_clk,
-input wire i_reset,
-
-// From cache FSM (processor)
-input wire [31:0] i_address,
-input wire [31:0] i_address_nxt,
-input wire i_rd,
-input wire i_wr,
-
-// CPSR, SR, DAC register.
-input wire [31:0] i_cpsr,
-input wire [1:0] i_sr,
-input wire [31:0] i_dac_reg,
-input wire [31:0] i_baddr,
-
-// From CP15.
-input wire i_mmu_en,
-input wire i_inv,
-
-// To cache FSM.
-output wire [31:0] o_phy_addr,
-output wire [7:0] o_fsr,
-output wire [31:0] o_far,
-output wire o_fault,
-output wire o_cacheable,
-output wire o_busy,
-
-// Wishbone memory interface - Needs to go through some OR gates.
-output wire o_wb_stb_nxt,
-output wire o_wb_cyc_nxt,
-output wire [31:0] o_wb_adr_nxt,
-output wire o_wb_wen_nxt,
-output wire [3:0] o_wb_sel_nxt,
-input wire [31:0] i_wb_dat,
-output wire [31:0] o_wb_dat_nxt,
-input wire i_wb_ack
-
-);
-
-// ----------------------------------------------------------------------------
-
-assign o_wb_dat_nxt = 32'd0;
-
-`include "zap_localparams.vh"
-`include "zap_defines.vh"
-`include "zap_functions.vh"
-
-wire [`SECTION_TLB_WDT-1:0] setlb_wdata, setlb_rdata;
-wire [`LPAGE_TLB_WDT-1:0] lptlb_wdata, lptlb_rdata;
-wire [`SPAGE_TLB_WDT-1:0] sptlb_wdata, sptlb_rdata;
-wire sptlb_wen, lptlb_wen, setlb_wen;
-wire sptlb_ren, lptlb_ren, setlb_ren;
-wire walk;
-wire [7:0] fsr;
-wire [31:0] far;
-wire cacheable;
-wire [31:0] phy_addr;
-
-// ----------------------------------------------------------------------------
-
-zap_mem_inv_block #(.WIDTH(`SECTION_TLB_WDT), .DEPTH(SECTION_TLB_ENTRIES))
-u_section_tlb (
-.i_clk (i_clk),
-.i_reset (i_reset),
-
-.i_wdata (setlb_wdata),
-.i_wen (setlb_wen),
-.i_ren (1'd1),
-
-.i_inv (i_inv | !i_mmu_en),
-
-.i_raddr (i_address_nxt[`VA__SECTION_INDEX]),
-.i_waddr (i_address[`VA__SECTION_INDEX]),
-
-.o_rdata (setlb_rdata),
-.o_rdav (setlb_ren)
-);
-
-// ----------------------------------------------------------------------------
-
-zap_mem_inv_block #(.WIDTH(`LPAGE_TLB_WDT), .DEPTH(LPAGE_TLB_ENTRIES))
-u_lpage_tlb (
-.i_clk (i_clk),
-.i_reset (i_reset),
-
-.i_wdata (lptlb_wdata),
-.i_wen (lptlb_wen),
-.i_ren (1'd1),
-
-.i_inv (i_inv | !i_mmu_en),
-
-.i_raddr (i_address_nxt[`VA__LPAGE_INDEX]),
-.i_waddr (i_address[`VA__LPAGE_INDEX]),
-
-.o_rdata (lptlb_rdata),
-.o_rdav (lptlb_ren)
-);
-
-// ----------------------------------------------------------------------------
-
-zap_mem_inv_block #(.WIDTH(`SPAGE_TLB_WDT), .DEPTH(SPAGE_TLB_ENTRIES))
-u_spage_tlb (
-.i_clk (i_clk),
-.i_reset (i_reset),
-
-.i_wdata (sptlb_wdata),
-.i_wen (sptlb_wen),
-.i_ren (1'd1),
-
-.i_inv (i_inv | !i_mmu_en),
-
-.i_raddr (i_address_nxt[`VA__SPAGE_INDEX]),
-.i_waddr (i_address[`VA__SPAGE_INDEX]),
-
-.o_rdata (sptlb_rdata),
-.o_rdav (sptlb_ren)
-);
-
-// ----------------------------------------------------------------------------
-
-zap_tlb_check #(
-.LPAGE_TLB_ENTRIES(LPAGE_TLB_ENTRIES),
-.SPAGE_TLB_ENTRIES(SPAGE_TLB_ENTRIES),
-.SECTION_TLB_ENTRIES(SECTION_TLB_ENTRIES))
-u_zap_tlb_check (
-
-.i_mmu_en (i_mmu_en),
-.i_va (i_address),
-.i_rd (i_rd),
-.i_wr (i_wr),
-
-.i_cpsr (i_cpsr),
-.i_sr (i_sr),
-.i_dac_reg (i_dac_reg),
-
-.i_sptlb_rdata (sptlb_rdata),
-.i_sptlb_rdav (sptlb_ren),
-
-.i_lptlb_rdata (lptlb_rdata),
-.i_lptlb_rdav (lptlb_ren),
-
-.i_setlb_rdata (setlb_rdata),
-.i_setlb_rdav (setlb_ren),
-
-.o_walk (walk),
-.o_fsr (fsr),
-.o_far (far),
-.o_cacheable (cacheable),
-.o_phy_addr (phy_addr)
-
-);
-
-// ----------------------------------------------------------------------------
-
-zap_tlb_fsm #(
-.LPAGE_TLB_ENTRIES (LPAGE_TLB_ENTRIES),
-.SPAGE_TLB_ENTRIES (SPAGE_TLB_ENTRIES),
-.SECTION_TLB_ENTRIES (SECTION_TLB_ENTRIES)
-) u_zap_tlb_fsm (
-.o_unused_ok (), // UNCONNECTED. For lint.
-.i_clk (i_clk),
-.i_reset (i_reset),
-.i_mmu_en (i_mmu_en),
-.i_baddr (i_baddr),
-.i_address (i_address),
-.i_walk (walk),
-.i_fsr (fsr),
-.i_far (far),
-.i_cacheable (cacheable),
-.i_phy_addr (phy_addr),
-
-.o_fsr (o_fsr),
-.o_far (o_far),
-.o_fault (o_fault),
-.o_phy_addr (o_phy_addr),
-.o_cacheable (o_cacheable),
-.o_busy (o_busy),
-
-.o_setlb_wdata (setlb_wdata),
-.o_setlb_wen (setlb_wen),
-
-.o_sptlb_wdata (sptlb_wdata),
-.o_sptlb_wen (sptlb_wen),
-
-.o_lptlb_wdata (lptlb_wdata),
-.o_lptlb_wen (lptlb_wen),
-
-.o_wb_cyc (),
-.o_wb_stb (),
-.o_wb_wen (o_wb_wen_nxt),
-.o_wb_sel (),
-.o_wb_adr (),
-.i_wb_dat (i_wb_dat),
-.i_wb_ack (i_wb_ack),
-
-.o_wb_sel_nxt (o_wb_sel_nxt),
-.o_wb_cyc_nxt (o_wb_cyc_nxt),
-.o_wb_stb_nxt (o_wb_stb_nxt),
-.o_wb_adr_nxt (o_wb_adr_nxt)
-);
-
-// ----------------------------------------------------------------------------
-
-endmodule
-`default_nettype wire
Index: zap/trunk/src/rtl/cpu/zap_decode.v
===================================================================
--- zap/trunk/src/rtl/cpu/zap_decode.v (revision 57)
+++ zap/trunk/src/rtl/cpu/zap_decode.v (nonexistent)
@@ -1,694 +0,0 @@
-// -----------------------------------------------------------------------------
-// -- --
-// -- (C) 2016-2018 Revanth Kamaraj. --
-// -- --
-// -- --------------------------------------------------------------------------
-// -- --
-// -- This program is free software; you can redistribute it and/or --
-// -- modify it under the terms of the GNU General Public License --
-// -- as published by the Free Software Foundation; either version 2 --
-// -- of the License, or (at your option) any later version. --
-// -- --
-// -- This program 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 General Public License for more details. --
-// -- --
-// -- You should have received a copy of the GNU General Public License --
-// -- along with this program; if not, write to the Free Software --
-// -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA --
-// -- 02110-1301, USA. --
-// -- --
-// -----------------------------------------------------------------------------
-// -- --
-// -- This module performs core ARM instruction decoding by translating ARM --
-// -- instructions into an internal long format that can be processed by core --
-// -- logic. Note that the predecode stage must change the 32-bit instr. to --
-// -- 36-bit before feeding it into this unit. --
-// -- --
-// -----------------------------------------------------------------------------
-
-
-`default_nettype none
-
-module zap_decode (
-
-i_irq, // IRQ request from previous stage.
-i_fiq, // FIQ request from previous stage.
-i_abt, // Code abort flagged from previous stage.
-
-// Instruction input from pre-decode.
-i_instruction,
-i_instruction_valid,
-
-//
-// CPU mode from active CPSR. Required to prevent CPSR change on MSR
-// instruction in USR mode.
-//
-i_cpsr_ff_mode,
-
-//
-// Bits related to decoded instruction...
-//
-
-o_condition_code, // 4-bit CC.
-o_destination_index, // Destination register.
-o_alu_source, // ALU source register.
-o_alu_operation, // ALU operation to be performed.
-o_shift_source, // Register to be treated as input to shifter.
-o_shift_operation, // Shift operation to perform.
-o_shift_length, // Length of the shift operation.
-o_flag_update, // 1 means flags must be updated.
-
-// Memory related.
-o_mem_srcdest_index, // Data register.
-o_mem_load, // Load operation.
-o_mem_store, // Store operation.
-o_mem_pre_index, // Pre-Index.
-o_mem_unsigned_byte_enable, // Access treated as uint8_t.
-o_mem_signed_byte_enable, // Access treated as int8_t.
-o_mem_signed_halfword_enable, // Access treated as int16_t.
-o_mem_unsigned_halfword_enable, // Access treated as uint16_t.
-o_mem_translate, // Force user view of memory.
-
-o_und, // Declare as undecodable.
-o_switch // Switch between ARM and Thumb may be needed if this is 1.
-
-);
-
-// ----------------------------------------------------------------------------
-
- // Number of architectural registers.
- parameter ARCH_REGS = 32;
-
- // Number of opcodes.
- parameter ALU_OPS = 32;
-
- // Number of shift operations.
- parameter SHIFT_OPS = 6;
-
-
- // I/O Ports.
- input wire i_irq, i_fiq, i_abt;
- input wire [35:0] i_instruction;
- input wire i_instruction_valid;
- input wire [4:0] i_cpsr_ff_mode;
- output reg [3:0] o_condition_code;
- output reg [$clog2(ARCH_REGS)-1:0] o_destination_index;
- output reg [32:0] o_alu_source;
- output reg [$clog2(ALU_OPS)-1:0] o_alu_operation;
- output reg [32:0] o_shift_source;
- output reg [$clog2(SHIFT_OPS)-1:0] o_shift_operation;
- output reg [32:0] o_shift_length;
- output reg o_flag_update;
- output reg [$clog2(ARCH_REGS)-1:0] o_mem_srcdest_index;
- output reg o_mem_load;
- output reg o_mem_store;
- output reg o_mem_pre_index;
- output reg o_mem_unsigned_byte_enable;
- output reg o_mem_signed_byte_enable;
- output reg o_mem_signed_halfword_enable;
- output reg o_mem_unsigned_halfword_enable;
- output reg o_mem_translate;
- output reg o_und;
- output reg o_switch;
-
-// ----------------------------------------------------------------------------
-
-`include "zap_defines.vh"
-`include "zap_localparams.vh"
-`include "zap_functions.vh"
-
-// Related to memory operations.
-localparam [1:0] SIGNED_BYTE = 2'd0;
-localparam [1:0] UNSIGNED_HALF_WORD = 2'd1;
-localparam [1:0] SIGNED_HALF_WORD = 2'd2;
-
-// ----------------------------------------------------------------------------
-
-always @*
-begin: mainBlk1
- // If an unrecognized instruction enters this, the output
- // signals an NV state i.e., invalid.
- o_condition_code = NV;
- o_destination_index = 0;
- o_alu_source = 0;
- o_alu_operation = 0;
- o_shift_source = 0;
- o_shift_operation = 0;
- o_shift_length = 0;
- o_flag_update = 0;
- o_mem_srcdest_index = RAZ_REGISTER;
- o_mem_load = 0;
- o_mem_store = 0;
- o_mem_translate = 0;
- o_mem_pre_index = 0;
- o_mem_unsigned_byte_enable = 0;
- o_mem_signed_byte_enable = 0;
- o_mem_signed_halfword_enable = 0;
- o_mem_unsigned_halfword_enable = 0;
- o_mem_translate = 0;
- o_und = 0;
- o_switch = 0;
-
-
- // Based on our pattern match, call the appropriate task
- if ( i_fiq || i_irq || i_abt )
- begin
- // Generate LR = PC - 4.
- o_condition_code = AL;
- o_alu_operation = SUB;
- o_alu_source = ARCH_PC;
- o_alu_source[32] = INDEX_EN;
- o_destination_index = ARCH_LR;
- o_shift_source = 4;
- o_shift_source[32] = IMMED_EN;
- o_shift_operation = LSL;
- o_shift_length = 0;
- o_shift_length[32] = IMMED_EN;
- end
- else if ( i_instruction_valid )
- casez ( i_instruction[31:0] )
- CLZ_INSTRUCTION: decode_clz ( i_instruction );
- BX_INST: decode_bx ( i_instruction );
- MRS: decode_mrs ( i_instruction );
- MSR,MSR_IMMEDIATE: decode_msr ( i_instruction );
-
- DATA_PROCESSING_IMMEDIATE,
- DATA_PROCESSING_REGISTER_SPECIFIED_SHIFT,
- DATA_PROCESSING_INSTRUCTION_SPECIFIED_SHIFT:
- decode_data_processing ( i_instruction );
-
- BRANCH_INSTRUCTION: decode_branch ( i_instruction );
-
- LS_INSTRUCTION_SPECIFIED_SHIFT,
- LS_IMMEDIATE: decode_ls ( i_instruction );
-
- MULT_INST: decode_mult ( i_instruction );
- LMULT_INST: decode_lmult( i_instruction );
- HALFWORD_LS: decode_halfword_ls ( i_instruction );
- SOFTWARE_INTERRUPT: decode_swi ( i_instruction );
-
- default:
- begin
- decode_und ( i_instruction );
- end
- endcase
-end
-
-// ----------------------------------------------------------------------------
-
-// =============================
-// 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}
-begin: tskLDecodeMult
-
- o_condition_code = i_instruction[31:28];
- o_flag_update = i_instruction[20];
-
- // ARM rd.
- o_destination_index = {i_instruction[`DP_RD_EXTEND],
- i_instruction[19:16]};
- // For MUL, Rd and Rn are interchanged.
- // For 64bit, this is normally high register.
-
- o_alu_source = i_instruction[11:8]; // ARM rs
- o_alu_source[32] = INDEX_EN;
-
- o_shift_source = {i_instruction[`DP_RB_EXTEND],
- i_instruction[`DP_RB]};
- o_shift_source[32] = INDEX_EN; // ARM rm
-
- // ARM rn
- o_shift_length = i_instruction[24] ?
- {i_instruction[`DP_RA_EXTEND],
- i_instruction[`DP_RD]} : 32'd0;
-
- o_shift_length[32] = i_instruction[24] ? INDEX_EN:IMMED_EN;
-
-
- // We need to generate output code.
- case ( i_instruction[22:21] )
- 2'b00:
- begin
- // Unsigned MULT64
- o_alu_operation = UMLALH;
- o_mem_srcdest_index = RAZ_REGISTER; // rh.
- end
- 2'b01:
- begin
- // Unsigned MAC64. Need mem_srcdest as source for RdHi.
- o_alu_operation = UMLALH;
- o_mem_srcdest_index = i_instruction[19:16];
- end
- 2'b10:
- begin
- // Signed MULT64
- o_alu_operation = SMLALH;
- o_mem_srcdest_index = RAZ_REGISTER;
- end
- 2'b11:
- begin
- // Signed MAC64. Need mem_srcdest as source of RdHi.
- o_alu_operation = SMLALH;
- o_mem_srcdest_index = i_instruction[19:16];
- end
- endcase
-
- if ( i_instruction[`OPCODE_EXTEND] == 1'd0 ) // Low request.
- begin
- o_destination_index = i_instruction[15:12]; // Low register.
- o_alu_operation[0] = 1'd0; // Request low operation.
- end
-end
-endtask
-
-// ----------------------------------------------------------------------------
-
-// ===============================
-// Decode undefined instructions.
-// ===============================
-task decode_und( input [34:0] i_instruction );
-begin
- // Say instruction is undefined.
- o_und = 1;
-
- // Generate LR = PC - 4
- o_condition_code = AL;
- o_alu_operation = SUB;
- o_alu_source = ARCH_PC;
- o_alu_source[32] = INDEX_EN;
- o_destination_index = ARCH_LR;
- o_shift_source = 4;
- o_shift_source[32] = IMMED_EN;
- o_shift_operation = LSL;
- o_shift_length = 0;
- o_shift_length[32] = IMMED_EN;
-end
-endtask
-
-// ----------------------------------------------------------------------------
-
-// ===========================================
-// Decode software interrupt instructions.
-// ===========================================
-task decode_swi( input [34:0] i_instruction );
-begin: tskDecodeSWI
-
- // Generate LR = PC - 4
- o_condition_code = AL;
- o_alu_operation = SUB;
- o_alu_source = ARCH_PC;
- o_alu_source[32] = INDEX_EN;
- o_destination_index = ARCH_LR;
- o_shift_source = 4;
- o_shift_source[32] = IMMED_EN;
- o_shift_operation = LSL;
- o_shift_length = 0;
- o_shift_length[32] = IMMED_EN;
-end
-endtask
-
-// ----------------------------------------------------------------------------
-
-// ============================
-// Decode halfword LOAD/STORE.
-// ============================
-task decode_halfword_ls( input [34:0] i_instruction );
-begin: tskDecodeHalfWordLs
- reg [11:0] temp, temp1;
-
- temp = i_instruction;
- temp1 = i_instruction;
-
- o_condition_code = i_instruction[31:28];
-
- temp[7:4] = temp[11:8];
- temp[11:8] = 0;
- temp1[11:4] = 0;
-
- if ( i_instruction[22] ) // immediate
- begin
- process_immediate ( temp );
- end
- else
- begin
- process_instruction_specified_shift ( temp1 );
- end
-
- o_alu_operation = i_instruction[23] ? ADD : SUB;
- o_alu_source = { i_instruction[`BASE_EXTEND],
- i_instruction[`BASE]}; // Pointer register.
- o_alu_source[32] = INDEX_EN;
- o_mem_load = i_instruction[20];
- o_mem_store = !o_mem_load;
- o_mem_pre_index = i_instruction[24];
-
- // If post-index is used or pre-index is used with writeback,
- // take is as a request to update the base register.
- o_destination_index = (i_instruction[21] || !o_mem_pre_index) ?
- o_alu_source :
- RAZ_REGISTER; // Pointer register already added.
-
- o_mem_srcdest_index = {i_instruction[`SRCDEST_EXTEND],
- i_instruction[`SRCDEST]};
-
- // Transfer size.
-
- o_mem_unsigned_byte_enable = 0;
- o_mem_unsigned_halfword_enable = 0;
- o_mem_signed_halfword_enable = 0;
-
- case ( i_instruction[6:5] )
- SIGNED_BYTE: o_mem_signed_byte_enable = 1;
- UNSIGNED_HALF_WORD: o_mem_unsigned_halfword_enable = 1;
- SIGNED_HALF_WORD: o_mem_signed_halfword_enable = 1;
- default:
- begin
- o_mem_unsigned_byte_enable = 0;
- o_mem_unsigned_halfword_enable = 0;
- o_mem_signed_halfword_enable = 0;
- end
- endcase
-end
-endtask
-
-// ----------------------------------------------------------------------------
-
-// ==============================
-// Decode short multiplication.
-// ==============================
-task decode_mult( input [34:0] i_instruction );
-begin: tskDecodeMult
-
-
- o_condition_code = i_instruction[31:28];
- o_flag_update = i_instruction[20];
- o_alu_operation = UMLALL;
- o_destination_index = {i_instruction[`DP_RD_EXTEND],
- i_instruction[19:16]};
-
- // For MUL, Rd and Rn are interchanged.
- o_alu_source = i_instruction[11:8]; // ARM rs
- o_alu_source[32] = INDEX_EN;
-
- o_shift_source = {i_instruction[`DP_RB_EXTEND],
- i_instruction[`DP_RB]};
- o_shift_source[32] = INDEX_EN; // ARM rm
-
- // ARM rn - Set for accumulate.
- o_shift_length = i_instruction[21] ?
- {i_instruction[`DP_RA_EXTEND],
- i_instruction[`DP_RD]} : 32'd0;
-
- o_shift_length[32] = i_instruction[21] ? INDEX_EN : IMMED_EN;
-
- // Set rh = 0.
- o_mem_srcdest_index = RAZ_REGISTER;
-end
-endtask
-
-// ----------------------------------------------------------------------------
-
-// =============================
-// BX decode.
-// =============================
-// Converted into a MOV to PC. The task of setting the T-bit in the CPSR is
-// the job of the writeback stage.
-task decode_bx( input [34:0] i_instruction );
-begin: tskDecodeBx
- reg [34:0] temp;
-
- temp = i_instruction[31:0];
- temp[31:4] = 0; // Zero out stuff to avoid conflicts in the function.
-
- process_instruction_specified_shift(temp);
-
- // The RAW ALU source does not matter.
- o_condition_code = i_instruction[31:28];
- o_alu_operation = MOV;
- o_destination_index = ARCH_PC;
-
- // We will force an immediate in alu source to prevent unwanted locks.
- o_alu_source = 0;
- o_alu_source[32] = IMMED_EN;
-
- // Indicate switch. This is a primary differentiator.
- o_switch = 1;
-end
-endtask
-
-// ----------------------------------------------------------------------------
-
-// =============================================
-// Task for decoding load-store instructions.
-// =============================================
-task decode_ls( input [34:0] i_instruction );
-begin: tskDecodeLs
-
-
- o_condition_code = i_instruction[31:28];
-
- if ( !i_instruction[25] ) // immediate
- begin
- o_shift_source = i_instruction[11:0];
- o_shift_source[32] = IMMED_EN;
- o_shift_length = 0;
- o_shift_length[32] = IMMED_EN;
- o_shift_operation = LSL;
- end
- else
- begin
- process_instruction_specified_shift ( i_instruction[11:0] );
- end
-
- o_alu_operation = i_instruction[23] ? ADD : SUB;
-
- // Pointer register.
- o_alu_source = {i_instruction[`BASE_EXTEND], i_instruction[`BASE]};
- o_alu_source[32] = INDEX_EN;
- o_mem_load = i_instruction[20];
- o_mem_store = !o_mem_load;
- o_mem_pre_index = i_instruction[24];
-
- // If post-index is used or pre-index is used with writeback,
- // take is as a request to update the base register.
- o_destination_index = (i_instruction[21] || !o_mem_pre_index) ?
- o_alu_source :
- RAZ_REGISTER; // Pointer register already added.
- o_mem_unsigned_byte_enable = i_instruction[22];
-
- o_mem_srcdest_index = {i_instruction[`SRCDEST_EXTEND], i_instruction[`SRCDEST]};
-
- if ( !o_mem_pre_index ) // Post-index, writeback has no meaning.
- begin
- if ( i_instruction[21] )
- begin
- // Use it for force usr mode memory mappings.
- o_mem_translate = 1'd1;
- end
- end
-end
-endtask
-
-// ----------------------------------------------------------------------------
-
-task decode_mrs( input [34:0] i_instruction );
-begin
-
- process_immediate ( i_instruction[11:0] );
-
- o_condition_code = i_instruction[31:28];
- o_destination_index = {i_instruction[`DP_RD_EXTEND], i_instruction[`DP_RD]};
- o_alu_source = i_instruction[22] ? ARCH_CURR_SPSR : ARCH_CPSR;
- o_alu_source[32] = INDEX_EN;
- o_alu_operation = ADD;
-end
-endtask
-
-// ----------------------------------------------------------------------------
-
-task decode_msr( input [34:0] i_instruction );
-begin
-
- if ( i_instruction[25] ) // Immediate present.
- begin
- process_immediate ( i_instruction[11:0] );
- end
- else
- begin
- process_instruction_specified_shift ( i_instruction[11:0] );
- end
-
- // Destination.
- o_destination_index = i_instruction[22] ? ARCH_CURR_SPSR : ARCH_CPSR;
-
- o_condition_code = i_instruction[31:28];
-
- // Make srcdest as SPSR. useful for MMOV.
- o_mem_srcdest_index = ARCH_CURR_SPSR;
-
- // Select SPSR or CPSR.
- o_alu_operation = i_instruction[22] ? MMOV : FMOV;
-
- o_alu_source = i_instruction[19:16];
- o_alu_source[32] = IMMED_EN;
-
- // Part of the instruction will silently fail when changing mode bits
- // in user mode. This is as per the ARM spec.
- if ( i_cpsr_ff_mode == USR )
- begin
- o_alu_source[2:0] = 3'b0;
- end
-end
-endtask
-
-// ----------------------------------------------------------------------------
-
-// ========================
-// Decode B
-// ========================
-task decode_branch( input [34:0] i_instruction );
-begin
- // A branch is decayed into PC = PC + $signed(immed)
- o_condition_code = i_instruction[31:28];
- o_alu_operation = ADD;
- o_destination_index = ARCH_PC;
- o_alu_source = ARCH_PC;
- o_alu_source[32] = INDEX_EN;
- o_shift_source = ($signed(i_instruction[23:0]));
- o_shift_source[32] = IMMED_EN;
- o_shift_operation = LSL;
- o_shift_length = i_instruction[34] ? 1 : 2; // Thumb branches sometimes need only a shift of 1.
- o_shift_length[32] = IMMED_EN;
-end
-endtask
-
-// ----------------------------------------------------------------------------
-
-//
-// Common data processing handles the common section of all 3 data processing
-// formats.
-//
-task decode_data_processing( input [34:0] i_instruction );
-begin
- o_condition_code = i_instruction[31:28];
- o_alu_operation = i_instruction[24:21];
- o_flag_update = i_instruction[20];
- o_destination_index = {i_instruction[`DP_RD_EXTEND], i_instruction[`DP_RD]};
- o_alu_source = i_instruction[`DP_RA];
- o_alu_source[32] = INDEX_EN;
- o_mem_srcdest_index = ARCH_CURR_SPSR;
-
- if ( o_alu_operation == CMP ||
- o_alu_operation == CMN ||
- o_alu_operation == TST ||
- o_alu_operation == TEQ )
- begin
- o_destination_index = RAZ_REGISTER;
- end
-
- casez ( {i_instruction[25],i_instruction[7],i_instruction[4]} )
- 3'b1zz: process_immediate ( i_instruction );
- 3'b0z0: process_instruction_specified_shift ( i_instruction );
- 3'b001: process_register_specified_shift ( i_instruction );
- default:
- begin
- $display("Error : Decoder Error.");
- $finish;
- end
- endcase
-end
-endtask
-
-// ----------------------------------------------------------------------------
-
-//
-// If an immediate value is to be rotated right by an
-// immediate value, this mode is used.
-//
-task process_immediate ( input [34:0] instruction );
-begin
- o_shift_length = instruction[11:8] << 1'd1;
- o_shift_length[32] = IMMED_EN;
- o_shift_source = instruction[7:0];
- o_shift_source[32] = IMMED_EN;
- o_shift_operation = RORI;
-end
-endtask
-
-// ----------------------------------------------------------------------------
-
-//
-// The shifter source is a register but the
-// amount to shift is in the instruction itself.
-//
-task process_instruction_specified_shift ( input [34:0] instruction );
-begin
- // ROR #0 = RRC, ASR #0 = ASR #32, LSL #0 = LSL #0, LSR #0 = LSR #32
- // ROR #n = ROR_1 #n ( n > 0 )
- o_shift_length = instruction[11:7];
- o_shift_length[32] = IMMED_EN;
- o_shift_source = {i_instruction[`DP_RB_EXTEND],instruction[`DP_RB]};
- o_shift_source[32] = INDEX_EN;
- o_shift_operation = instruction[6:5];
-
- case ( o_shift_operation )
- LSR: if ( !o_shift_length[31:0] ) o_shift_length[31:0] = 32;
- ASR: if ( !o_shift_length[31:0] ) o_shift_length[31:0] = 32;
- ROR:
- begin
- if ( !o_shift_length[31:0] )
- o_shift_operation = RRC;
- else
- o_shift_operation = ROR_1;
- // Differs in carry generation behavior.
- end
- default: // For lint.
- begin
- end
- endcase
-
- // Reinforce the fact.
- o_shift_length[32] = IMMED_EN;
-end
-endtask
-
-// ----------------------------------------------------------------------------
-
-// The source register and the amount of shift are both in registers.
-task process_register_specified_shift ( input [34:0] instruction );
-begin
- o_shift_length = instruction[11:8];
- o_shift_length[32] = INDEX_EN;
- o_shift_source = {i_instruction[`DP_RB_EXTEND], instruction[`DP_RB]};
- o_shift_source[32] = INDEX_EN;
- o_shift_operation = instruction[6:5];
-end
-endtask
-
-endmodule // zap_decode.v
-`default_nettype wire
Index: zap/trunk/src/rtl/cpu/zap_alu_main.v
===================================================================
--- zap/trunk/src/rtl/cpu/zap_alu_main.v (revision 57)
+++ zap/trunk/src/rtl/cpu/zap_alu_main.v (nonexistent)
@@ -1,981 +0,0 @@
-// ---------------------------------------------------------------------------
-// -- --
-// -- (C) 2016-2018 Revanth Kamaraj. --
-// -- --
-// -- ------------------------------------------------------------------------
-// -- --
-// -- This program is free software; you can redistribute it and/or --
-// -- modify it under the terms of the GNU General Public License --
-// -- as published by the Free Software Foundation; either version 2 --
-// -- of the License, or (at your option) any later version. --
-// -- --
-// -- This program 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 General Public License for more details. --
-// -- --
-// -- You should have received a copy of the GNU General Public License --
-// -- along with this program; if not, write to the Free Software --
-// -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA --
-// -- 02110-1301, USA. --
-// -- --
-// ---------------------------------------------------------------------------
-// -- --
-// -- This is the main ZAP arithmetic and logic unit. Apart from shfits --
-// -- and multiplies, all other arithmetic and logic is performed here. --
-// -- Also data memory access signals are generated at the end of the clock --
-// -- cycle. Instructions that fail condition checks are invalidated here. --
-// -- --
-// ---------------------------------------------------------------------------
-
-`default_nettype none
-
-module zap_alu_main #(
-
- parameter [31:0] PHY_REGS = 32'd46, // Number of physical registers.
- parameter [31:0] SHIFT_OPS = 32'd5, // Number of shift operations.
- parameter [31:0] ALU_OPS = 32'd32, // Number of arithmetic operations.
- parameter [31:0] FLAG_WDT = 32'd32 // Width of active CPSR.
-)
-(
- // ------------------------------------------------------------------
- // Decompile Interface. Only for debug.
- // ------------------------------------------------------------------
-
- input wire [64*8-1:0] i_decompile,
- output reg [64*8-1:0] o_decompile,
-
- // ------------------------------------------------------------------
- // ALU Hijack Interface. For Thumb Data Abort address calculation.
- // ------------------------------------------------------------------
-
- input wire i_hijack, // Enable hijack.
- input wire [31:0] i_hijack_op1, // Hijack operand 1.
- input wire [31:0] i_hijack_op2, // Hijack operand 2.
- input wire i_hijack_cin, // Hijack carry in.
- output wire [31:0] o_hijack_sum, // Hijack sum out.
-
- // ------------------------------------------------------------------
- // Clock and reset
- // ------------------------------------------------------------------
-
- input wire i_clk, // Clock.
- input wire i_reset, // sync active high reset.
-
- // -------------------------------------------------------------------
- // Clear and Stall signals.
- // -------------------------------------------------------------------
-
- input wire i_clear_from_writeback, // Clear unit.
- input wire i_data_stall, // DCACHE stall.
-
- // -------------------------------------------------------------------
- // Misc. signals
- // -------------------------------------------------------------------
-
- input wire [31:0] i_cpsr_nxt, // From passive CPSR.
- input wire i_switch_ff, // Switch state.
- input wire [1:0] i_taken_ff, // Branch prediction.
- input wire [31:0] i_pc_ff, // Addr of instr.
- input wire i_nozero_ff, // Zero flag will not be set.
-
- // ------------------------------------------------------------------
- // Source values
- // ------------------------------------------------------------------
-
- input wire [31:0] i_alu_source_value_ff, // ALU source value.
- input wire [31:0] i_shifted_source_value_ff, // Shifted source value.
- input wire i_shift_carry_ff, // Carry from shifter.
- input wire [31:0] i_pc_plus_8_ff, // PC + 8 value.
-
- // ------------------------------------------------------------------
- // Interrupt Tagging
- // ------------------------------------------------------------------
-
- input wire i_abt_ff, // ABT flagged.
- input wire i_irq_ff, // IRQ flagged.
- input wire i_fiq_ff, // FIQ flagged.
- input wire i_swi_ff, // SWI flagged.
- input wire i_und_ff, // Flagged undefined instructions.
- input wire i_data_mem_fault, // Flagged Data abort.
-
- // ------------------------------------------------------------------
- // Memory Access Related
- // ------------------------------------------------------------------
-
- input wire [31:0] i_mem_srcdest_value_ff, // Value to store.
- input wire [zap_clog2(PHY_REGS)-1:0] i_mem_srcdest_index_ff, // LD/ST Memory data register index.
- input wire i_mem_load_ff, // LD/ST Memory load.
- input wire i_mem_store_ff, // LD/ST Memory store.
- input wire i_mem_pre_index_ff, // LD/ST Pre/Post index.
- input wire i_mem_unsigned_byte_enable_ff, // LD/ST uint8_t data type.
- input wire i_mem_signed_byte_enable_ff, // LD/ST int8_t data type.
- input wire i_mem_signed_halfword_enable_ff, // LD/ST int16_t data type.
- input wire i_mem_unsigned_halfword_enable_ff,// LD/ST uint16_t data type.
- input wire i_mem_translate_ff, // LD/ST Force user view of memory.
- input wire i_force32align_ff, // Force address alignment to 32-bit.
-
- // -------------------------------------------------------------------
- // ALU controls
- // -------------------------------------------------------------------
-
- input wire [3:0] i_condition_code_ff, // CC associated with instr.
- input wire [zap_clog2(PHY_REGS)-1:0] i_destination_index_ff, // Target register index.
- input wire [zap_clog2(ALU_OPS)-1:0] i_alu_operation_ff, // Operation to perform.
- input wire i_flag_update_ff, // Update flags if 1.
-
- // -----------------------------------------------------------------
- // ALU result
- // -----------------------------------------------------------------
-
- output reg [31:0] o_alu_result_nxt, // For feedback. ALU result _nxt version.
- output reg [31:0] o_alu_result_ff, // ALU result flopped version.
- output reg o_dav_ff, // Instruction valid.
- output reg o_dav_nxt, // Instruction valid _nxt version.
- output reg [FLAG_WDT-1:0] o_flags_ff, // Output flags (CPSR).
- output reg [FLAG_WDT-1:0] o_flags_nxt, // CPSR next.
- output reg [zap_clog2(PHY_REGS)-1:0] o_destination_index_ff, // Destination register index.
-
- // -----------------------------------------------------------------
- // Interrupt Tagging
- // -----------------------------------------------------------------
-
- output reg o_abt_ff, // Instruction abort flagged.
- output reg o_irq_ff, // IRQ flagged.
- output reg o_fiq_ff, // FIQ flagged.
- output reg o_swi_ff, // SWI flagged.
- output reg o_und_ff, // Flagged undefined instructions
-
- // -----------------------------------------------------------------
- // Jump Controls, BP Confirm, PC + 8
- // -----------------------------------------------------------------
-
- output reg [31:0] o_pc_plus_8_ff, // Instr address + 8.
- output reg o_clear_from_alu, // ALU commands a pipeline clear and a predictor correction.
- output reg [31:0] o_pc_from_alu, // Corresponding address to go to is provided here.
- output reg o_confirm_from_alu, // Tell branch predictor it was correct.
-
- // ----------------------------------------------------------------
- // Memory access related
- // ----------------------------------------------------------------
-
- output reg [zap_clog2(PHY_REGS)-1:0] o_mem_srcdest_index_ff, // LD/ST data register.
- output reg o_mem_load_ff, // LD/ST load indicator.
- output reg o_mem_store_ff, // LD/ST store indicator.
- output reg [31:0] o_mem_address_ff, // LD/ST address to access.
- output reg o_mem_unsigned_byte_enable_ff, // uint8_t
- output reg o_mem_signed_byte_enable_ff, // int8_t
- output reg o_mem_signed_halfword_enable_ff, // int16_t
- output reg o_mem_unsigned_halfword_enable_ff, // uint16_t
- output reg [31:0] o_mem_srcdest_value_ff, // LD/ST value to store.
- output reg o_mem_translate_ff, // LD/ST force user view of memory.
- output reg [3:0] o_ben_ff, // LD/ST byte enables (only for STore instructions).
- output reg [31:0] o_address_nxt, // D pin of address register to drive TAG RAMs.
-
- // -------------------------------------------------------------
- // Wishbone signal outputs.
- // -------------------------------------------------------------
-
- output reg o_data_wb_we_nxt,
- output reg o_data_wb_cyc_nxt,
- output reg o_data_wb_stb_nxt,
- output reg [31:0] o_data_wb_dat_nxt,
- output reg [3:0] o_data_wb_sel_nxt,
- output reg o_data_wb_we_ff,
- output reg o_data_wb_cyc_ff,
- output reg o_data_wb_stb_ff,
- output reg [31:0] o_data_wb_dat_ff,
- output reg [3:0] o_data_wb_sel_ff
-);
-
-// ----------------------------------------------------------------------------
-// Includes
-// ----------------------------------------------------------------------------
-
-`include "zap_defines.vh"
-`include "zap_localparams.vh"
-`include "zap_functions.vh"
-
-// -----------------------------------------------------------------------------
-// Localparams
-// -----------------------------------------------------------------------------
-
-// Local N,Z,C,V structures.
-localparam [1:0] _N = 2'd3;
-localparam [1:0] _Z = 2'd2;
-localparam [1:0] _C = 2'd1;
-localparam [1:0] _V = 2'd0;
-
-// Branch status.
-localparam [1:0] SNT = 2'd0;
-localparam [1:0] WNT = 2'd1;
-localparam [1:0] WT = 2'd2;
-localparam [1:0] ST = 2'd3;
-
-// ------------------------------------------------------------------------------
-// Variables
-// ------------------------------------------------------------------------------
-
-// Memory srcdest value (i.e., data)
-wire [31:0] mem_srcdest_value_nxt;
-
-// Byte enable generator.
-wire [3:0] ben_nxt;
-
-// Address about to be output. Used to drive tag RAMs etc.
-reg [31:0] mem_address_nxt;
-
-/*
- Sleep flop. When 1 unit sleeps i.e., does not produce any output except on
- the first clock cycle where LR is calculated using the ALU.
-*/
-reg sleep_ff, sleep_nxt;
-
-/*
- CPSR (Active CPSR). The active CPSR is from the where the CPU flags are
- read out and the mode also is. Mode changes via manual writes to CPSR
- are first written to the active and they then propagate to the passive CPSR
- in the writeback stage. This reduces the pipeline flush penalty.
-*/
-reg [31:0] flags_ff, flags_nxt;
-
-reg [31:0] rm, rn; // RM = shifted source value Rn for
- // non shifted source value. These are
- // values and not indices.
-
-
-reg [5:0] clz_rm; // Count leading zeros in Rm.
-
-// Destination index about to be output.
-reg [zap_clog2(PHY_REGS)-1:0] o_destination_index_nxt;
-
-// 1s complement of Rm and Rn.
-wire [31:0] not_rm = ~rm;
-wire [31:0] not_rn = ~rn;
-
-// Wires which connect to an adder.
-reg [31:0] op1, op2;
-reg cin;
-
-// 32-bit adder with carry input and carry output.
-wire [32:0] sum = {1'd0, op1} + {1'd0, op2} + {32'd0, cin};
-
-reg [31:0] tmp_flags, tmp_sum;
-
-// Opcode.
-wire [zap_clog2(ALU_OPS)-1:0] opcode = i_alu_operation_ff;
-
-// -------------------------------------------------------------------------------
-// Assigns
-// -------------------------------------------------------------------------------
-
-/*
- For memory stores, we must generate correct byte enables. This is done
- by examining access type inputs. For loads, always 1111 is generated.
- If there is neither a load or a store, the old value is preserved.
-*/
-assign ben_nxt = generate_ben (
- i_mem_unsigned_byte_enable_ff,
- i_mem_signed_byte_enable_ff,
- i_mem_unsigned_halfword_enable_ff,
- i_mem_unsigned_halfword_enable_ff,
- mem_address_nxt);
-
-assign mem_srcdest_value_nxt = duplicate (
- i_mem_unsigned_byte_enable_ff,
- i_mem_signed_byte_enable_ff,
- i_mem_unsigned_halfword_enable_ff,
- i_mem_unsigned_halfword_enable_ff,
- i_mem_srcdest_value_ff );
-
-/*
- Hijack interface. Data aborts use the hijack interface to find return
- address. The writeback drives the ALU inputs to find the final output.
-*/
-assign o_hijack_sum = sum;
-
-// -------------------------------------------------------------------------------
-// CLZ logic.
-// -------------------------------------------------------------------------------
-
-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
-
-// ----------------------------------------------------------------------------
-// Aliases
-// ----------------------------------------------------------------------------
-
-always @*
-begin
- rm = i_shifted_source_value_ff;
- rn = i_alu_source_value_ff;
- o_flags_ff = flags_ff;
- o_flags_nxt = flags_nxt;
-end
-
-// -----------------------------------------------------------------------------
-// Sequential logic.
-// -----------------------------------------------------------------------------
-
-always @ (posedge i_clk)
-begin
- if ( i_reset )
- begin
- // On reset, processor enters supervisory mode with interrupts
- // masked.
- clear ( {1'd1,1'd1,1'd0,SVC} );
- end
- else if ( i_clear_from_writeback )
- begin
- // Clear but take CPSR from writeback.
- clear ( i_cpsr_nxt );
- end
- else if ( i_data_stall )
- begin
- // Preserve values.
- end
- else if ( i_data_mem_fault || sleep_ff )
- begin
- // Clear and preserve flags. Keep sleeping.
- clear(flags_ff);
- sleep_ff <= 1'd1;
- o_dav_ff <= 1'd0; // Don't give any output.
- end
- else
- begin
- // Clock out all flops normally.
-
- o_alu_result_ff <= o_alu_result_nxt;
- o_dav_ff <= o_dav_nxt;
- o_pc_plus_8_ff <= i_pc_plus_8_ff;
- o_destination_index_ff <= o_destination_index_nxt;
- flags_ff <= flags_nxt;
- o_abt_ff <= i_abt_ff;
- o_irq_ff <= i_irq_ff;
- o_fiq_ff <= i_fiq_ff;
- o_swi_ff <= i_swi_ff;
- o_mem_srcdest_index_ff <= i_mem_srcdest_index_ff;
- o_mem_srcdest_index_ff <= i_mem_srcdest_index_ff;
-
- // Load or store must come up only if an actual LDR/STR is
- // detected.
- o_mem_load_ff <= o_dav_nxt ? i_mem_load_ff : 1'd0;
- o_mem_store_ff <= o_dav_nxt ? i_mem_store_ff: 1'd0;
-
- o_mem_unsigned_byte_enable_ff <= i_mem_unsigned_byte_enable_ff;
- o_mem_signed_byte_enable_ff <= i_mem_signed_byte_enable_ff;
- o_mem_signed_halfword_enable_ff <= i_mem_signed_halfword_enable_ff;
- o_mem_unsigned_halfword_enable_ff<= i_mem_unsigned_halfword_enable_ff;
- o_mem_translate_ff <= i_mem_translate_ff;
-
- //
- // The value to store will have to be duplicated for easier
- // memory controller design. See the duplicate() function.
- //
- o_mem_srcdest_value_ff <= mem_srcdest_value_nxt;
-
- sleep_ff <= sleep_nxt;
- o_und_ff <= i_und_ff;
-
- // Generating byte enables based on the data type and address.
- o_ben_ff <= ben_nxt;
-
- // For debug
- o_decompile <= i_decompile;
- end
-end
-
-// ----------------------------------------------------------------------------
-
-always @ ( posedge i_clk ) // Wishbone flops.
-begin
- // Wishbone updates.
- o_data_wb_cyc_ff <= o_data_wb_cyc_nxt;
- o_data_wb_stb_ff <= o_data_wb_stb_nxt;
- o_data_wb_we_ff <= o_data_wb_we_nxt;
- o_data_wb_dat_ff <= o_data_wb_dat_nxt;
- o_data_wb_sel_ff <= o_data_wb_sel_nxt;
- o_mem_address_ff <= o_address_nxt;
-end
-
-// -----------------------------------------------------------------------------
-// WB next state logic.
-// -----------------------------------------------------------------------------
-
-always @*
-begin
- // Preserve values.
- o_data_wb_cyc_nxt = o_data_wb_cyc_ff;
- o_data_wb_stb_nxt = o_data_wb_stb_ff;
- o_data_wb_we_nxt = o_data_wb_we_ff;
- o_data_wb_dat_nxt = o_data_wb_dat_ff;
- o_data_wb_sel_nxt = o_data_wb_sel_ff;
- o_address_nxt = o_mem_address_ff;
-
- if ( i_reset ) // Synchronous reset.
- begin
- o_data_wb_cyc_nxt = 1'd0;
- o_data_wb_stb_nxt = 1'd0;
- end
- else if ( i_clear_from_writeback )
- begin
- o_data_wb_cyc_nxt = 0;
- o_data_wb_stb_nxt = 0;
- end
- else if ( i_data_stall )
- begin
- // Save state.
- end
- else if ( i_data_mem_fault || sleep_ff )
- begin
- o_data_wb_cyc_nxt = 0;
- o_data_wb_stb_nxt = 0;
- end
- else
- begin
- o_data_wb_cyc_nxt = o_dav_nxt ? i_mem_load_ff | i_mem_store_ff : 1'd0;
- o_data_wb_stb_nxt = o_dav_nxt ? i_mem_load_ff | i_mem_store_ff : 1'd0;
- o_data_wb_we_nxt = o_dav_nxt ? i_mem_store_ff : 1'd0;
- o_data_wb_dat_nxt = mem_srcdest_value_nxt;
- o_data_wb_sel_nxt = ben_nxt;
- o_address_nxt = mem_address_nxt;
- end
-end
-
-// ----------------------------------------------------------------------------
-// Used to generate access address.
-// ----------------------------------------------------------------------------
-
-always @ (*)
-begin:pre_post_index_address_generator
- /*
- * Do not change address if not needed.
- * If not a load OR a store. Preserve this value. Power saving.
- */
- if (!( (i_mem_load_ff || i_mem_store_ff) && o_dav_nxt ))
- mem_address_nxt = o_mem_address_ff;
- else
- begin
- /*
- * Memory address output based on pre or post index.
- * For post-index, update is done after memory access.
- * For pre-index, update is done before memory access.
- */
- if ( i_mem_pre_index_ff == 0 )
- mem_address_nxt = rn; // Postindex;
- else
- mem_address_nxt = o_alu_result_nxt; // Preindex.
-
- // If a force 32 align is set, make the lower 2 bits as zero.
- if ( i_force32align_ff )
- mem_address_nxt[1:0] = 2'b00;
- end
-end
-
-// ---------------------------------------------------------------------------------
-// Used to generate ALU result + Flags
-// ---------------------------------------------------------------------------------
-
-always @*
-begin: alu_result
-
- // Default value.
- tmp_flags = flags_ff;
-
- // If it is a logical instruction.
- if ( opcode == AND ||
- opcode == EOR ||
- opcode == MOV ||
- opcode == MVN ||
- opcode == BIC ||
- opcode == ORR ||
- opcode == TST ||
- opcode == TEQ ||
- opcode == CLZ
- )
- begin
- // Call the logical processing function.
- {tmp_flags[31:28], tmp_sum} = process_logical_instructions (
- rn, rm, flags_ff[31:28],
- opcode, i_flag_update_ff, i_nozero_ff
- );
- end
-
- /*
- * Flag MOV(FMOV) i.e., MOV to CPSR and MMOV handler.
- * FMOV moves to CPSR and flushes the pipeline.
- * MMOV moves to SPSR and does not flush the pipeline.
- */
- else if ( opcode == FMOV || opcode == MMOV )
- begin: fmov_mmov
- integer i;
- reg [31:0] exp_mask;
-
- // Read entire CPSR or SPSR.
- tmp_sum = opcode == FMOV ? flags_ff : i_mem_srcdest_value_ff;
-
- // Generate a proper mask.
- exp_mask = {{8{rn[3]}},{8{rn[2]}},{8{rn[1]}},{8{rn[0]}}};
-
- // Change only specific bits as specified by the mask.
- for ( i=0;i<32;i=i+1 )
- begin
- if ( exp_mask[i] )
- tmp_sum[i] = rm[i];
- end
-
- /*
- * FMOV moves to the CPSR in ALU and writeback.
- * No register is changed. The MSR out of this will have
- * a target to CPSR.
- */
- if ( opcode == FMOV )
- begin
- tmp_flags = tmp_sum;
- end
- end
- else
- begin: blk3
- reg [3:0] flags;
- reg [zap_clog2(ALU_OPS)-1:0] op;
- reg n,z,c,v;
-
- op = opcode;
-
- // Assign output of adder to flags after some minimal logic.
- c = sum[32];
- z = (sum[31:0] == 0);
- n = sum[31];
-
- // Overflow.
- if ( ( op == ADD || op == ADC || op == CMN ) && (rn[31] == rm[31]) && (sum[31] != rn[31]) )
- v = 1;
- else if ( (op == RSB || op == RSC) && (rm[31] == !rn[31]) && (sum[31] != rm[31] ) )
- v = 1;
- else if ( (op == SUB || op == SBC || op == CMP) && (rn[31] == !rm[31]) && (sum[31] != rn[31]) )
- v = 1;
- else
- v = 0;
-
- //
- // If you choose not to update flags, do not change the flags.
- // Otherwise, they will contain their newly computed values.
- //
- if ( i_flag_update_ff )
- tmp_flags[31:28] = {n,z,c,v};
-
- // Write out the result.
- tmp_sum = op == CLZ ? clz_rm : sum;
- end
-
- // Drive nxt pin of result register.
- o_alu_result_nxt = tmp_sum;
-end
-
-// ----------------------------------------------------------------------------
-// Flag propagation and branch prediction feedback unit
-// ----------------------------------------------------------------------------
-
-always @*
-begin: flags_bp_feedback
-
- o_clear_from_alu = 1'd0;
- o_pc_from_alu = 32'd0;
- sleep_nxt = sleep_ff;
- flags_nxt = tmp_flags;
- o_destination_index_nxt = i_destination_index_ff;
- o_confirm_from_alu = 1'd0;
-
- // Check if condition is satisfied.
- o_dav_nxt = is_cc_satisfied ( i_condition_code_ff, flags_ff[31:28] );
-
- if ( i_irq_ff || i_fiq_ff || i_abt_ff || i_swi_ff || i_und_ff )
- begin
- //
- // Any sign of an interrupt is present, put unit to sleep.
- // The current instruction will not be executed ultimately.
- // However o_dav_nxt = 1 since interrupt must be carried on.
- //
- o_dav_nxt = 1'd1;
- sleep_nxt = 1'd1;
- end
- else if ( (opcode == FMOV) && o_dav_nxt ) // Writes to CPSR...
- begin
- o_clear_from_alu = 1'd1; // Need to flush everything because we might end up fetching stuff in KERNEL instead of USER mode.
- o_pc_from_alu = sum; // NOT tmp_sum, that would be loaded into CPSR.
-
- // USR cannot change mode. Will silently fail.
- flags_nxt[`CPSR_MODE] = (flags_nxt[`CPSR_MODE] == USR) ? USR : flags_nxt[`CPSR_MODE]; // Security.
- end
- else if ( i_destination_index_ff == ARCH_PC && (i_condition_code_ff != NV))
- begin
- if ( i_flag_update_ff && o_dav_nxt ) // PC update with S bit. Context restore.
- begin
- o_destination_index_nxt = PHY_RAZ_REGISTER;
- o_clear_from_alu = 1'd1;
- o_pc_from_alu = tmp_sum;
- flags_nxt = i_mem_srcdest_value_ff; // Restore CPSR from SPSR.
- flags_nxt[`CPSR_MODE] = (flags_nxt[`CPSR_MODE] == USR) ? USR : flags_nxt[`CPSR_MODE]; // Security.
- end
- else if ( o_dav_nxt ) // Branch taken and no flag update.
- begin
- if ( i_taken_ff == SNT || i_taken_ff == WNT ) // Incorrectly predicted.
- begin
- // Quick branches - Flush everything before.
- // Dumping ground since PC change is done. Jump to branch target for fast switching.
- o_destination_index_nxt = PHY_RAZ_REGISTER;
- o_clear_from_alu = 1'd1;
- o_pc_from_alu = tmp_sum;
-
- if ( i_switch_ff )
- begin
- flags_nxt[T] = tmp_sum[0];
- end
- end
- else // Correctly predicted.
- begin
- // If thumb bit changes, flush everything before
- if ( i_switch_ff )
- begin
- // Quick branches! PC goes to RAZ register since
- // change is done.
-
- o_destination_index_nxt = PHY_RAZ_REGISTER;
- o_clear_from_alu = 1'd1;
- o_pc_from_alu = tmp_sum; // Jump to branch target.
- flags_nxt[T] = tmp_sum[0];
- end
- else
- begin
- // No mode change, do not change anything.
-
- o_destination_index_nxt = PHY_RAZ_REGISTER;
- o_clear_from_alu = 1'd0;
-
- // Send confirmation message to branch predictor.
-
- o_pc_from_alu = 32'd0;
- o_confirm_from_alu = 1'd1;
- end
- end
- end
- else // Branch not taken
- begin
- if ( i_taken_ff == WT || i_taken_ff == ST )
- //
- // Wrong prediction as taken. Go back to the same
- // branch. Non branches are always predicted as not-taken.
- //
- // GO BACK TO THE SAME BRANCH AND INFORM PREDICTOR OF ITS
- // MISTAKE - THE NEXT TIME THE PREDICTION WILL BE NOT-TAKEN.
- //
- begin
- o_clear_from_alu = 1'd1;
- o_pc_from_alu = i_pc_ff;
- end
- else // Correct prediction.
- begin
- o_clear_from_alu = 1'd0;
- o_pc_from_alu = 32'd0;
- end
- end
- end
- else if ( i_mem_srcdest_index_ff == ARCH_PC && o_dav_nxt && i_mem_load_ff)
- begin
- // Loads to PC also puts the unit to sleep.
- sleep_nxt = 1'd1;
- end
-
- // If the current instruction is invalid, do not update flags.
- if ( o_dav_nxt == 1'd0 )
- flags_nxt = flags_ff;
-end
-
-// ----------------------------------------------------------------------------
-// MUX structure on the inputs of the adder.
-// ----------------------------------------------------------------------------
-
-// These are adder connections. Data processing and FMOV use these.
-always @*
-begin: adder_ip_mux
- reg [zap_clog2(ALU_OPS)-1:0] op;
- reg [31:0] flags;
-
- flags = flags_ff[31:28];
- op = i_alu_operation_ff;
-
- if ( i_hijack )
- begin
- op1 = i_hijack_op1;
- op2 = i_hijack_op2;
- cin = i_hijack_cin;
- end
- else
- case ( op )
- FMOV: begin op1 = i_pc_plus_8_ff ; op2 = ~32'd4 ; cin = 1'd1; end
- ADD: begin op1 = rn ; op2 = rm ; cin = 32'd0; end
- ADC: begin op1 = rn ; op2 = rm ; cin = flags[_C]; end
- SUB: begin op1 = rn ; op2 = not_rm ; cin = 32'd1; end
- RSB: begin op1 = rm ; op2 = not_rn ; cin = 32'd1; end
- SBC: begin op1 = rn ; op2 = not_rm ; cin = !flags[_C];end
- RSC: begin op1 = rm ; op2 = not_rn ; cin = !flags[_C];end
-
- // Target is not written.
- CMP: begin op1 = rn ; op2 = not_rm ; cin = 32'd1; end
- CMN: begin op1 = rn ; op2 = rm ; cin = 32'd0; end
-
- default:
- begin
- op1 = 0;
- op2 = 0;
- cin = 0;
- end
- endcase
-end
-
-// ----------------------------------------------------------------------------
-// Functions
-// ----------------------------------------------------------------------------
-
-// Process logical instructions.
-function [35:0] process_logical_instructions
-(
- input [31:0] rn,
- input [31:0] rm,
- input [3:0] flags,
- input [zap_clog2(ALU_OPS)-1:0] op,
- input i_flag_upd, input nozero
-);
-begin: blk2
- reg [31:0] rd;
- reg [3:0] flags_out;
-
- // Avoid accidental latch inference.
- rd = 0;
- flags_out = 0;
-
- case(op)
- AND: rd = rn & rm;
- EOR: rd = rn ^ rm;
- BIC: rd = rn & ~(rm);
- MOV: rd = rm;
- MVN: rd = ~rm;
- ORR: rd = rn | rm;
- TST: rd = rn & rm; // Target is not written.
- TEQ: rd = rn ^ rn; // Target is not written.
- default:
- begin
- rd = 0;
- $display("*Error: Logic unit got non logic opcode...");
- $finish;
- end
- endcase
-
- // Suppose flags are not going to change at ALL.
- flags_out = flags;
-
- // Assign values to the flags only if an update is requested. Note that V
- // is not touched even if change is requested.
- if ( i_flag_upd )
- begin
- // V is preserved since flags_out = flags assignment.
- flags_out[_C] = i_shift_carry_ff;
-
- if ( nozero )
- // This specifically states that we must NOT set the
- // ZERO flag under any circumstance.
- flags_out[_Z] = 1'd0;
- else
- flags_out[_Z] = (rd == 0);
-
- flags_out[_N] = rd[31];
- end
-
- process_logical_instructions = {flags_out, rd};
-end
-endfunction
-
-/*
- * This task clears out the flip-flops in this module.
- * The flag input is used to preserve/force flags to
- * a specific state.
- */
-task clear ( input [31:0] flags );
-begin
- o_dav_ff <= 0;
- flags_ff <= flags;
- o_abt_ff <= 0;
- o_irq_ff <= 0;
- o_fiq_ff <= 0;
- o_swi_ff <= 0;
- o_und_ff <= 0;
- sleep_ff <= 0;
- o_mem_load_ff <= 0;
- o_mem_store_ff <= 0;
-end
-endtask
-
-/*
- * The reason we use the duplicate function is to copy value over the memory
- * bus for memory stores. If we have a byte write to address 1, then the
- * memory controller basically takes address 0 and byte enable 0010 and writes
- * to address 1. This enables implementation of a 32-bit memory controller
- * with byte enables to control updates as is commonly done. Basically this
- * is to faciliate byte and halfword based writes on a 32-bit aligned memory
- * bus using byte enables. The rules are simple:
- * For a byte access - duplicate the lower byte of the register 4 times.
- * For halfword access - duplicate the lower 16-bit of the register twice.
- */
-
-function [31:0] duplicate ( input ub, // Unsigned byte.
- input sb, // Signed byte.
- input uh, // Unsigned halfword.
- input sh, // Signed halfword.
- input [31:0] val );
-reg [31:0] x;
-begin
- if ( ub || sb)
- begin
- // Byte.
- x = {val[7:0], val[7:0], val[7:0], val[7:0]};
- end
- else if (uh || sh)
- begin
- // Halfword.
- x = {val[15:0], val[15:0]};
- end
- else
- begin
- x = val;
- end
-
- duplicate = x;
-end
-endfunction
-
-/*
- * Generate byte enables based on access mode.
- * This function is similar in spirit to the previous one. The
- * byte enables are generated in such a way that along with
- * duplicate - byte and halfword accesses are possible.
- * Rules -
- * For a byte access, generate a byte enable with a 1 at the
- * position that the lower 2-bits read (0,1,2,3).
- * For a halfword access, based on lower 2-bits, if it is 00,
- * make no change to byte enable (0011) else if it is 10, then
- * make byte enable as (1100) which is basically the 32-bit
- * address + 2 (and 3) which will be written.
- */
-function [3:0] generate_ben ( input ub, // Unsigned byte.
- input sb, // Signed byte.
- input uh, // Unsigned halfword.
- input sh, // Signed halfword.
- input [31:0] addr );
-reg [3:0] x;
-begin
- if ( ub || sb ) // Byte oriented.
- begin
- case ( addr[1:0] ) // Based on address lower 2-bits.
- 0: x = 1;
- 1: x = 1 << 1;
- 2: x = 1 << 2;
- 3: x = 1 << 3;
- endcase
- end
- else if ( uh || sh ) // Halfword. A word = 2 half words.
- begin
- case ( addr[1] )
- 0: x = 4'b0011;
- 1: x = 4'b1100;
- endcase
- end
- else
- begin
- x = 4'b1111; // Word oriented.
- end
-
- generate_ben = x;
-end
-endfunction // generate_ben
-
-/*
- * This assertion ensures that no privilege escalation is possible.
- * It does so by ensuring that the flag register cannot change out
- * of USR during normal operation.
- */
-always @*
-begin
- if ( flags_nxt[`CPSR_MODE] != USR && flags_ff[`CPSR_MODE] == USR )
- begin
- $display($time, " - %m :: Error: Privilege Escalation Error.");
- $stop;
- end
-end
-
-reg [64*8-1:0] OPCODE;
-
-always @*
-case(opcode)
- AND:begin OPCODE = "AND"; end
- EOR:begin OPCODE = "EOR"; end
- MOV:begin OPCODE = "MOV"; end
- MVN:begin OPCODE = "MVN"; end
- BIC:begin OPCODE = "BIC"; end
- ORR:begin OPCODE = "ORR"; end
- TST:begin OPCODE = "TST"; end
- TEQ:begin OPCODE = "TEQ"; end
- CLZ:begin OPCODE = "CLZ"; end
- FMOV:begin OPCODE = "FMOV"; end
- ADD:begin OPCODE = "ADD"; end
- ADC:begin OPCODE = "ADC"; end
- SUB:begin OPCODE = "SUB"; end
- RSB:begin OPCODE = "RSB"; end
- SBC:begin OPCODE = "SBC"; end
- RSC:begin OPCODE = "RSC"; end
- CMP:begin OPCODE = "CMP"; end
- CMN:begin OPCODE = "CMN"; end
-endcase
-
-endmodule // zap_alu_main.v
-
-`default_nettype wire
-
-// ----------------------------------------------------------------------------
-// END OF FILE
-// ----------------------------------------------------------------------------
Index: zap/trunk/src/rtl/cpu/zap_decode_main.v
===================================================================
--- zap/trunk/src/rtl/cpu/zap_decode_main.v (revision 57)
+++ zap/trunk/src/rtl/cpu/zap_decode_main.v (nonexistent)
@@ -1,393 +0,0 @@
-// -----------------------------------------------------------------------------
-// -- --
-// -- (C) 2016-2018 Revanth Kamaraj. --
-// -- --
-// -- --------------------------------------------------------------------------
-// -- --
-// -- This program is free software; you can redistribute it and/or --
-// -- modify it under the terms of the GNU General Public License --
-// -- as published by the Free Software Foundation; either version 2 --
-// -- of the License, or (at your option) any later version. --
-// -- --
-// -- This program 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 General Public License for more details. --
-// -- --
-// -- You should have received a copy of the GNU General Public License --
-// -- along with this program; if not, write to the Free Software --
-// -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA --
-// -- 02110-1301, USA. --
-// -- --
-// -----------------------------------------------------------------------------
-// -- --
-// -- This module decodes 32-bit ARM instructions into an internal wide --
-// -- instruction format that is understood by downstream logic. --
-// -- --
-// -----------------------------------------------------------------------------
-
-`default_nettype none
-
-module zap_decode_main #(
- // Number of architectural registers.
- parameter [31:0] ARCH_REGS = 32'd32,
-
- // Number of arithm. opcodes
- parameter ALU_OPS = 32,
-
- // Total shift operations supported.
- parameter SHIFT_OPS = 6,
-
- // Number of physical registers.
- parameter PHY_REGS = 46
-)
-(
- output reg [64*8-1:0] o_decompile, // For debug purposes.
-
- // -------------------
- // Inputs.
- // -------------------
-
- // Clock and reset.
- input wire i_clk,
- input wire i_reset,
-
- // Branch state.
- input wire [1:0] i_taken,
-
- // Thumb undefined.
- input wire i_thumb_und,
-
- // Force 32-bit
- input wire i_force32align,
-
- // Clear and stall signals. High to low priority.
- input wire i_clear_from_writeback, // | Priority
- input wire i_data_stall, // |
- input wire i_clear_from_alu, // |
- input wire i_stall_from_shifter, // |
- input wire i_stall_from_issue, // V
-
- // Interrupt events.
- input wire i_irq,
- input wire i_fiq,
- input wire i_abt,
-
- // PC input.
- input wire [31:0] i_pc_ff,
- input wire [31:0] i_pc_plus_8_ff,
-
- // CPU mode. Taken from CPSR.
- input wire [4:0] i_cpsr_ff_mode, // Mode.
- input wire i_cpsr_ff_i, // IRQ state.
- input wire i_cpsr_ff_f, // FIQ state.
-
- // Instruction input.
- input wire [35:0] i_instruction,
- input wire i_instruction_valid,
-
- // ------------------------
- // Outputs.
- // ------------------------
-
- // This signal is used to check the validity of a pipeline stage.
- output reg [3:0] o_condition_code_ff,
-
- //
- // Where the primary output of the instruction must go to. Make this RAZ
- // to throw away the primary output to a void.
- //
- output reg [$clog2(PHY_REGS)-1:0] o_destination_index_ff,
-
- //
- // The ALU source is the source that is fed directly to the ALU without the
- // barrel shifter. For multiplication, o_alu_source simply becomes an operand.
- // For alu_source_ff, if bit 32 is 1, then [31:0] is a constant else
- // [31:0] is a register index (lower 6-bit effectively).
- //
- output reg [32:0] o_alu_source_ff,
- output reg [$clog2(ALU_OPS)-1:0] o_alu_operation_ff,
-
- //
- // Stuff related to the shifter. For multiplication, the source and length
- // simply become two operands. For shift_source_ff and shift_length_ff,
- // bit 32 has the same meaning as for o_alu_source_ff.
- //
- output reg [32:0] o_shift_source_ff,
- output reg [$clog2(SHIFT_OPS)-1:0] o_shift_operation_ff,
- output reg [32:0] o_shift_length_ff,
-
- //
- // Update the flags. Note that writing to CPSR will cause a flag-update (if
- // you asked for) even if this is 0.
- //
- output reg o_flag_update_ff,
-
- // Things related to memory operations.
-
- //
- // Data register index. Register is read
- // for stores and written for loads.
- //
- output reg [$clog2(PHY_REGS)-1:0] o_mem_srcdest_index_ff,
-
- // Load or store.
- output reg o_mem_load_ff,
- output reg o_mem_store_ff,
-
- // Indicate pre-ALU tap for address since pre-index.
- output reg o_mem_pre_index_ff,
-
- // Access size and type.
-
- // Unsigned byte access.
- output reg o_mem_unsigned_byte_enable_ff,
-
- // Signed byte access.
- output reg o_mem_signed_byte_enable_ff,
-
- // Signed halfword access.
- output reg o_mem_signed_halfword_enable_ff,
-
- // Unsigned halfword access.
- output reg o_mem_unsigned_halfword_enable_ff,
-
- // Force user view of memory.
- output reg o_mem_translate_ff,
-
- // PC output. Simply clocked out.
- output reg [31:0] o_pc_plus_8_ff,
- output reg [31:0] o_pc_ff,
-
- // Switch.
- output reg o_switch_ff,
-
- // Interrupts.
- output reg o_irq_ff, // Goes through mask.
- output reg o_fiq_ff, // Goes through mask.
- output reg o_abt_ff, // Clocked out.
- output reg o_und_ff, // Undefined instr.
- output reg o_swi_ff, // SWI encountered.
- // EXECUTE tests for condition validity and triggers SWI.
-
- // Force 32-bit alignment on memory accesses. Simply clocked out.
- output reg o_force32align_ff,
-
- // Branch state. Simply clocked out.
- output reg [1:0] o_taken_ff
-);
-
-// ----------------------------------------------------------------------------
-
-`include "zap_defines.vh"
-`include "zap_localparams.vh"
-`include "zap_functions.vh"
-
-wire [3:0] o_condition_code_nxt;
-wire [$clog2(PHY_REGS )-1:0] o_destination_index_nxt;
-wire [32:0] o_alu_source_nxt;
-wire [$clog2(ALU_OPS)-1:0] o_alu_operation_nxt;
-wire [32:0] o_shift_source_nxt;
-wire [$clog2(SHIFT_OPS)-1:0] o_shift_operation_nxt;
-wire [32:0] o_shift_length_nxt;
-wire o_flag_update_nxt;
-wire [$clog2(PHY_REGS )-1:0] o_mem_srcdest_index_nxt; // Data register.
-wire o_mem_load_nxt; // Type of operation...
-wire o_mem_store_nxt;
-wire o_mem_pre_index_nxt; // Indicate pre-ALU tap for address.
-wire o_mem_unsigned_byte_enable_nxt;// Byte enable (unsigned).
-wire o_mem_signed_byte_enable_nxt;
-wire o_mem_signed_halfword_enable_nxt;
-wire o_mem_unsigned_halfword_enable_nxt;
-wire o_mem_translate_nxt; // Force user's view of memory.
-wire o_force_locked_access_nxt;
-wire o_irq_nxt;
-wire o_fiq_nxt;
-wire o_abt_nxt;
-reg o_swi_nxt;
-wire o_und_nxt;
-wire o_switch_nxt;
-
-wire [$clog2(ARCH_REGS)-1:0] destination_index_nxt;
-wire [32:0] alu_source_nxt;
-wire [32:0] shift_source_nxt;
-wire [32:0] shift_length_nxt;
-wire [$clog2(ARCH_REGS)-1:0] mem_srcdest_index_nxt;
-
-// ----------------------------------------------------------------------------
-
-// Abort
-assign o_abt_nxt = (i_abt || i_thumb_und) && i_instruction_valid;
-
-// IRQ and FIQ next state.
-assign o_irq_nxt = i_irq & !i_cpsr_ff_i; // Pass only when mask is 0.
-assign o_fiq_nxt = i_fiq & !i_cpsr_ff_f; // Pass only when mask is 0.
-
-//
-// This section translates the indices from the decode stage converts
-// into a physical index. This is needed because the decode.v module extracts
-// architectural register numbers.
-//
-assign o_destination_index_nxt = // Always a register so no need for IMMED_EN.
- translate ( destination_index_nxt, i_cpsr_ff_mode );
-
-assign o_alu_source_nxt =
- (alu_source_nxt[32] == IMMED_EN ) ? // Constant...?
- alu_source_nxt : // Pass constant on.
- translate ( alu_source_nxt, i_cpsr_ff_mode ); // Translate index.
-
-assign o_shift_source_nxt =
- (shift_source_nxt[32] == IMMED_EN ) ? // Constant...?
- shift_source_nxt : // Pass constant on.
- translate ( shift_source_nxt, i_cpsr_ff_mode ); // Translate index.
-
-assign o_shift_length_nxt =
- (shift_length_nxt[32] == IMMED_EN ) ? // Constant...?
- shift_length_nxt : // Pass constant on.
- translate ( shift_length_nxt, i_cpsr_ff_mode ); // Translate index.
-
-assign o_mem_srcdest_index_nxt = // Always a register so no need for IMMED_EN.
- translate ( mem_srcdest_index_nxt, i_cpsr_ff_mode );
-
-
-// ----------------------------------------------------------------------------
-
-//
-// The actual decision whether or not to execute this is taken in EX stage.
-// At this point, we don't do anything with the SWI except take note.
-//
-always @*
- o_swi_nxt = &i_instruction[27:24];
-
-// ----------------------------------------------------------------------------
-
-wire [64*8-1:0] decompile_tmp;
-
-// Flop the outputs to break the pipeline at this point.
-always @ (posedge i_clk)
-begin
- if ( i_reset )
- begin
- clear;
- end
- else if ( i_clear_from_writeback )
- begin
- clear;
- end
- else if ( i_data_stall )
- begin
- // Preserve state.
- end
- else if ( i_clear_from_alu )
- begin
- clear;
- end
- else if ( i_stall_from_shifter )
- begin
- // Preserve state.
- end
- else if ( i_stall_from_issue )
- begin
- // Preserve state.
- end
- // If no stall, only then update...
- else
- begin
- o_irq_ff <= o_irq_nxt;
- o_fiq_ff <= o_fiq_nxt;
- o_swi_ff <= o_swi_nxt;
- o_abt_ff <= o_abt_nxt;
- o_und_ff <= o_und_nxt;
- o_condition_code_ff <= o_condition_code_nxt;
- o_destination_index_ff <= o_destination_index_nxt;
- o_alu_source_ff <= o_alu_source_nxt;
- o_alu_operation_ff <= o_alu_operation_nxt;
- o_shift_source_ff <= o_shift_source_nxt;
- o_shift_operation_ff <= o_shift_operation_nxt;
- o_shift_length_ff <= o_shift_length_nxt;
- o_flag_update_ff <= o_flag_update_nxt;
- o_mem_srcdest_index_ff <= o_mem_srcdest_index_nxt;
- o_mem_load_ff <= o_mem_load_nxt;
- o_mem_store_ff <= o_mem_store_nxt;
- o_mem_pre_index_ff <= o_mem_pre_index_nxt;
- o_mem_unsigned_byte_enable_ff <= o_mem_unsigned_byte_enable_nxt;
- o_mem_signed_byte_enable_ff <= o_mem_signed_byte_enable_nxt;
- o_mem_signed_halfword_enable_ff <= o_mem_signed_halfword_enable_nxt;
- o_mem_unsigned_halfword_enable_ff <= o_mem_unsigned_halfword_enable_nxt;
- o_mem_translate_ff <= o_mem_translate_nxt;
- o_pc_plus_8_ff <= i_pc_plus_8_ff;
- o_pc_ff <= i_pc_ff;
- o_switch_ff <= o_switch_nxt;
- o_force32align_ff <= i_force32align;
- o_taken_ff <= i_taken;
-
- // For debug
- o_decompile <= decompile_tmp;
- end
-end
-
-// ----------------------------------------------------------------------------
-
-task clear; // Clear and refresh the unit. Clear everything and a set a dummy
- // output to NV acting like a reset.
-begin
- o_irq_ff <= 0;
- o_fiq_ff <= 0;
- o_swi_ff <= 0;
- o_abt_ff <= 0;
- o_condition_code_ff <= NV;
- o_und_ff <= 0;
- o_taken_ff <= 0;
-end
-endtask
-
-// ----------------------------------------------------------------------------
-
-// Bulk of the decode logic is here.
-zap_decode #(
- .ARCH_REGS (ARCH_REGS),
- .ALU_OPS (ALU_OPS),
- .SHIFT_OPS (SHIFT_OPS)
-)
-u_zap_decode (
- .i_irq(i_irq),
- .i_fiq(i_fiq),
- .i_abt(i_abt),
- .i_instruction(i_instruction),
- .i_instruction_valid(i_instruction_valid),
- .i_cpsr_ff_mode(i_cpsr_ff_mode),
- .o_condition_code(o_condition_code_nxt),
- .o_destination_index(destination_index_nxt),
- .o_alu_source(alu_source_nxt),
- .o_alu_operation(o_alu_operation_nxt),
- .o_shift_source(shift_source_nxt),
- .o_shift_operation(o_shift_operation_nxt),
- .o_shift_length(shift_length_nxt),
- .o_flag_update(o_flag_update_nxt),
- .o_mem_srcdest_index(mem_srcdest_index_nxt),
- .o_mem_load(o_mem_load_nxt),
- .o_mem_store(o_mem_store_nxt),
- .o_mem_pre_index(o_mem_pre_index_nxt),
- .o_mem_unsigned_byte_enable(o_mem_unsigned_byte_enable_nxt),
- .o_mem_signed_byte_enable(o_mem_signed_byte_enable_nxt),
- .o_mem_signed_halfword_enable(o_mem_signed_halfword_enable_nxt),
- .o_mem_unsigned_halfword_enable(o_mem_unsigned_halfword_enable_nxt),
- .o_mem_translate(o_mem_translate_nxt),
- .o_und(o_und_nxt),
- .o_switch(o_switch_nxt)
-);
-
-// -------------------------------------------------------------------------------
-
-// Decompile
-
-
-zap_decompile u_zap_decompile (
- .i_instruction (i_instruction),
- .i_dav (i_instruction_valid),
- .o_decompile (decompile_tmp)
-);
-
-
-endmodule // zap_decode_main.v
-`default_nettype wire
Index: zap/trunk/src/rtl/cpu/zap_core.v
===================================================================
--- zap/trunk/src/rtl/cpu/zap_core.v (revision 57)
+++ zap/trunk/src/rtl/cpu/zap_core.v (nonexistent)
@@ -1,1201 +0,0 @@
-// -----------------------------------------------------------------------------
-// -- --
-// -- (C) 2016-2018 Revanth Kamaraj. --
-// -- --
-// -- --------------------------------------------------------------------------
-// -- --
-// -- This program is free software; you can redistribute it and/or --
-// -- modify it under the terms of the GNU General Public License --
-// -- as published by the Free Software Foundation; either version 2 --
-// -- of the License, or (at your option) any later version. --
-// -- --
-// -- This program 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 General Public License for more details. --
-// -- --
-// -- You should have received a copy of the GNU General Public License --
-// -- along with this program; if not, write to the Free Software --
-// -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA --
-// -- 02110-1301, USA. --
-// -- --
-// -----------------------------------------------------------------------------
-// -- --
-// -- This is the ZAP core which contains the bare processor core without any --
-// -- cache or MMU. In other words, this is the bare pipeline. --
-// -- --
-// -----------------------------------------------------------------------------
-
-`default_nettype none
-
-module zap_core #(
- // Number of branch predictor entries.
- parameter [31:0] BP_ENTRIES = 1024,
-
- // Depth of FIFO.
- parameter [31:0] FIFO_DEPTH = 4
-)
-(
-
-// ------------------------------------------------
-// Clock and reset. Reset is synchronous.
-// ------------------------------------------------
-
-input wire i_clk,
-input wire i_reset,
-
-// -------------------------------------------------
-// Wishbone memory access for data.
-// -------------------------------------------------
-
-output wire o_data_wb_we,
-output wire o_data_wb_cyc,
-output wire o_data_wb_stb,
-output wire[31:0] o_data_wb_adr,
-input wire i_data_wb_ack,
-input wire i_data_wb_err,
-input wire [31:0] i_data_wb_dat,
-output wire [31:0] o_data_wb_dat,
-output wire [3:0] o_data_wb_sel,
-
-// Next state stuff for Wishbone data.
-output wire o_data_wb_we_nxt,
-output wire o_data_wb_cyc_nxt,
-output wire o_data_wb_stb_nxt,
-output wire [31:0] o_data_wb_dat_nxt,
-output wire [3:0] o_data_wb_sel_nxt,
-output wire [31:0] o_data_wb_adr_nxt,
-
-// Force user view.
-output wire o_mem_translate,
-
-// --------------------------------------------------
-// Interrupts. Active high.
-// --------------------------------------------------
-
-input wire i_fiq, // FIQ signal.
-input wire i_irq, // IRQ signal.
-
-// ---------------------------------------------------
-// Wishbone instruction access ports.
-// ---------------------------------------------------
-
-output wire [31:0] o_instr_wb_adr, // Code address.
-output wire o_instr_wb_cyc, // Always 1.
-output wire o_instr_wb_stb, // Always 1.
-output wire o_instr_wb_we, // Always 0.
-input wire [31:0] i_instr_wb_dat, // A 32-bit ZAP instruction.
-input wire i_instr_wb_ack, // Instruction available.
-input wire i_instr_wb_err, // Instruction abort fault. Given with ack = 1.
-output wire [3:0] o_instr_wb_sel, // wishbone byte select.
-
-// Instruction wishbone nxt ports.
-output wire [31:0] o_instr_wb_adr_nxt,
-output wire o_instr_wb_stb_nxt,
-
-// Determines user or supervisory mode. Cache must use this for VM.
-output wire [31:0] o_cpsr,
-
-// -----------------------------------------------------
-// For MMU/cache connectivity.
-// -----------------------------------------------------
-
-input wire [31:0] i_fsr,
-input wire [31:0] i_far,
-output wire [31:0] o_dac,
-output wire [31:0] o_baddr,
-output wire o_mmu_en,
-output wire [1:0] o_sr,
-output wire o_pid,
-output wire o_dcache_inv,
-output wire o_icache_inv,
-output wire o_dcache_clean,
-output wire o_icache_clean,
-output wire o_dtlb_inv,
-output wire o_itlb_inv,
-output wire o_dcache_en,
-output wire o_icache_en,
-input wire i_dcache_inv_done,
-input wire i_icache_inv_done,
-input wire i_dcache_clean_done,
-input wire i_icache_clean_done
-);
-
-// ----------------------------------------------------------------------------
-
-`include "zap_localparams.vh"
-`include "zap_defines.vh"
-`include "zap_functions.vh"
-
-localparam ARCH_REGS = 32;
-localparam ALU_OPS = 32;
-localparam SHIFT_OPS = 7;
-localparam PHY_REGS = TOTAL_PHY_REGS;
-localparam FLAG_WDT = 32;
-
-// ----------------------------------------------------------------------------
-
-// Low Bandwidth Coprocessor (COP) I/F to CP15 control block.
-wire copro_done; // COP done.
-wire copro_dav; // COP command valid.
-wire [31:0] copro_word; // COP command.
-wire copro_reg_en; // COP controls registers.
-wire [$clog2(PHY_REGS)-1:0] copro_reg_wr_index;// Reg. file write index.
-wire [$clog2(PHY_REGS)-1:0] copro_reg_rd_index;// Reg. file read index.
-wire [31:0] copro_reg_wr_data; // Reg. file write data.
-wire [31:0] copro_reg_rd_data; // Reg. file read data.
-
-wire reset; // Tied to i_reset.
-wire shelve; // From writeback.
-wire fiq; // Tied to FIQ.
-wire irq; // Tied to IRQ.
-
-// Clear and stall signals.
-wire stall_from_decode;
-wire clear_from_alu;
-wire stall_from_issue;
-wire clear_from_writeback;
-wire data_stall;
-wire code_stall;
-wire instr_valid;
-wire pipeline_is_not_empty;
-
-// Fetch
-wire [31:0] fetch_instruction; // Instruction from the fetch unit.
-wire fetch_valid; // Instruction valid from the fetch unit.
-wire fetch_instr_abort; // abort indicator.
-wire [31:0] fetch_pc_plus_8_ff; // PC + 8 generated from the fetch unit.
-wire [31:0] fetch_pc_ff; // PC generated from fetch unit.
-wire [1:0] fetch_bp_state;
-
-// FIFO.
-wire [31:0] fifo_pc_plus_8;
-wire fifo_valid;
-wire fifo_instr_abort;
-wire [31:0] fifo_instruction;
-wire [1:0] fifo_bp_state;
-
-// Predecode
-wire [31:0] predecode_pc_plus_8;
-wire [31:0] predecode_pc;
-wire predecode_irq;
-wire predecode_fiq;
-wire predecode_abt;
-wire [35:0] predecode_inst;
-wire predecode_val;
-wire predecode_force32;
-wire predecode_und;
-wire [1:0] predecode_taken;
-
-// Compressed decoder.
-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;
-
-// Decode
-wire [3:0] decode_condition_code;
-wire [$clog2(PHY_REGS)-1:0] decode_destination_index;
-wire [32:0] decode_alu_source_ff;
-wire [$clog2(ALU_OPS)-1:0] decode_alu_operation_ff;
-wire [32:0] decode_shift_source_ff;
-wire [$clog2(SHIFT_OPS)-1:0] decode_shift_operation_ff;
-wire [32:0] decode_shift_length_ff;
-wire decode_flag_update_ff;
-wire [$clog2(PHY_REGS)-1:0] decode_mem_srcdest_index_ff;
-wire decode_mem_load_ff;
-wire decode_mem_store_ff;
-wire decode_mem_pre_index_ff;
-wire decode_mem_unsigned_byte_enable_ff;
-wire decode_mem_signed_byte_enable_ff;
-wire decode_mem_signed_halfword_enable_ff;
-wire decode_mem_unsigned_halfword_enable_ff;
-wire decode_mem_translate_ff;
-wire decode_irq_ff;
-wire decode_fiq_ff;
-wire decode_abt_ff;
-wire decode_swi_ff;
-wire [31:0] decode_pc_plus_8_ff;
-wire [31:0] decode_pc_ff;
-wire decode_switch_ff;
-wire decode_force32_ff;
-wire decode_und_ff;
-wire clear_from_decode;
-wire [31:0] pc_from_decode;
-wire [1:0] decode_taken_ff;
-
-// Issue
-wire [$clog2(PHY_REGS)-1:0] issue_rd_index_0,
- issue_rd_index_1,
- issue_rd_index_2,
- issue_rd_index_3;
-
-wire [3:0] issue_condition_code_ff;
-wire [$clog2(PHY_REGS)-1:0] issue_destination_index_ff;
-wire [$clog2(ALU_OPS)-1:0] issue_alu_operation_ff;
-wire [$clog2(SHIFT_OPS)-1:0] issue_shift_operation_ff;
-wire issue_flag_update_ff;
-wire [$clog2(PHY_REGS)-1:0] issue_mem_srcdest_index_ff;
-wire issue_mem_load_ff;
-wire issue_mem_store_ff;
-wire issue_mem_pre_index_ff;
-wire issue_mem_unsigned_byte_enable_ff;
-wire issue_mem_signed_byte_enable_ff;
-wire issue_mem_signed_halfword_enable_ff;
-wire issue_mem_unsigned_halfword_enable_ff;
-wire issue_mem_translate_ff;
-wire issue_irq_ff;
-wire issue_fiq_ff;
-wire issue_abt_ff;
-wire issue_swi_ff;
-wire [31:0] issue_alu_source_value_ff;
-wire [31:0] issue_shift_source_value_ff;
-wire [31:0] issue_shift_length_value_ff;
-wire [31:0] issue_mem_srcdest_value_ff;
-wire [32:0] issue_alu_source_ff;
-wire [32:0] issue_shift_source_ff;
-wire [31:0] issue_pc_plus_8_ff;
-wire [31:0] issue_pc_ff;
-wire issue_shifter_disable_ff;
-wire issue_switch_ff;
-wire issue_force32_ff;
-wire issue_und_ff;
-wire [1:0] issue_taken_ff;
-
-wire [$clog2(PHY_REGS)-1:0] rd_index_0;
-wire [$clog2(PHY_REGS)-1:0] rd_index_1;
-wire [$clog2(PHY_REGS)-1:0] rd_index_2;
-wire [$clog2(PHY_REGS)-1:0] rd_index_3;
-
-// Shift
-wire [$clog2(PHY_REGS)-1:0] shifter_mem_srcdest_index_ff;
-wire shifter_mem_load_ff;
-wire shifter_mem_store_ff;
-wire shifter_mem_pre_index_ff;
-wire shifter_mem_unsigned_byte_enable_ff;
-wire shifter_mem_signed_byte_enable_ff;
-wire shifter_mem_signed_halfword_enable_ff;
-wire shifter_mem_unsigned_halfword_enable_ff;
-wire shifter_mem_translate_ff;
-wire [3:0] shifter_condition_code_ff;
-wire [$clog2(PHY_REGS)-1:0] shifter_destination_index_ff;
-wire [$clog2(ALU_OPS)-1:0] shifter_alu_operation_ff;
-wire shifter_nozero_ff;
-wire shifter_flag_update_ff;
-wire [31:0] shifter_mem_srcdest_value_ff;
-wire [31:0] shifter_alu_source_value_ff;
-wire [31:0] shifter_shifted_source_value_ff;
-wire shifter_shift_carry_ff;
-wire [31:0] shifter_pc_plus_8_ff;
-wire [31:0] shifter_pc_ff;
-wire shifter_irq_ff;
-wire shifter_fiq_ff;
-wire shifter_abt_ff;
-wire shifter_swi_ff;
-wire shifter_switch_ff;
-wire shifter_force32_ff;
-wire shifter_und_ff;
-wire stall_from_shifter;
-wire [1:0] shifter_taken_ff;
-
-// ALU
-wire [$clog2(SHIFT_OPS)-1:0] alu_shift_operation_ff;
-wire [31:0] alu_alu_result_nxt;
-wire [31:0] alu_alu_result_ff;
-wire alu_abt_ff;
-wire alu_irq_ff;
-wire alu_fiq_ff;
-wire alu_swi_ff;
-wire alu_dav_ff;
-wire alu_dav_nxt;
-wire [31:0] alu_pc_plus_8_ff;
-wire [31:0] pc_from_alu;
-wire [$clog2(PHY_REGS)-1:0] alu_destination_index_ff;
-wire [FLAG_WDT-1:0] alu_flags_ff;
-wire [$clog2(PHY_REGS)-1:0] alu_mem_srcdest_index_ff;
-wire alu_mem_load_ff;
-wire alu_und_ff;
-wire [31:0] alu_cpsr_nxt;
-wire confirm_from_alu;
-wire alu_sbyte_ff;
-wire alu_ubyte_ff;
-wire alu_shalf_ff;
-wire alu_uhalf_ff;
-wire [31:0] alu_address_ff;
-wire [31:0] alu_address_nxt;
-
-// Memory
-wire [31:0] memory_alu_result_ff;
-wire [$clog2(PHY_REGS)-1:0] memory_destination_index_ff;
-wire [$clog2(PHY_REGS)-1:0] memory_mem_srcdest_index_ff;
-wire memory_dav_ff;
-wire [31:0] memory_pc_plus_8_ff;
-wire memory_irq_ff;
-wire memory_fiq_ff;
-wire memory_swi_ff;
-wire memory_instr_abort_ff;
-wire memory_mem_load_ff;
-wire [FLAG_WDT-1:0] memory_flags_ff;
-wire [31:0] memory_mem_rd_data;
-wire memory_und_ff;
-wire memory_data_abt_ff;
-
-// Writeback
-wire [31:0] rd_data_0;
-wire [31:0] rd_data_1;
-wire [31:0] rd_data_2;
-wire [31:0] rd_data_3;
-wire [31:0] cpsr_nxt, cpsr;
-
-// Hijack interface - related to Writeback - ALU interaction.
-wire wb_hijack;
-wire [31:0] wb_hijack_op1;
-wire [31:0] wb_hijack_op2;
-wire wb_hijack_cin;
-wire [31:0] alu_hijack_sum;
-
-// Decompile chain for debugging.
-wire [64*8-1:0] decode_decompile;
-wire [64*8-1:0] issue_decompile;
-wire [64*8-1:0] shifter_decompile;
-wire [64*8-1:0] alu_decompile;
-wire [64*8-1:0] memory_decompile;
-wire [64*8-1:0] rb_decompile;
-
-// ----------------------------------------------------------------------------
-
-assign o_cpsr = alu_flags_ff;
-assign o_data_wb_adr = {alu_address_ff[31:2], 2'd0};
-assign o_data_wb_adr_nxt = {alu_address_nxt[31:2], 2'd0};
-assign o_instr_wb_we = 1'd0;
-assign o_instr_wb_sel = 4'b1111;
-assign reset = i_reset;
-assign irq = i_irq;
-assign fiq = i_fiq;
-assign data_stall = o_data_wb_stb && o_data_wb_cyc && !i_data_wb_ack;
-assign code_stall = (!o_instr_wb_stb && !o_instr_wb_cyc) || !i_instr_wb_ack;
-assign instr_valid = o_instr_wb_stb && o_instr_wb_cyc && i_instr_wb_ack & !shelve;
-assign pipeline_is_not_empty = predecode_val ||
- (decode_condition_code != NV) ||
- (issue_condition_code_ff != NV) ||
- (shifter_condition_code_ff!= NV) ||
- alu_dav_ff ||
- memory_dav_ff;
-
-// ----------------------------------------------------------------------------
-
-// =========================
-// FETCH STAGE
-// =========================
-zap_fetch_main
-#(
- .BP_ENTRIES(BP_ENTRIES)
-)
-u_zap_fetch_main (
- // Input.
- .i_clk (i_clk),
- .i_reset (reset),
-
- .i_code_stall (code_stall),
-
- .i_clear_from_writeback (clear_from_writeback),
- .i_clear_from_decode (clear_from_decode),
-
- .i_data_stall (1'd0),
-
- .i_clear_from_alu (clear_from_alu),
-
- .i_stall_from_shifter (1'd0),
- .i_stall_from_issue (1'd0),
- .i_stall_from_decode (1'd0),
-
- .i_pc_ff (o_instr_wb_adr),
- .i_instruction (i_instr_wb_dat),
- .i_valid (instr_valid),
- .i_instr_abort (i_instr_wb_err),
-
- .i_cpsr_ff_t (alu_flags_ff[T]),
-
- // Output.
- .o_instruction (fetch_instruction),
- .o_valid (fetch_valid),
- .o_instr_abort (fetch_instr_abort),
- .o_pc_plus_8_ff (fetch_pc_plus_8_ff),
- .o_pc_ff (fetch_pc_ff),
-
-
- .i_confirm_from_alu (confirm_from_alu),
- .i_pc_from_alu (shifter_pc_ff),
- .i_taken (shifter_taken_ff),
- .o_taken (fetch_bp_state)
-);
-
-// =========================
-// FIFO.
-// =========================
-zap_fifo
-#( .WDT(67), .DEPTH(FIFO_DEPTH) ) U_ZAP_FIFO (
- .i_clk (i_clk),
- .i_reset (i_reset),
- .i_clear_from_writeback (clear_from_writeback),
-
- .i_write_inhibit ( code_stall ),
- .i_data_stall ( data_stall ),
-
- .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_instr ({fetch_pc_plus_8_ff, fetch_instr_abort, fetch_instruction, fetch_bp_state}),
- .i_valid (fetch_valid),
- .o_instr ({fifo_pc_plus_8, fifo_instr_abort, fifo_instruction, fifo_bp_state}),
- .o_valid (fifo_valid),
-
- .o_wb_stb (o_instr_wb_stb),
- .o_wb_stb_nxt (o_instr_wb_stb_nxt),
- .o_wb_cyc (o_instr_wb_cyc)
-);
-
-// =========================
-// COMPRESSED DECODER STAGE
-// =========================
-zap_thumb_decoder u_zap_thumb_decoder (
-.i_clk (i_clk),
-.i_reset (i_reset),
-.i_clear_from_writeback (clear_from_writeback),
-.i_data_stall (data_stall),
-.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 && !alu_flags_ff[I] : 1'd0), // Pass interrupt only if mask = 0 and instruction exists.
-.i_fiq (fifo_valid ? fiq && !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 (alu_flags_ff[T] ? fifo_pc_plus_8 - 32'd4 : 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 #(
- .ARCH_REGS(ARCH_REGS),
- .PHY_REGS(PHY_REGS),
- .SHIFT_OPS(SHIFT_OPS),
- .ALU_OPS(ALU_OPS),
- .COPROCESSOR_INTERFACE_ENABLE(1'd1),
- .COMPRESSED_EN(1'd1)
-)
-u_zap_predecode (
- // Input.
- .i_clk (i_clk),
- .i_reset (reset),
-
- .i_clear_from_writeback (clear_from_writeback),
- .i_data_stall (data_stall),
- .i_clear_from_alu (clear_from_alu),
- .i_stall_from_shifter (stall_from_shifter),
- .i_stall_from_issue (stall_from_issue),
-
- .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_mode (alu_flags_ff[`CPSR_MODE]),
-
- .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 (pipeline_is_not_empty),
-
- // Output.
- .o_stall_from_decode (stall_from_decode),
- .o_pc_plus_8_ff (predecode_pc_plus_8),
-
- .o_pc_ff (predecode_pc),
- .o_irq_ff (predecode_irq),
- .o_fiq_ff (predecode_fiq),
- .o_abt_ff (predecode_abt),
- .o_und_ff (predecode_und),
-
- .o_force32align_ff (predecode_force32),
-
- .o_copro_dav_ff (copro_dav),
- .o_copro_word_ff (copro_word),
-
- .o_clear_from_decode (clear_from_decode),
- .o_pc_from_decode (pc_from_decode),
-
- .o_instruction_ff (predecode_inst),
- .o_instruction_valid_ff (predecode_val),
-
- .o_taken_ff (predecode_taken)
-);
-
-// =====================
-// DECODE STAGE
-// =====================
-
-zap_decode_main #(
- .ARCH_REGS(ARCH_REGS),
- .PHY_REGS(PHY_REGS),
- .SHIFT_OPS(SHIFT_OPS),
- .ALU_OPS(ALU_OPS)
-)
-u_zap_decode_main (
- .o_decompile (decode_decompile),
-
- // Input.
- .i_clk (i_clk),
- .i_reset (reset),
-
- .i_clear_from_writeback (clear_from_writeback),
- .i_data_stall (data_stall),
- .i_clear_from_alu (clear_from_alu),
- .i_stall_from_shifter (stall_from_shifter),
- .i_stall_from_issue (stall_from_issue),
- .i_thumb_und (predecode_und),
- .i_irq (predecode_irq),
- .i_fiq (predecode_fiq),
- .i_abt (predecode_abt),
- .i_pc_plus_8_ff (predecode_pc_plus_8),
- .i_pc_ff (predecode_pc),
-
- .i_cpsr_ff_mode (alu_flags_ff[`CPSR_MODE]),
- .i_cpsr_ff_i (alu_flags_ff[I]),
- .i_cpsr_ff_f (alu_flags_ff[F]),
-
- .i_instruction (predecode_inst),
- .i_instruction_valid (predecode_val),
- .i_taken (predecode_taken),
- .i_force32align (predecode_force32),
-
- // Output.
- .o_condition_code_ff (decode_condition_code),
- .o_destination_index_ff (decode_destination_index),
- .o_alu_source_ff (decode_alu_source_ff),
- .o_alu_operation_ff (decode_alu_operation_ff),
- .o_shift_source_ff (decode_shift_source_ff),
- .o_shift_operation_ff (decode_shift_operation_ff),
- .o_shift_length_ff (decode_shift_length_ff),
- .o_flag_update_ff (decode_flag_update_ff),
- .o_mem_srcdest_index_ff (decode_mem_srcdest_index_ff),
- .o_mem_load_ff (decode_mem_load_ff),
- .o_mem_store_ff (decode_mem_store_ff),
- .o_mem_pre_index_ff (decode_mem_pre_index_ff),
- .o_mem_unsigned_byte_enable_ff (decode_mem_unsigned_byte_enable_ff),
- .o_mem_signed_byte_enable_ff (decode_mem_signed_byte_enable_ff),
- .o_mem_signed_halfword_enable_ff(decode_mem_signed_halfword_enable_ff),
- .o_mem_unsigned_halfword_enable_ff (decode_mem_unsigned_halfword_enable_ff),
- .o_mem_translate_ff (decode_mem_translate_ff),
- .o_pc_plus_8_ff (decode_pc_plus_8_ff),
- .o_pc_ff (decode_pc_ff),
- .o_switch_ff (decode_switch_ff),
- .o_irq_ff (decode_irq_ff),
- .o_fiq_ff (decode_fiq_ff),
- .o_abt_ff (decode_abt_ff),
- .o_swi_ff (decode_swi_ff),
- .o_und_ff (decode_und_ff),
- .o_force32align_ff (decode_force32_ff),
- .o_taken_ff (decode_taken_ff)
-);
-
-// ==================
-// ISSUE
-// ==================
-
-zap_issue_main #(
- .PHY_REGS(PHY_REGS),
- .SHIFT_OPS(SHIFT_OPS),
- .ALU_OPS(ALU_OPS)
-
-)
-u_zap_issue_main
-(
- .i_decompile(decode_decompile),
- .o_decompile(issue_decompile),
-
- .i_und_ff(decode_und_ff),
- .o_und_ff(issue_und_ff),
-
- .i_taken_ff(decode_taken_ff),
- .o_taken_ff(issue_taken_ff),
-
- .i_pc_ff(decode_pc_ff),
- .o_pc_ff(issue_pc_ff),
-
- // Inputs
- .i_clk (i_clk),
- .i_reset (reset),
- .i_clear_from_writeback (clear_from_writeback),
- .i_stall_from_shifter (stall_from_shifter),
- .i_data_stall (data_stall),
- .i_clear_from_alu (clear_from_alu),
- .i_pc_plus_8_ff (decode_pc_plus_8_ff),
- .i_condition_code_ff (decode_condition_code),
- .i_destination_index_ff (decode_destination_index),
- .i_alu_source_ff (decode_alu_source_ff),
- .i_alu_operation_ff (decode_alu_operation_ff),
- .i_shift_source_ff (decode_shift_source_ff),
- .i_shift_operation_ff (decode_shift_operation_ff),
- .i_shift_length_ff (decode_shift_length_ff),
- .i_flag_update_ff (decode_flag_update_ff),
- .i_mem_srcdest_index_ff (decode_mem_srcdest_index_ff),
- .i_mem_load_ff (decode_mem_load_ff),
- .i_mem_store_ff (decode_mem_store_ff),
- .i_mem_pre_index_ff (decode_mem_pre_index_ff),
- .i_mem_unsigned_byte_enable_ff (decode_mem_unsigned_byte_enable_ff),
- .i_mem_signed_byte_enable_ff (decode_mem_signed_byte_enable_ff),
- .i_mem_signed_halfword_enable_ff(decode_mem_signed_halfword_enable_ff),
- .i_mem_unsigned_halfword_enable_ff(decode_mem_unsigned_halfword_enable_ff),
- .i_mem_translate_ff (decode_mem_translate_ff),
- .i_irq_ff (decode_irq_ff),
- .i_fiq_ff (decode_fiq_ff),
- .i_abt_ff (decode_abt_ff),
- .i_swi_ff (decode_swi_ff),
- .i_cpu_mode (alu_flags_ff),
- // Needed to resolve CPSR refs.
-
- .i_force32align_ff (decode_force32_ff),
- .o_force32align_ff (issue_force32_ff),
-
- // Register file.
- .i_rd_data_0 (rd_data_0),
- .i_rd_data_1 (rd_data_1),
- .i_rd_data_2 (rd_data_2),
- .i_rd_data_3 (rd_data_3),
-
- // Feedback.
- .i_shifter_destination_index_ff (shifter_destination_index_ff),
- .i_alu_destination_index_ff (alu_destination_index_ff),
- .i_memory_destination_index_ff (memory_destination_index_ff),
- .i_alu_dav_nxt (alu_dav_nxt),
- .i_alu_dav_ff (alu_dav_ff),
- .i_memory_dav_ff (memory_dav_ff),
- .i_alu_destination_value_nxt (alu_alu_result_nxt),
- .i_alu_destination_value_ff (alu_alu_result_ff),
- .i_memory_destination_value_ff (memory_alu_result_ff),
- .i_shifter_mem_srcdest_index_ff (shifter_mem_srcdest_index_ff),
- .i_alu_mem_srcdest_index_ff (alu_mem_srcdest_index_ff),
- .i_memory_mem_srcdest_index_ff (memory_mem_srcdest_index_ff),
- .i_shifter_mem_load_ff (shifter_mem_load_ff),
- .i_alu_mem_load_ff (alu_mem_load_ff),
- .i_memory_mem_load_ff (memory_mem_load_ff),
- .i_memory_mem_srcdest_value_ff (memory_mem_rd_data),
-
- // Switch indicator.
- .i_switch_ff (decode_switch_ff),
- .o_switch_ff (issue_switch_ff),
-
- // Outputs.
- .o_rd_index_0 (rd_index_0),
- .o_rd_index_1 (rd_index_1),
- .o_rd_index_2 (rd_index_2),
- .o_rd_index_3 (rd_index_3),
- .o_condition_code_ff (issue_condition_code_ff),
- .o_destination_index_ff (issue_destination_index_ff),
- .o_alu_operation_ff (issue_alu_operation_ff),
- .o_shift_operation_ff (issue_shift_operation_ff),
- .o_flag_update_ff (issue_flag_update_ff),
- .o_mem_srcdest_index_ff (issue_mem_srcdest_index_ff),
- .o_mem_load_ff (issue_mem_load_ff),
- .o_mem_store_ff (issue_mem_store_ff),
- .o_mem_pre_index_ff (issue_mem_pre_index_ff),
- .o_mem_unsigned_byte_enable_ff (issue_mem_unsigned_byte_enable_ff),
- .o_mem_signed_byte_enable_ff (issue_mem_signed_byte_enable_ff),
- .o_mem_signed_halfword_enable_ff(issue_mem_signed_halfword_enable_ff),
- .o_mem_unsigned_halfword_enable_ff(issue_mem_unsigned_halfword_enable_ff),
- .o_mem_translate_ff (issue_mem_translate_ff),
- .o_irq_ff (issue_irq_ff),
- .o_fiq_ff (issue_fiq_ff),
- .o_abt_ff (issue_abt_ff),
- .o_swi_ff (issue_swi_ff),
-
- .o_alu_source_value_ff (issue_alu_source_value_ff),
- .o_shift_source_value_ff (issue_shift_source_value_ff),
- .o_shift_length_value_ff (issue_shift_length_value_ff),
- .o_mem_srcdest_value_ff (issue_mem_srcdest_value_ff),
-
- .o_alu_source_ff (issue_alu_source_ff),
- .o_shift_source_ff (issue_shift_source_ff),
- .o_stall_from_issue (stall_from_issue),
- .o_pc_plus_8_ff (issue_pc_plus_8_ff),
- .o_shifter_disable_ff (issue_shifter_disable_ff)
-);
-
-// =======================
-// SHIFTER STAGE
-// =======================
-
-zap_shifter_main #(
- .PHY_REGS(PHY_REGS),
- .ALU_OPS(ALU_OPS),
- .SHIFT_OPS(SHIFT_OPS)
-)
-u_zap_shifter_main
-(
- .i_decompile (issue_decompile),
- .o_decompile (shifter_decompile),
-
- .i_pc_ff (issue_pc_ff),
- .o_pc_ff (shifter_pc_ff),
-
- .i_taken_ff (issue_taken_ff),
- .o_taken_ff (shifter_taken_ff),
-
- .i_und_ff (issue_und_ff),
- .o_und_ff (shifter_und_ff),
-
- .o_nozero_ff (shifter_nozero_ff),
-
- .i_clk (i_clk),
- .i_reset (reset),
-
- .i_clear_from_writeback (clear_from_writeback),
- .i_data_stall (data_stall),
- .i_clear_from_alu (clear_from_alu),
- .i_condition_code_ff (issue_condition_code_ff),
- .i_destination_index_ff (issue_destination_index_ff),
- .i_alu_operation_ff (issue_alu_operation_ff),
- .i_shift_operation_ff (issue_shift_operation_ff),
- .i_flag_update_ff (issue_flag_update_ff),
- .i_mem_srcdest_index_ff (issue_mem_srcdest_index_ff),
- .i_mem_load_ff (issue_mem_load_ff),
- .i_mem_store_ff (issue_mem_store_ff),
- .i_mem_pre_index_ff (issue_mem_pre_index_ff),
- .i_mem_unsigned_byte_enable_ff (issue_mem_unsigned_byte_enable_ff),
- .i_mem_signed_byte_enable_ff (issue_mem_signed_byte_enable_ff),
- .i_mem_signed_halfword_enable_ff(issue_mem_signed_halfword_enable_ff),
- .i_mem_unsigned_halfword_enable_ff(issue_mem_unsigned_halfword_enable_ff),
- .i_mem_translate_ff (issue_mem_translate_ff),
- .i_irq_ff (issue_irq_ff),
- .i_fiq_ff (issue_fiq_ff),
- .i_abt_ff (issue_abt_ff),
- .i_swi_ff (issue_swi_ff),
- .i_alu_source_ff (issue_alu_source_ff),
- .i_shift_source_ff (issue_shift_source_ff),
- .i_alu_source_value_ff (issue_alu_source_value_ff),
- .i_shift_source_value_ff (issue_shift_source_value_ff),
- .i_shift_length_value_ff (issue_shift_length_value_ff),
- .i_mem_srcdest_value_ff (issue_mem_srcdest_value_ff),
- .i_pc_plus_8_ff (issue_pc_plus_8_ff),
- .i_disable_shifter_ff (issue_shifter_disable_ff),
-
- // Next CPSR.
- .i_cpsr_nxt (alu_cpsr_nxt),
- .i_cpsr_ff (alu_flags_ff),
-
- // Feedback
- .i_alu_value_nxt (alu_alu_result_nxt),
- .i_alu_dav_nxt (alu_dav_nxt),
-
- // Switch indicator.
- .i_switch_ff (issue_switch_ff),
- .o_switch_ff (shifter_switch_ff),
-
- // Force32
- .i_force32align_ff (issue_force32_ff),
- .o_force32align_ff (shifter_force32_ff),
-
- // Outputs.
-
- .o_mem_srcdest_value_ff (shifter_mem_srcdest_value_ff),
- .o_alu_source_value_ff (shifter_alu_source_value_ff),
- .o_shifted_source_value_ff (shifter_shifted_source_value_ff),
- .o_shift_carry_ff (shifter_shift_carry_ff),
-
- .o_pc_plus_8_ff (shifter_pc_plus_8_ff),
-
- .o_mem_srcdest_index_ff (shifter_mem_srcdest_index_ff),
- .o_mem_load_ff (shifter_mem_load_ff),
- .o_mem_store_ff (shifter_mem_store_ff),
- .o_mem_pre_index_ff (shifter_mem_pre_index_ff),
- .o_mem_unsigned_byte_enable_ff (shifter_mem_unsigned_byte_enable_ff),
- .o_mem_signed_byte_enable_ff (shifter_mem_signed_byte_enable_ff),
- .o_mem_signed_halfword_enable_ff(shifter_mem_signed_halfword_enable_ff),
- .o_mem_unsigned_halfword_enable_ff(shifter_mem_unsigned_halfword_enable_ff),
- .o_mem_translate_ff (shifter_mem_translate_ff),
-
- .o_condition_code_ff (shifter_condition_code_ff),
- .o_destination_index_ff (shifter_destination_index_ff),
- .o_alu_operation_ff (shifter_alu_operation_ff),
- .o_flag_update_ff (shifter_flag_update_ff),
-
- // Interrupts.
- .o_irq_ff (shifter_irq_ff),
- .o_fiq_ff (shifter_fiq_ff),
- .o_abt_ff (shifter_abt_ff),
- .o_swi_ff (shifter_swi_ff),
-
- // Stall
- .o_stall_from_shifter (stall_from_shifter)
-);
-
-// ===============
-// ALU STAGE
-// ===============
-
-zap_alu_main #(
- .PHY_REGS(PHY_REGS),
- .SHIFT_OPS(SHIFT_OPS),
- .ALU_OPS(ALU_OPS)
-)
-u_zap_alu_main
-(
- .i_decompile (shifter_decompile),
- .o_decompile (alu_decompile),
-
- .i_hijack ( wb_hijack ),
- .i_hijack_op1 ( wb_hijack_op1 ),
- .i_hijack_op2 ( wb_hijack_op2 ),
- .i_hijack_cin ( wb_hijack_cin ),
- .o_hijack_sum ( alu_hijack_sum ),
-
- .i_taken_ff (shifter_taken_ff),
- .o_confirm_from_alu (confirm_from_alu),
-
- .i_pc_ff (shifter_pc_ff),
-
- .i_und_ff (shifter_und_ff),
- .o_und_ff (alu_und_ff),
-
- .i_nozero_ff ( shifter_nozero_ff ),
-
- .i_clk (i_clk),
- .i_reset (reset),
- .i_clear_from_writeback (clear_from_writeback),
- .i_data_stall (data_stall),
- .i_cpsr_nxt (cpsr_nxt),
- .i_flag_update_ff (shifter_flag_update_ff),
- .i_switch_ff (shifter_switch_ff),
-
- .i_force32align_ff (shifter_force32_ff),
-
- .i_mem_srcdest_value_ff (shifter_mem_srcdest_value_ff),
- .i_alu_source_value_ff (shifter_alu_source_value_ff),
- .i_shifted_source_value_ff (shifter_shifted_source_value_ff),
- .i_shift_carry_ff (shifter_shift_carry_ff),
- .i_pc_plus_8_ff (shifter_pc_plus_8_ff),
-
- .i_abt_ff (shifter_abt_ff),
- .i_irq_ff (shifter_irq_ff),
- .i_fiq_ff (shifter_fiq_ff),
- .i_swi_ff (shifter_swi_ff),
-
- .i_mem_srcdest_index_ff (shifter_mem_srcdest_index_ff),
- .i_mem_load_ff (shifter_mem_load_ff),
- .i_mem_store_ff (shifter_mem_store_ff),
- .i_mem_pre_index_ff (shifter_mem_pre_index_ff),
- .i_mem_unsigned_byte_enable_ff (shifter_mem_unsigned_byte_enable_ff),
- .i_mem_signed_byte_enable_ff (shifter_mem_signed_byte_enable_ff),
- .i_mem_signed_halfword_enable_ff(shifter_mem_signed_halfword_enable_ff),
- .i_mem_unsigned_halfword_enable_ff(shifter_mem_unsigned_halfword_enable_ff),
- .i_mem_translate_ff (shifter_mem_translate_ff),
-
- .i_condition_code_ff (shifter_condition_code_ff),
- .i_destination_index_ff (shifter_destination_index_ff),
- .i_alu_operation_ff (shifter_alu_operation_ff), // {OP,S}
-
- .i_data_mem_fault (i_data_wb_err),
-
- .o_alu_result_nxt (alu_alu_result_nxt),
-
- .o_alu_result_ff (alu_alu_result_ff),
-
- .o_abt_ff (alu_abt_ff),
- .o_irq_ff (alu_irq_ff),
- .o_fiq_ff (alu_fiq_ff),
- .o_swi_ff (alu_swi_ff),
-
- .o_dav_ff (alu_dav_ff),
- .o_dav_nxt (alu_dav_nxt),
-
- .o_pc_plus_8_ff (alu_pc_plus_8_ff),
-
- // Data access address. Ignore [1:0].
- .o_mem_address_ff (alu_address_ff),
- .o_clear_from_alu (clear_from_alu),
- .o_pc_from_alu (pc_from_alu),
- .o_destination_index_ff (alu_destination_index_ff),
- .o_flags_ff (alu_flags_ff), // Output flags.
- .o_flags_nxt (alu_cpsr_nxt),
-
- .o_mem_srcdest_value_ff (),
- .o_mem_srcdest_index_ff (alu_mem_srcdest_index_ff),
- .o_mem_load_ff (alu_mem_load_ff),
- .o_mem_store_ff (),
-
- .o_ben_ff (),
-
- .o_mem_unsigned_byte_enable_ff (alu_ubyte_ff),
- .o_mem_signed_byte_enable_ff (alu_sbyte_ff),
- .o_mem_signed_halfword_enable_ff (alu_shalf_ff),
- .o_mem_unsigned_halfword_enable_ff(alu_uhalf_ff),
- .o_mem_translate_ff (o_mem_translate),
-
- .o_address_nxt ( alu_address_nxt ),
-
- .o_data_wb_we_nxt (o_data_wb_we_nxt),
- .o_data_wb_cyc_nxt (o_data_wb_cyc_nxt),
- .o_data_wb_stb_nxt (o_data_wb_stb_nxt),
- .o_data_wb_dat_nxt (o_data_wb_dat_nxt),
- .o_data_wb_sel_nxt (o_data_wb_sel_nxt),
-
- .o_data_wb_we_ff (o_data_wb_we),
- .o_data_wb_cyc_ff (o_data_wb_cyc),
- .o_data_wb_stb_ff (o_data_wb_stb),
- .o_data_wb_dat_ff (o_data_wb_dat),
- .o_data_wb_sel_ff (o_data_wb_sel)
-
-);
-
-// ====================
-// MEMORY
-// ====================
-
-zap_memory_main #(
- .PHY_REGS(PHY_REGS)
-)
-u_zap_memory_main
-(
- .i_decompile (alu_decompile),
- .o_decompile (memory_decompile),
-
- .i_und_ff (alu_und_ff),
- .o_und_ff (memory_und_ff),
-
- .i_mem_address_ff (alu_address_ff),
-
-
- .i_clk (i_clk),
- .i_reset (reset),
-
- .i_sbyte_ff (alu_sbyte_ff), // Signed byte.
- .i_ubyte_ff (alu_ubyte_ff), // Unsigned byte.
- .i_shalf_ff (alu_shalf_ff), // Signed half word.
- .i_uhalf_ff (alu_uhalf_ff), // Unsigned half word.
-
- .i_clear_from_writeback (clear_from_writeback),
- .i_data_stall (data_stall),
- .i_alu_result_ff (alu_alu_result_ff),
- .i_flags_ff (alu_flags_ff),
-
- .i_mem_load_ff (alu_mem_load_ff),
-
- .i_mem_rd_data (i_data_wb_dat),// From memory.
-
- .i_mem_fault (i_data_wb_err), // From cache.
-
- .o_mem_fault (memory_data_abt_ff),
-
-
- .i_dav_ff (alu_dav_ff),
- .i_pc_plus_8_ff (alu_pc_plus_8_ff),
-
- .i_destination_index_ff (alu_destination_index_ff),
-
- .i_irq_ff (alu_irq_ff),
- .i_fiq_ff (alu_fiq_ff),
- .i_instr_abort_ff (alu_abt_ff),
- .i_swi_ff (alu_swi_ff),
-
- // Used to speed up loads.
- .i_mem_srcdest_index_ff (alu_mem_srcdest_index_ff),
-
- // Can come in handy since this is reused for several other things.
- .i_mem_srcdest_value_ff (o_data_wb_dat),
-
- .o_alu_result_ff (memory_alu_result_ff),
- .o_flags_ff (memory_flags_ff),
-
- .o_destination_index_ff (memory_destination_index_ff),
- .o_mem_srcdest_index_ff (memory_mem_srcdest_index_ff),
-
- .o_dav_ff (memory_dav_ff),
- .o_pc_plus_8_ff (memory_pc_plus_8_ff),
-
- .o_irq_ff (memory_irq_ff),
- .o_fiq_ff (memory_fiq_ff),
- .o_swi_ff (memory_swi_ff),
- .o_instr_abort_ff (memory_instr_abort_ff),
-
- .o_mem_load_ff (memory_mem_load_ff),
-
-
- .o_mem_rd_data (memory_mem_rd_data)
-);
-
-// ==================
-// WRITEBACK
-// ==================
-
-zap_writeback #(
- .PHY_REGS(PHY_REGS)
-)
-u_zap_writeback
-(
- .i_decompile (memory_decompile),
- .o_decompile (rb_decompile),
-
- .o_shelve (shelve),
-
- .i_clk (i_clk), // ZAP clock.
-
-
- .i_reset (reset), // ZAP reset.
- .i_valid (memory_dav_ff),
- .i_data_stall (data_stall),
- .i_clear_from_alu (clear_from_alu),
- .i_pc_from_alu (pc_from_alu),
- .i_stall_from_decode (stall_from_decode),
- .i_stall_from_issue (stall_from_issue),
- .i_stall_from_shifter (stall_from_shifter),
-
- .i_thumb (alu_flags_ff[T]), // To indicate thumb state.
-
- .i_clear_from_decode (clear_from_decode),
- .i_pc_from_decode (pc_from_decode),
-
- .i_code_stall (code_stall),
-
- // Used to valid writes on i_wr_index1.
- .i_mem_load_ff (memory_mem_load_ff),
-
- .i_rd_index_0 (rd_index_0),
- .i_rd_index_1 (rd_index_1),
- .i_rd_index_2 (rd_index_2),
- .i_rd_index_3 (rd_index_3),
-
- .i_wr_index (memory_destination_index_ff),
- .i_wr_data (memory_alu_result_ff),
- .i_flags (memory_flags_ff),
- .i_wr_index_1 (memory_mem_srcdest_index_ff),// load index.
- .i_wr_data_1 (memory_mem_rd_data), // load data.
-
- .i_irq (memory_irq_ff),
- .i_fiq (memory_fiq_ff),
- .i_instr_abt (memory_instr_abort_ff),
- .i_data_abt (memory_data_abt_ff),
- .i_swi (memory_swi_ff),
- .i_und (memory_und_ff),
-
- .i_pc_buf_ff (memory_pc_plus_8_ff),
-
- .i_copro_reg_en (copro_reg_en),
- .i_copro_reg_wr_index (copro_reg_wr_index),
- .i_copro_reg_rd_index (copro_reg_rd_index),
- .i_copro_reg_wr_data (copro_reg_wr_data),
-
- .o_copro_reg_rd_data_ff (copro_reg_rd_data),
-
- .o_rd_data_0 (rd_data_0),
- .o_rd_data_1 (rd_data_1),
- .o_rd_data_2 (rd_data_2),
- .o_rd_data_3 (rd_data_3),
-
- .o_pc (o_instr_wb_adr),
- .o_pc_nxt (o_instr_wb_adr_nxt),
- .o_cpsr_nxt (cpsr_nxt),
- .o_clear_from_writeback (clear_from_writeback),
-
- .o_hijack (wb_hijack),
- .o_hijack_op1 (wb_hijack_op1),
- .o_hijack_op2 (wb_hijack_op2),
- .o_hijack_cin (wb_hijack_cin),
-
- .i_hijack_sum (alu_hijack_sum)
-);
-
-// ==================================
-// CP15 CB
-// ==================================
-
-zap_cp15_cb u_zap_cp15_cb (
- .i_clk (i_clk),
- .i_reset (i_reset),
- .i_cp_word (copro_word),
- .i_cp_dav (copro_dav),
- .o_cp_done (copro_done),
- .i_cpsr (o_cpsr),
- .o_reg_en (copro_reg_en),
- .o_reg_wr_data (copro_reg_wr_data),
- .i_reg_rd_data (copro_reg_rd_data),
- .o_reg_wr_index (copro_reg_wr_index),
- .o_reg_rd_index (copro_reg_rd_index),
-
- .i_fsr (i_fsr),
- .i_far (i_far),
- .o_dac (o_dac),
- .o_baddr (o_baddr),
- .o_mmu_en (o_mmu_en),
- .o_sr (o_sr),
- .o_pid (o_pid),
- .o_dcache_inv (o_dcache_inv),
- .o_icache_inv (o_icache_inv),
- .o_dcache_clean (o_dcache_clean),
- .o_icache_clean (o_icache_clean),
- .o_dtlb_inv (o_dtlb_inv),
- .o_itlb_inv (o_itlb_inv),
- .o_dcache_en (o_dcache_en),
- .o_icache_en (o_icache_en),
- .i_dcache_inv_done (i_dcache_inv_done),
- .i_icache_inv_done (i_icache_inv_done),
- .i_dcache_clean_done (i_dcache_clean_done),
- .i_icache_clean_done (i_icache_clean_done)
-);
-
-reg [(8*8)-1:0] CPU_MODE; // Max 8 characters i.e. 64-bit string.
-
-always @*
-case(o_cpsr[`CPSR_MODE])
-FIQ: CPU_MODE = "FIQ";
-IRQ: CPU_MODE = "IRQ";
-USR: CPU_MODE = "USR";
-UND: CPU_MODE = "UND";
-SVC: CPU_MODE = "SVC";
-ABT: CPU_MODE = "ABT";
-SYS: CPU_MODE = "SYS";
-default: CPU_MODE = "???";
-endcase
-
-endmodule // zap_core.v
-
-`default_nettype wire
-
-// ----------------------------------------------------------------------------
-// EOF
-// ----------------------------------------------------------------------------
Index: zap/trunk/src/rtl/cpu/zap_ram_simple.v
===================================================================
--- zap/trunk/src/rtl/cpu/zap_ram_simple.v (revision 57)
+++ zap/trunk/src/rtl/cpu/zap_ram_simple.v (nonexistent)
@@ -1,83 +0,0 @@
-// -----------------------------------------------------------------------------
-// -- --
-// -- (C) 2016-2018 Revanth Kamaraj. --
-// -- --
-// -- --------------------------------------------------------------------------
-// -- --
-// -- This program is free software; you can redistribute it and/or --
-// -- modify it under the terms of the GNU General Public License --
-// -- as published by the Free Software Foundation; either version 2 --
-// -- of the License, or (at your option) any later version. --
-// -- --
-// -- This program 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 General Public License for more details. --
-// -- --
-// -- You should have received a copy of the GNU General Public License --
-// -- along with this program; if not, write to the Free Software --
-// -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA --
-// -- 02110-1301, USA. --
-// -- --
-// -----------------------------------------------------------------------------
-// -- --
-// -- Synthesizes to standard 1R + 1W block RAM. The read and write addresses--
-// -- may be specified separately. Only for FPGA. --
-// -- --
-// -----------------------------------------------------------------------------
-
-`default_nettype none
-
-module zap_ram_simple #(
- parameter WIDTH = 32,
- parameter DEPTH = 32
-)
-(
- input wire i_clk,
-
- // Write and read enable.
- input wire i_wr_en,
- input wire i_rd_en,
-
- // Write data and address.
- input wire [WIDTH-1:0] i_wr_data,
- input wire[$clog2(DEPTH)-1:0] i_wr_addr,
-
- // Read address and data.
- input wire [$clog2(DEPTH)-1:0] i_rd_addr,
- output reg [WIDTH-1:0] o_rd_data
-);
-
-// Memory array.
-reg [WIDTH-1:0] mem [DEPTH-1:0];
-
-// Initialize block RAM to 0.
-initial
-begin: blk1
- integer i;
-
- for(i=0;i 16 bytes.
-
-// States.
-localparam IDLE = 0;
-localparam CACHE_CLEAN_GET_ADDRESS = 1;
-localparam CACHE_CLEAN_WRITE = 2;
-localparam CACHE_INV = 3;
-
-
-// ----------------------------------------------------------------------------
-
-reg [(CACHE_SIZE/16)-1:0] dirty;
-reg [(CACHE_SIZE/16)-1:0] valid;
-reg [`CACHE_TAG_WDT-1:0] tag_ram [(CACHE_SIZE/16)-1:0];
-reg [127:0] dat_ram [(CACHE_SIZE/16)-1:0];
-
-// ----------------------------------------------------------------------------
-
-reg [`CACHE_TAG_WDT-1:0] tag_ram_wr_data;
-reg tag_ram_wr_en;
-reg [$clog2(CACHE_SIZE/16)-1:0] tag_ram_wr_addr, tag_ram_rd_addr;
-reg tag_ram_clear;
-reg tag_ram_clean;
-
-// ----------------------------------------------------------------------------
-
-reg [1:0] state_ff, state_nxt;
-
-// ----------------------------------------------------------------------------
-
-reg [$clog2(NUMBER_OF_DIRTY_BLOCKS)-1:0] blk_ctr_ff, blk_ctr_nxt;
-reg [2:0] adr_ctr_ff, adr_ctr_nxt;
-
-// ----------------------------------------------------------------------------
-
-initial
-begin: blk1
- // FPGA anyway initializes to 0 on start.
- integer i;
-
- for(i=0;i 3 )
- begin
- // Remove dirty marking. BUG FIX.
- tag_ram_clean = 1;
-
- // Kill access.
- kill_access;
-
- // Go to new state.
- state_nxt = CACHE_CLEAN_GET_ADDRESS;
- end
- else
- begin: blk1111
- reg [31:0] shamt;
- reg [31:0] data;
- reg [31:0] pa;
-
- shamt = adr_ctr_nxt << 5;
- data = o_cache_line >> shamt;
- pa = {o_cache_tag[`CACHE_TAG__PA], 4'd0};
-
- // Perform a Wishbone write using Physical Address.
- wb_prpr_write( data, pa + (adr_ctr_nxt << 2), adr_ctr_nxt != 3 ? CTI_BURST : CTI_EOB, 4'b1111
- );
- end
- end
-
- CACHE_INV:
- begin
- tag_ram_clear = 1'd1;
- state_nxt = IDLE;
- o_cache_inv_done = 1'd1;
- end
-
- endcase
-end
-
-// -----------------------------------------------------------------------------
-
-// Priority encoder.
-function [4:0] pri_enc1 ( input [15:0] in );
-begin: priEncFn
- casez ( in )
- 16'b0000_0000_0000_0001: pri_enc1 = 4'd0;
- 16'b0000_0000_0000_001?: pri_enc1 = 4'd1;
- 16'b0000_0000_0000_01??: pri_enc1 = 4'd2;
- 16'b0000_0000_0000_1???: pri_enc1 = 4'd3;
- 16'b0000_0000_0001_????: pri_enc1 = 4'd4;
- 16'b0000_0000_001?_????: pri_enc1 = 4'd5;
- 16'b0000_0000_01??_????: pri_enc1 = 4'd6;
- 16'b0000_0000_1???_????: pri_enc1 = 4'd7;
- 16'b0000_0001_????_????: pri_enc1 = 4'd8;
- 16'b0000_001?_????_????: pri_enc1 = 4'd9;
- 16'b0000_01??_????_????: pri_enc1 = 4'hA;
- 16'b0000_1???_????_????: pri_enc1 = 4'hB;
- 16'b0001_????_????_????: pri_enc1 = 4'hC;
- 16'b001?_????_????_????: pri_enc1 = 4'hD;
- 16'b01??_????_????_????: pri_enc1 = 4'hE;
- 16'b1???_????_????_????: pri_enc1 = 4'hF;
- default: pri_enc1 = 5'b11111;
- endcase
-end
-endfunction
-
-// -----------------------------------------------------------------------------
-
-function [31:0] get_tag_ram_rd_addr (
-input [31:0] blk_ctr,
-input [CACHE_SIZE/16-1:0] dirty
-);
-reg [CACHE_SIZE/16-1:0] dirty_new;
-reg [3:0] enc;
-reg [31:0] shamt;
-begin
- shamt = blk_ctr_ff << 4;
- dirty_new = dirty >> shamt;
- enc = pri_enc1(dirty_new);
- get_tag_ram_rd_addr = shamt + enc;
-end
-endfunction
-
-// ----------------------------------------------------------------------------
-
-/* Function to generate Wishbone read signals. */
-task wb_prpr_read;
-input [31:0] i_address;
-input [2:0] i_cti;
-begin
- o_wb_cyc_nxt = 1'd1;
- o_wb_stb_nxt = 1'd1;
- o_wb_wen_nxt = 1'd0;
- o_wb_sel_nxt = 4'b1111;
- o_wb_adr_nxt = i_address;
- o_wb_cti_nxt = i_cti;
- o_wb_dat_nxt = 0;
-end
-endtask
-
-// ----------------------------------------------------------------------------
-
-/* Function to generate Wishbone write signals */
-task wb_prpr_write;
-input [31:0] i_data;
-input [31:0] i_address;
-input [2:0] i_cti;
-input [3:0] i_ben;
-begin
- o_wb_cyc_nxt = 1'd1;
- o_wb_stb_nxt = 1'd1;
- o_wb_wen_nxt = 1'd1;
- o_wb_sel_nxt = i_ben;
- o_wb_adr_nxt = i_address;
- o_wb_cti_nxt = i_cti;
- o_wb_dat_nxt = i_data;
-end
-endtask
-
-// ----------------------------------------------------------------------------
-
-/* Disables Wishbone */
-task kill_access;
-begin
- o_wb_cyc_nxt = 0;
- o_wb_stb_nxt = 0;
- o_wb_wen_nxt = 0;
- o_wb_adr_nxt = 0;
- o_wb_dat_nxt = 0;
- o_wb_sel_nxt = 0;
- o_wb_cti_nxt = CTI_CLASSIC;
-end
-endtask
-
-// ----------------------------------------------------------------------------
-
-function [4:0] baggage ( input [CACHE_SIZE/16-1:0] dirty, input [31:0] blk_ctr_ff );
-reg [31:0] shamt;
-integer i;
-begin
- shamt = blk_ctr_ff << 4;
- baggage = pri_enc1(dirty >> shamt);
-end
-endfunction
-
-endmodule // zap_cache_tag_ram.v
-
-`default_nettype wire
-
-// ----------------------------------------------------------------------------
-// END OF FILE
-// ----------------------------------------------------------------------------
-
Index: zap/trunk/src/rtl/cpu/zap_fetch_main.v
===================================================================
--- zap/trunk/src/rtl/cpu/zap_fetch_main.v (revision 57)
+++ zap/trunk/src/rtl/cpu/zap_fetch_main.v (nonexistent)
@@ -1,312 +0,0 @@
-// -----------------------------------------------------------------------------
-// -- --
-// -- (C) 2016-2018 Revanth Kamaraj. --
-// -- --
-// -- --------------------------------------------------------------------------
-// -- --
-// -- This program is free software; you can redistribute it and/or --
-// -- modify it under the terms of the GNU General Public License --
-// -- as published by the Free Software Foundation; either version 2 --
-// -- of the License, or (at your option) any later version. --
-// -- --
-// -- This program 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 General Public License for more details. --
-// -- --
-// -- You should have received a copy of the GNU General Public License --
-// -- along with this program; if not, write to the Free Software --
-// -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA --
-// -- 02110-1301, USA. --
-// -- --
-// -----------------------------------------------------------------------------
-// -- --
-// -- This is the simple I-cache frontend to the processor. This stage --
-// -- serves as a buffer for instructions. Data aborts are handled by adding --
-// -- an extra signal down the pipeline. Data aborts piggyback off --
-// -- AND R0, R0, R0. --
-// -- --
-// -----------------------------------------------------------------------------
-
-`default_nettype none
-
-module zap_fetch_main #(
- // Branch predictor entries.
- parameter BP_ENTRIES = 1024
-)
-(
-// Clock and reset.
-input wire i_clk, // ZAP clock.
-input wire i_reset, // Active high synchronous reset.
-
-//
-// From other parts of the pipeline. These
-// signals either tell the unit to invalidate
-// its outputs or freeze in place.
-//
-input wire i_code_stall, // |
-input wire i_clear_from_writeback, // | High Priority.
-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, // | Low Priority.
-input wire i_clear_from_decode, // V
-
-// Comes from WB unit.
-input wire [31:0] i_pc_ff, // Program counter.
-
-// Comes from CPSR
-input wire i_cpsr_ff_t, // CPSR T bit.
-
-// From I-cache.
-input wire [31:0] i_instruction, // A 32-bit ZAP instruction.
-
-input wire i_valid, // Instruction valid indicator.
-input wire i_instr_abort, // Instruction abort fault.
-
-
-// To decode.
-output reg [31:0] o_instruction, // The 32-bit instruction.
-output reg o_valid, // Instruction valid.
-output reg o_instr_abort, // Indication of an abort.
-output reg [31:0] o_pc_plus_8_ff, // PC +8 ouput.
-output reg [31:0] o_pc_ff, // PC output.
-
-// For BP.
-input wire i_confirm_from_alu, // Confirm branch prediction from ALU.
-input wire [31:0] i_pc_from_alu, // Address of branch.
-input wire [1:0] i_taken, // Predicted status.
-output wire [1:0] o_taken // Prediction. Not a flip-flop...
-
-);
-
-`include "zap_defines.vh"
-`include "zap_localparams.vh"
-`include "zap_functions.vh"
-
-// Unused signals are assigned to this.
-wire _unused_ok_;
-
-// If an instruction abort occurs, this unit sleeps until it is woken up.
-reg sleep_ff;
-
-// Taken_v
-wire [1:0] taken_v;
-
-// Predict non branches as not taken...
-assign o_taken = o_instruction[28:26] == 3'b101 ? taken_v : SNT;
-
-// ----------------------------------------------------------------------------
-
-//
-// This is the instruction payload on an abort
-// because no instruction is actually available on
-// an abort. This is AND R0, R0, R0 which is a NOP.
-//
-localparam ABORT_PAYLOAD = 32'd0;
-
-// Branch states.
-localparam [1:0] SNT = 2'b00; // Strongly Not Taken.
-localparam [1:0] WNT = 2'b01; // Weakly Not Taken.
-localparam [1:0] WT = 2'b10; // Weakly Taken.
-localparam [1:0] ST = 2'b11; // Strongly Taken.
-
-//
-// NOTE: If an instruction is invalid, only then can it be tagged with any
-// kind of interrupt. Thus, the MMU must make instruction valid as 1 before
-// attaching an abort interrupt to it even though the instruction generated
-// might be invalid. Such an instruction is not actually executed.
-//
-
-//
-// This stage simply forwards data from the
-// I-cache downwards.
-//
-always @ (posedge i_clk)
-begin
- if ( i_reset )
- begin
- // Unit has no valid output.
- o_valid <= 1'd0;
-
- // Do not signal any abort.
- o_instr_abort <= 1'd0;
-
- // Wake unit up.
- sleep_ff <= 1'd0;
- end
- else if ( i_clear_from_writeback ) clear_unit;
- else if ( i_data_stall) begin end // Save state.
- else if ( i_clear_from_alu ) clear_unit;
- else if ( i_stall_from_shifter ) begin end // Save state.
- else if ( i_stall_from_issue ) begin end // Save state.
- else if ( i_stall_from_decode) begin end // Save state.
- else if ( i_clear_from_decode ) clear_unit;
- else if ( i_code_stall ) begin end
-
- // If unit is sleeping.
- else if ( sleep_ff )
- begin
- // Nothing valid to be sent.
- o_valid <= 1'd0;
-
- // No aborts.
- o_instr_abort <= 1'd0;
-
- // Keep sleeping.
- sleep_ff <= 1'd1;
- end
-
- // Data from memory is valid. This could also be used to signal
- // an instruction access abort.
- else if ( i_valid )
- begin
- // Instruction aborts occur with i_valid as 1. See NOTE.
- o_valid <= 1'd1;
- o_instr_abort <= i_instr_abort;
-
- // Put unit to sleep on an abort.
- sleep_ff <= i_instr_abort;
-
- //
- // Pump PC + 8 or 4 down the pipeline. The number depends on
- // ARM/Compressed mode.
- //
- o_pc_plus_8_ff <= i_cpsr_ff_t ? ( i_pc_ff + 32'd4 ) :
- ( i_pc_ff + 32'd8 );
-
- // PC is pumped down the pipeline.
- o_pc_ff <= i_pc_ff;
-
- // Instruction. If 16-bit aligned address, move data from
- // cache by 16-bit to focus on the instruction.
- o_instruction <= i_pc_ff[1] ? i_instruction >> 16 : i_instruction;
- end
- else
- begin
- // Invalidate the output.
- o_valid <= 1'd0;
- end
-end
-
-always @ (negedge i_clk)
-begin
- if ( i_pc_ff[0] != 1'd0 )
- begin
- $display($time, " - %m :: Error: PC LSB isn't zero. This is not legal...");
- $finish;
- end
-end
-
-// ----------------------------------------------------------------------------
-
-//
-// Branch State RAM.
-// Holds the 2-bit state for a range of branches. Whenever a branch is
-// either detected as correctly taken or incorrectly taken, this RAM is
-// updated. Each entry in the RAM corresponds to a virtual memory address
-// whether or not it be a legit branch or not.
-//
-zap_ram_simple
-#(.DEPTH(BP_ENTRIES), .WIDTH(2)) u_br_ram
-(
- .i_clk(i_clk),
-
- // The reason that a no-stall condition is included is that
- // if the pipeline stalls, this memory should be trigerred multiply
- // times.
- .i_wr_en( !i_data_stall &&
- !i_stall_from_issue &&
- !i_stall_from_decode &&
- !i_stall_from_shifter &&
- (i_clear_from_alu || i_confirm_from_alu)),
-
- // Lower bits of the PC index into the branch RAM for read and
- // write addresses.
- .i_wr_addr(i_pc_from_alu[$clog2(BP_ENTRIES):1]),
- .i_rd_addr(i_pc_ff[$clog2(BP_ENTRIES):1]),
-
- // Write the new state.
- .i_wr_data(compute(i_taken, i_clear_from_alu)),
-
- // Read when there is no stall.
- .i_rd_en(
- !i_code_stall &&
- !i_data_stall &&
- !i_stall_from_issue &&
- !i_stall_from_decode &&
- !i_stall_from_shifter
- ),
-
- // Send the read data over to o_taken_ff which is a 2-bit value.
- .o_rd_data(taken_v)
-);
-
-// ----------------------------------------------------------------------------
-
-//
-// Branch Memory writes.
-// Implements a 4-state predictor.
-//
-function [1:0] compute ( input [1:0] i_taken, input i_clear_from_alu );
-begin
- // Branch was predicted incorrectly.
- if ( i_clear_from_alu )
- begin
- case ( i_taken )
- SNT: compute = WNT;
- WNT: compute = WT;
- WT: compute = WNT;
- ST: compute = WT;
- endcase
- end
- else // Confirm from alu that branch was correctly predicted.
- begin
- case ( i_taken )
- SNT: compute = SNT;
- WNT: compute = SNT;
- WT: compute = ST;
- ST: compute = ST;
- endcase
- end
-end
-endfunction
-
-// ----------------------------------------------------------------------------
-
-//
-// This task clears out the unit and refreshes it for a new
-// service session. Will wake the unit up and clear the outputs.
-//
-task clear_unit;
-begin
- // No valid output.
- o_valid <= 1'd0;
-
- // No aborts since we are clearing out the unit.
- o_instr_abort <= 1'd0;
-
- // Wake up the unit.
- sleep_ff <= 1'd0;
-end
-endtask
-
-assign _unused_ok_ = i_pc_from_alu[0] &&
- i_pc_from_alu[31:$clog2(BP_ENTRIES) + 1];
-
-// ----------------------------------------------------------------------------
-
-zap_decompile u_zap_decompile (
- .i_instruction ({4'd0, o_instruction}),
- .i_dav (o_valid),
- .o_decompile ()
-);
-
-
-endmodule // zap_fetch_main.v
-`default_nettype wire
-
-// ----------------------------------------------------------------------------
-// EOF
-// ----------------------------------------------------------------------------
Index: zap/trunk/src/rtl/cpu/zap_predecode_mem_fsm.v
===================================================================
--- zap/trunk/src/rtl/cpu/zap_predecode_mem_fsm.v (revision 57)
+++ zap/trunk/src/rtl/cpu/zap_predecode_mem_fsm.v (nonexistent)
@@ -1,709 +0,0 @@
-// -----------------------------------------------------------------------------
-// -- --
-// -- (C) 2016-2018 Revanth Kamaraj. --
-// -- --
-// -- --------------------------------------------------------------------------
-// -- --
-// -- This program is free software; you can redistribute it and/or --
-// -- modify it under the terms of the GNU General Public License --
-// -- as published by the Free Software Foundation; either version 2 --
-// -- of the License, or (at your option) any later version. --
-// -- --
-// -- This program 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 General Public License for more details. --
-// -- --
-// -- You should have received a copy of the GNU General Public License --
-// -- along with this program; if not, write to the Free Software --
-// -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA --
-// -- 02110-1301, USA. --
-// -- --
-// -----------------------------------------------------------------------------
-// -- --
-// -- This module sequences ARM LDM/STM CISC instructions into simpler RISC --
-// -- instructions. Basically LDM -> LDRs and STM -> STRs. Supports a base --
-// -- restored abort model. Start instruction carries interrupt information --
-// -- so this cannot block interrupts if there is a sequence of these. --
-// -- --
-// -- Also handles SWAP instruction. --
-// -- --
-// -- SWAP steps: --
-// -- - Read data from [Rn] into DUMMY. - LDR DUMMY0, [Rn] --
-// -- - Write data in Rm to [Rn] - STR Rm, [Rn] --
-// -- - Copy data from DUMMY to Rd. - MOV Rd, DUMMY0 --
-// -- --
-// -----------------------------------------------------------------------------
-
-`default_nettype none
-
-module zap_predecode_mem_fsm
-(
- // Clock and reset.
- input wire i_clk, // ZAP clock.
- input wire i_reset, // ZAP reset.
-
- // Instruction information from the fetch.
- input wire [34:0] i_instruction,
- input wire i_instruction_valid,
-
- // Interrupt information from the fetch.
- input wire i_irq,
- input wire i_fiq,
-
- // CPSR
- input wire i_cpsr_t,
-
- // Pipeline control signals.
- 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_issue_stall,
-
- // Instruction output.
- output reg [35:0] o_instruction,
- output reg o_instruction_valid,
-
- // We generate a stall.
- output reg o_stall_from_decode,
-
- // Possibly masked interrupts.
- output reg o_irq,
- output reg o_fiq
-);
-
-///////////////////////////////////////////////////////////////////////////////
-
-`include "zap_defines.vh"
-`include "zap_localparams.vh"
-`include "zap_functions.vh"
-
-///////////////////////////////////////////////////////////////////////////////
-
-// Instruction breakup
-wire [3:0] cc ;
-wire [2:0] id ;
-wire pre_index ;
-wire up ;
-wire s_bit ;
-wire writeback ;
-wire load ;
-wire [3:0] base ;
-wire [15:0] reglist ;
-
-// Instruction breakup assignment.
-assign {cc, id, pre_index, up, s_bit, writeback, load, base, reglist} = i_instruction;
-
-wire store = !load;
-wire link = i_instruction[24];
-wire [11:0] branch_offset = i_instruction[11:0];
-
-wire [11:0] oc_offset; // Ones counter offset.
-reg [3:0] state_ff, state_nxt; // State.
-reg [15:0] reglist_ff, reglist_nxt; // Register list.
-reg [31:0] const_ff, const_nxt; // For BLX - const reg.
-
-///////////////////////////////////////////////////////////////////////////////
-
-// States.
-localparam IDLE = 0;
-localparam MEMOP = 1;
-localparam WRITE_PC = 2;
-localparam SWAP1 = 3;
-localparam SWAP2 = 4;
-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;
-
-///////////////////////////////////////////////////////////////////////////////
-
-assign oc_offset = ones_counter(i_instruction);
-
-///////////////////////////////////////////////////////////////////////////////
-
-// Next state and output logic.
-always @*
-begin
- const_nxt = const_ff;
-
- // Block interrupts by default.
- o_irq = 0;
- o_fiq = 0;
-
- // Avoid latch inference.
- state_nxt = state_ff;
- o_instruction = i_instruction;
- o_instruction_valid = i_instruction_valid;
- reglist_nxt = reglist_ff;
- 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 if needed.
- 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
- // 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
- // 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 )
- begin
- // Backup base register.
- // MOV DUMMY0, Base
- if ( up )
- begin
- o_instruction = {cc, 2'b00, 1'b0, MOV,
- 1'b0, 4'd0, 4'd0, 8'd0, base};
-
- {o_instruction[`DP_RD_EXTEND],
- o_instruction[`DP_RD]}
- = ARCH_DUMMY_REG0;
- end
- else
- begin
- // SUB DUMMY0, BASE, OFFSET
- o_instruction = {cc, 2'b00, 1'b1, SUB,
- 1'd0, base, 4'd0, oc_offset};
-
- {o_instruction[`DP_RD_EXTEND],
- o_instruction[`DP_RD]} =
- ARCH_DUMMY_REG0;
- end
-
- o_instruction_valid = 1'd1;
- reglist_nxt = reglist;
-
- state_nxt = MEMOP;
- o_stall_from_decode = 1'd1;
-
- // Since this instruction does not change the
- // actual state of the CPU, an interrupt may be
- // taken on this.
- o_irq = i_irq;
- o_fiq = i_fiq;
- 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
- begin
- // Swap
-
- o_irq = i_irq;
- o_fiq = i_fiq;
-
- // dummy = *(rn) - LDR ARCH_DUMMY_REG0, [rn, #0]
- state_nxt = SWAP1;
-
- o_instruction = {cc, 3'b010, 1'd1, 1'd0,
- i_instruction[22], 1'd0, 1'd1,
- i_instruction[19:16], 4'b0000, 12'd0};
- // The 0000 is replaced with dummy0 below.
-
- {o_instruction[`SRCDEST_EXTEND],
- o_instruction[`SRCDEST]} = ARCH_DUMMY_REG0;
-
- o_instruction_valid = 1'd1;
- o_stall_from_decode = 1'd1;
- end
- else if ( i_instruction[27:23] == 5'd1 &&
- i_instruction[7:4] == 4'b1001 && i_instruction_valid )
- begin
- // LMULT
- state_nxt = LMULT_BUSY;
- o_stall_from_decode = 1'd1;
- o_irq = i_irq;
- o_fiq = i_fiq;
- o_instruction = i_instruction;
- o_instruction_valid = i_instruction_valid;
- end
- else if ( i_instruction[27:25] == 3'b101 &&
- i_instruction[24] && i_instruction_valid ) // BL.
- begin
- // Move to new state. In that state, we will
- // generate a plain branch.
- state_nxt = BL_S1;
-
- // PC will stall preventing the fetch from
- // presenting new data.
- o_stall_from_decode = 1'd1;
-
- if ( i_cpsr_t == 1'd0 ) // ARM
- begin
- // PC is 8 bytes ahead.
- // Craft a SUB LR, PC, 4.
- o_instruction = {i_instruction[31:28],
- 28'h24FE004};
- end
- else
- begin
- // PC is 4 bytes ahead...
- // Craft a SUB LR, PC, 1 so that return
- // goes to the next 16bit instruction
- // and making LSB of LR = 1.
- o_instruction = {i_instruction[31:28],
- 28'h24FE001};
- end
-
- // Sell it as a valid instruction
- o_instruction_valid = 1;
-
- // Silence interrupts if a BL instruction is
- // seen.
- o_irq = 0;
- o_fiq = 0;
- end
- else
- begin
- // Be transparent.
- state_nxt = state_ff;
- o_stall_from_decode = 1'd0;
- o_instruction = i_instruction;
- o_instruction_valid = i_instruction_valid;
- reglist_nxt = 16'd0;
- o_irq = i_irq;
- o_fiq = i_fiq;
- end
- end
-
- BL_S1:
- begin
- // Launch out the original instruction clearing the
- // link bit. This is like MOV PC,
- o_instruction = i_instruction & ~(1 << 24);
- o_instruction_valid = i_instruction_valid;
-
- // Move to IDLE state.
- state_nxt = IDLE;
-
- // Free the fetch from your clutches.
- o_stall_from_decode = 1'd0;
-
- // Continue to silence interrupts.
- o_irq = 0;
- o_fiq = 0;
- end
-
- LMULT_BUSY:
- begin
- o_irq = 0;
- o_fiq = 0;
- o_instruction = {1'd1, i_instruction};
- o_instruction_valid = i_instruction_valid;
- o_stall_from_decode = 1'd0;
- state_nxt = IDLE;
- end
-
- SWAP1, SWAP3:
- begin
- // STR Rm, [Rn, #0]
-
- o_irq = 0;
- o_fiq = 0;
-
- // If in SWAP3, end the sequence so get next operation
- // in when we move to IDLE.
- o_stall_from_decode = state_ff == SWAP3 ? 1'd0 : 1'd1;
-
- o_instruction_valid = 1;
- o_instruction = {cc, 3'b010, 1'd1, 1'd0,
- i_instruction[22], 1'd0, 1'd0,
- i_instruction[19:16],
- i_instruction[3:0], 12'd0}; // BUG FIX
-
- state_nxt = state_ff == SWAP3 ? IDLE : SWAP2;
- end
-
- SWAP2:
- begin:SWP2BLK
- // MOV Rd, DUMMY0
-
- reg [3:0] rd;
-
- rd = i_instruction[15:12];
-
- // Keep waiting. Next we initiate a read to ensure
- // write buffer gets flushed.
- o_stall_from_decode = 1'd1;
- o_instruction_valid = 1'd1;
-
- o_irq = 0;
- o_fiq = 0;
-
- o_instruction = {cc, 2'b00, 1'd0, MOV, 1'd0, 4'b0000,
- rd, 12'd0}; // ALU src doesn't matter.
-
- {o_instruction[`DP_RB_EXTEND], o_instruction[`DP_RB]}
- = ARCH_DUMMY_REG0;
-
- state_nxt = SWAP3;
- end
-
- MEMOP:
- begin: mem_op_blk_1
-
- // Memory operations happen here.
-
- reg [3:0] pri_enc_out;
-
- pri_enc_out = pri_enc(reglist_ff);
- reglist_nxt = reglist_ff & ~(16'd1 << pri_enc_out);
-
- o_irq = 0;
- o_fiq = 0;
-
- // The map function generates a base restore
- // instruction if reglist = 0.
- o_instruction = map ( i_instruction, pri_enc_out,
- reglist_ff );
- o_instruction_valid = 1'd1;
-
- if ( reglist_ff == 0 )
- begin
- if ( i_instruction[ARCH_PC] && load )
- begin
- o_stall_from_decode = 1'd1;
- state_nxt = WRITE_PC;
- end
- else
- begin
- o_stall_from_decode = 1'd0;
- state_nxt = IDLE;
- end
- end
- else
- begin
- state_nxt = MEMOP;
- o_stall_from_decode = 1'd1;
- end
- end
-
- // If needed, we finally write to the program counter as
- // either a MOV PC, LR or MOVS PC, LR.
- WRITE_PC:
- begin
- // MOV(S) PC, ARCH_DUMMY_REG1
- state_nxt = IDLE;
- o_stall_from_decode = 1'd0;
-
- o_instruction =
- { cc, 2'b00, 1'd0, MOV, s_bit, 4'd0, ARCH_PC,
- 8'd0, 4'd0 };
-
- {o_instruction[`DP_RB_EXTEND], o_instruction[`DP_RB]}
- = ARCH_DUMMY_REG1;
-
- o_instruction_valid = 1'd1;
- o_irq = 0;
- o_fiq = 0;
- end
- endcase
-end
-
-///////////////////////////////////////////////////////////////////////////////
-
-function [33:0] map ( input [31:0] instr, input [3:0] enc, input [15:0] list );
-// These override the globals within the function scope.
-reg [3:0] cc;
-reg [2:0] id;
-reg pre_index;
-reg up;
-reg s_bit;
-reg writeback;
-reg load;
-reg [3:0] base;
-reg [15:0] reglist;
-reg store;
-reg restore;
-begin
- restore = 0;
-
- {cc, id, pre_index, up, s_bit, writeback, load, base, reglist} = instr;
-
- store = !load;
- map = instr;
- map = map & ~(1<<22); // No byte access.
- map = map & ~(1<<25); // Constant Offset (of 4).
- map[23] = 1'd1; // Hard wired to increment.
-
- map[11:0] = 12'd4; // Offset
- map[27:26] = 2'b01; // Memory instruction.
-
- map[`SRCDEST] = enc;
- {map[`BASE_EXTEND],map[`BASE]} = ARCH_DUMMY_REG0;//Use as base register.
-
- // If not up, then DA -> IB and DB -> IA.
- if ( !up ) // DA or DB.
- begin
- map[24] = !map[24]; // Post <---> Pre switch.
- end
-
- // Since the indexing has swapped (possibly), we must rethink map[21].
- if ( map[24] == 0 ) // Post index.
- begin
- map[21] = 1'd0; // Writeback is implicit.
- end
- else // Pre-index - Must specify writeback.
- begin
- map[21] = 1'd1;
- end
-
- if ( list == 0 ) // Catch 0 list here itself...
- begin
- // Restore base. MOV Rbase, DUMMY0
- if ( writeback )
- begin
- restore = 1;
-
- if ( up ) // Original instruction asked increment.
- begin
- map =
- { cc, 2'b0, 1'b0, MOV, 1'b0, 4'd0,
- base, 8'd0, 4'd0 };
-
- {map[`DP_RB_EXTEND],map[`DP_RB]} =
- ARCH_DUMMY_REG0;
- end
- else
- begin // Restore.
- // SUB BASE, BASE, #OFFSET
- map = {cc, 2'b00, 1'b1, SUB,
- 1'd0, base, base, oc_offset};
- end
- end
- else
- begin
- map = 32'd0; // Wasted cycle.
- end
- end
- else if ( (store && s_bit) || (load && s_bit && !list[15]) )
- // STR with S bit or LDR with S bit and no PC - force user bank access.
- begin
- case ( map[`SRCDEST] ) // Force user bank.
- 8: {map[`SRCDEST_EXTEND],map[`SRCDEST]} = ARCH_USR2_R8;
- 9: {map[`SRCDEST_EXTEND],map[`SRCDEST]} = ARCH_USR2_R9;
- 10:{map[`SRCDEST_EXTEND],map[`SRCDEST]} = ARCH_USR2_R10;
- 11:{map[`SRCDEST_EXTEND],map[`SRCDEST]} = ARCH_USR2_R11;
- 12:{map[`SRCDEST_EXTEND],map[`SRCDEST]} = ARCH_USR2_R12;
- 13:{map[`SRCDEST_EXTEND],map[`SRCDEST]} = ARCH_USR2_R13;
- 14:{map[`SRCDEST_EXTEND],map[`SRCDEST]} = ARCH_USR2_R14;
- endcase
- end
- else if ( load && enc == 15 )
- //
- // Load with PC in register list. Load to dummy register.
- // Will never use user bank.
- //
- begin
- //
- // If S = 1, perform an atomic return.
- // If S = 0, just write to PC i.e., a jump.
- //
- // For now, load to ARCH_DUMMY_REG1.
- //
- {map[`SRCDEST_EXTEND],map[`SRCDEST]} = ARCH_DUMMY_REG1;
- end
-end
-endfunction
-
-///////////////////////////////////////////////////////////////////////////////
-
-always @ (posedge i_clk)
-begin
- if ( i_reset ) clear;
- else if ( i_clear_from_writeback) clear;
- else if ( i_data_stall ) begin end // Stall CPU.
- else if ( i_clear_from_alu ) clear;
- else if ( i_stall_from_shifter ) begin end
- else if ( i_issue_stall ) begin end
- else
- begin
- state_ff <= state_nxt;
- reglist_ff <= reglist_nxt;
- const_ff <= const_nxt;
- end
-end
-
-///////////////////////////////////////////////////////////////////////////////
-
-// Unit is reset.
-task clear;
-begin
- state_ff <= IDLE;
- reglist_ff <= 16'd0;
- const_ff <= 32'd0;
-end
-endtask
-
-// Counts the number of ones and multiplies that by 4 to get final
-// address offset.
-function [11:0] ones_counter (
- input [15:0] i_word // Register list.
-);
-begin: blk1
- integer i;
- reg [11:0] offset;
-
- offset = 0;
-
- // Counter number of ones.
- for(i=0;i<16;i=i+1)
- offset = offset + i_word[i];
-
- // Since LDM and STM occur only on 4 byte regions, compute the
- // net offset.
- offset = (offset << 2); // Multiply by 4.
-
- ones_counter = offset;
-end
-endfunction
-
-//
-// Function to model a 16-bit priority encoder.
-//
-
-// Priority encoder.
-function [3:0] pri_enc ( input [15:0] in );
-begin: priEncFn
- casez ( in )
- 16'b????_????_????_???1: pri_enc = 4'd0;
- 16'b????_????_????_??10: pri_enc = 4'd1;
- 16'b????_????_????_?100: pri_enc = 4'd2;
- 16'b????_????_????_1000: pri_enc = 4'd3;
- 16'b????_????_???1_0000: pri_enc = 4'd4;
- 16'b????_????_??10_0000: pri_enc = 4'd5;
- 16'b????_????_?100_0000: pri_enc = 4'd6;
- 16'b????_????_1000_0000: pri_enc = 4'd7;
- 16'b????_???1_0000_0000: pri_enc = 4'd8;
- 16'b????_??10_0000_0000: pri_enc = 4'd9;
- 16'b????_?100_0000_0000: pri_enc = 4'hA;
- 16'b????_1000_0000_0000: pri_enc = 4'hB;
- 16'b???1_0000_0000_0000: pri_enc = 4'hC;
- 16'b??10_0000_0000_0000: pri_enc = 4'hD;
- 16'b?100_0000_0000_0000: pri_enc = 4'hE;
- 16'b1000_0000_0000_0000: pri_enc = 4'hF;
- default: pri_enc = 4'h0;
- endcase
-end
-endfunction
-
-endmodule // zap_predecode_mem_fsm.v
-`default_nettype wire
Index: zap/trunk/src/rtl/cpu/zap_predecode_coproc.v
===================================================================
--- zap/trunk/src/rtl/cpu/zap_predecode_coproc.v (revision 57)
+++ zap/trunk/src/rtl/cpu/zap_predecode_coproc.v (nonexistent)
@@ -1,284 +0,0 @@
-// ---------------------------------------------------------------------------
-// -- --
-// -- (C) 2016-2018 Revanth Kamaraj. --
-// -- --
-// -- ------------------------------------------------------------------------
-// -- --
-// -- This program is free software; you can redistribute it and/or --
-// -- modify it under the terms of the GNU General Public License --
-// -- as published by the Free Software Foundation; either version 2 --
-// -- of the License, or (at your option) any later version. --
-// -- --
-// -- This program 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 General Public License for more details. --
-// -- --
-// -- You should have received a copy of the GNU General Public License --
-// -- along with this program; if not, write to the Free Software --
-// -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA --
-// -- 02110-1301, USA. --
-// -- --
-// ---------------------------------------------------------------------------
-// Implements a simple coprocessor interface for the ZAP core. The interface
-// is low bandwidth and thus is suited only for coprocessor that do not
-// perform large data exchanges. Note that the translate function must be
-// present in the coprocessor to account for CPU modes.
-// ----------------------------------------------------------------------------
-
-`default_nettype none
-
-module zap_predecode_coproc #(
- parameter PHY_REGS = 46
-)
-(
- input wire i_clk,
- input wire i_reset,
-
- // Instruction and valid qualifier.
- input wire [34:0] i_instruction,
- input wire i_valid,
-
- // CPSR Thumb Bit.
- input wire i_cpsr_ff_t,
- input wire [4:0] i_cpsr_ff_mode,
-
- // Interrupts.
- input wire i_irq,
- input wire i_fiq,
-
- // Clear and stall signals.
- input wire i_clear_from_writeback, // | High Priority
- input wire i_data_stall, // |
- input wire i_clear_from_alu, // |
- input wire i_stall_from_shifter, // |
- input wire i_stall_from_issue, // V Low Priority
-
- // Pipeline Valid. Must become 0 when every stage of the pipeline
- // is invalid.
- input wire i_pipeline_dav,
-
- // Coprocessor done signal.
- input wire i_copro_done,
-
- // Interrupts output.
- output reg o_irq,
- output reg o_fiq,
-
- // Instruction and valid qualifier.
- output reg [34:0] o_instruction,
- output reg o_valid,
-
- // We can generate stall if coprocessor is slow. We also have
- // some minimal latency.
- output reg o_stall_from_decode,
-
- // Are we really asking for the coprocessor ?
- output reg o_copro_dav_ff,
-
- // The entire instruction is passed to the coprocessor.
- output reg [31:0] o_copro_word_ff
-);
-
-///////////////////////////////////////////////////////////////////////////////
-
-`include "zap_defines.vh"
-`include "zap_localparams.vh"
-`include "zap_functions.vh"
-
-///////////////////////////////////////////////////////////////////////////////
-
-localparam IDLE = 0;
-localparam BUSY = 1;
-
-///////////////////////////////////////////////////////////////////////////////
-
-// State register.
-reg state_ff, state_nxt;
-
-// Output registers.
-reg cp_dav_ff, cp_dav_nxt;
-reg [31:0] cp_word_ff, cp_word_nxt;
-
-///////////////////////////////////////////////////////////////////////////////
-
-// Connect output registers to output.
-always @*
-begin
- o_copro_word_ff = cp_word_ff;
- o_copro_dav_ff = cp_dav_ff;
-end
-
-///////////////////////////////////////////////////////////////////////////////
-
-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;
-reg eclass;
-
-// Next state logic.
-always @*
-begin
- // Default values.
- cp_dav_nxt = cp_dav_ff;
- cp_word_nxt = cp_word_ff;
- o_stall_from_decode = 1'd0;
- o_instruction = i_instruction;
- o_valid = i_valid;
- state_nxt = state_ff;
- o_irq = i_irq;
- o_fiq = i_fiq;
-
- eclass = 0;
-
- case ( state_ff )
- IDLE:
- // Activate only if no thumb, not in USER mode and CP15 access is requested.
- casez ( (!i_cpsr_ff_t && (i_instruction[34:32] == 3'd0) && i_valid) ? i_instruction[31:0] : 35'd0 )
- MRC, MCR, LDC, STC, CDP, MRC2, MCR2, LDC2, STC2:
- begin
- if ( i_instruction[11:8] == 4'b1111 && i_cpsr_ff_mode != USR ) // CP15 and root access -- perfectly fine.
- begin
- // Send ANDNV R0, R0, R0 instruction.
- o_instruction = {4'b1111, 28'd0};
- o_valid = 1'd0;
- o_irq = 1'd0;
- o_fiq = 1'd0;
-
- // As long as there is an instruction to process...
- if ( i_pipeline_dav )
- begin
- // Do not impose any output. However, continue
- // to stall all before this unit in the
- // pipeline.
- o_valid = 1'd0;
- o_stall_from_decode = 1'd1;
- cp_dav_nxt = 1'd0;
- cp_word_nxt = 32'd0;
- end
- else
- begin
- // Prepare to move to BUSY. Continue holding
- // stall. Send out 0s.
- o_valid = 1'd0;
- o_stall_from_decode = 1'd1;
- cp_word_nxt = i_instruction;
- cp_dav_nxt = 1'd1;
- state_nxt = BUSY;
- end
- end
- else // Warning...
- begin
-
- if ( i_instruction[11:8] != 4'b1111 )
- eclass = 1;
- else
- eclass = 2;
-
-
- // Remain transparent since this is not a coprocessor
- // instruction.
- o_valid = i_valid;
- o_instruction = i_instruction;
- o_irq = i_irq;
- o_fiq = i_fiq;
- cp_dav_nxt = 0;
- o_stall_from_decode = 0;
- cp_word_nxt = {32{1'dx}}; // Don't care.
- end
- end
- default:
- begin
- // Remain transparent since this is not a coprocessor
- // instruction.
- o_valid = i_valid;
- o_instruction = i_instruction;
- o_irq = i_irq;
- o_fiq = i_fiq;
- cp_dav_nxt = 0;
- o_stall_from_decode = 0;
- cp_word_nxt = {32{1'dx}}; // Don't care.
- end
- endcase
-
- BUSY:
- begin
- // Provide coprocessor word and valid to the coprocessor.
- cp_word_nxt = cp_word_ff;
- cp_dav_nxt = cp_dav_ff;
-
- // Continue holding stall.
- o_stall_from_decode = 1'd1;
-
- // Send out nothing.
- o_valid = 1'd0;
- o_instruction = 32'd0;
-
- // Block interrupts.
- o_irq = 1'd0;
- o_fiq = 1'd0;
-
- // If we get a response, we can move back to IDLE. Release
- // the stall so that processor can continue.
- if ( i_copro_done )
- begin
- cp_dav_nxt = 1'd0;
- cp_word_nxt = 32'd0;
- state_nxt = IDLE;
- o_stall_from_decode = 1'd0;
- end
- end
- endcase
-end
-
-always @ (posedge i_clk)
-begin
- if ( i_reset )
- begin
- clear;
- end
- else if ( i_clear_from_writeback )
- begin
- clear;
- end
- else if ( i_data_stall )
- begin
- // Preserve values.
- end
- else if ( i_clear_from_alu )
- begin
- clear;
- end
- else if ( i_stall_from_shifter )
- begin
- // Preserve values.
- end
- else if ( i_stall_from_issue )
- begin
- // Preserve values.
- end
- else
- begin
- state_ff <= state_nxt;
- cp_word_ff <= cp_word_nxt;
- cp_dav_ff <= cp_dav_nxt;
- end
-end
-
-// Clear out the unit.
-task clear;
-begin
- state_ff <= IDLE;
- cp_dav_ff <= 1'd0;
-end
-endtask
-
-endmodule
-
-`default_nettype wire
-
-// ----------------------------------------------------------------------------
-// EOF
-// ----------------------------------------------------------------------------
Index: zap/trunk/makefile
===================================================================
--- zap/trunk/makefile (revision 57)
+++ zap/trunk/makefile (nonexistent)
@@ -1,9 +0,0 @@
-.PHONY: clean
-.PHONY: error
-
-error:
- @echo "To run a TC, go to src/ts and do a make there. Only target supported here is 'clean'."
-
-clean:
- @echo "Removing object folder."
- rm -rf obj/
Index: zap/trunk/README.md
===================================================================
--- zap/trunk/README.md (revision 57)
+++ zap/trunk/README.md (revision 58)
@@ -1,7 +1,7 @@
## NOTE: This project was designed by me as a part of a student design contest. It is no longer actively supported.
+## This project's files are hosted on GitHub.
+## The ZAP ARM Processor (ARMv5T Compatible, FPGA Synthesizable Soft Processor) @ https://github.com/krevanth/ZAP.git
-## The ZAP ARM Processor (ARMv5T Compatible, FPGA Synthesizable Soft Processor)
-
### Author : Revanth Kamaraj (revanth91kamaraj@gmail.com)
### Introduction
@@ -18,12 +18,10 @@
#### Repos
-This project is hosted on Github and Opencores.
+This project is hosted on Github.
GIT: https://github.com/krevanth/ZAP
-SVN: https://opencores.org/projects/zap
-
#### Features
##### ZAP Processor (zap_top.v)
@@ -100,10 +98,18 @@
| output | | o_wb_cyc_nxt | IGNORE THIS PORT. LEAVE OPEN. |
| output | [31:0] | o_wb_adr_nxt | IGNORE THIS PORT. LEAVE OPEN. |
-### Directory Structure
+### Installation and Directory Structure (GIT)
+To get the files of the ZAP processor, please execute:
+```bash
+git pull https://github.com/krevanth/ZAP.git
+```
+This should provide the following file structure:
+
+
+
├── LICENSE
├── makefile
├── README.md