URL
https://opencores.org/ocsvn/zap/zap/trunk
Subversion Repositories zap
Compare Revisions
- This comparison shows the changes necessary to convert path
/zap
- from Rev 57 to Rev 58
- ↔ Reverse comparison
Rev 57 → Rev 58
/trunk/src/testbench/zap_tb.v
File deleted
/trunk/src/testbench/ram.v
File deleted
/trunk/src/testbench/timer.v
File deleted
/trunk/src/testbench/vic.v
File deleted
/trunk/src/testbench/uart_tx_dumper.v
File deleted
/trunk/src/testbench/uart_rx_logger.v
File deleted
/trunk/src/testbench/chip_top.v
File deleted
/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
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: 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: trunk/src/testbench/External_IP/uart16550/doc/UART_spec.pdf
===================================================================
--- trunk/src/testbench/External_IP/uart16550/doc/UART_spec.pdf (revision 57)
+++ trunk/src/testbench/External_IP/uart16550/doc/UART_spec.pdf (nonexistent)
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: trunk/src/testbench/External_IP/uart16550/rtl/raminfr.v
===================================================================
--- trunk/src/testbench/External_IP/uart16550/rtl/raminfr.v (revision 57)
+++ trunk/src/testbench/External_IP/uart16550/rtl/raminfr.v (nonexistent)
@@ -1,112 +0,0 @@
-//////////////////////////////////////////////////////////////////////
-//// ////
-//// raminfr.v ////
-//// ////
-//// ////
-//// This file is part of the "UART 16550 compatible" project ////
-//// http://www.opencores.org/cores/uart16550/ ////
-//// ////
-//// Documentation related to this project: ////
-//// - http://www.opencores.org/cores/uart16550/ ////
-//// ////
-//// Projects compatibility: ////
-//// - WISHBONE ////
-//// RS232 Protocol ////
-//// 16550D uart (mostly supported) ////
-//// ////
-//// Overview (main Features): ////
-//// Inferrable Distributed RAM for FIFOs ////
-//// ////
-//// Known problems (limits): ////
-//// None . ////
-//// ////
-//// To Do: ////
-//// Nothing so far. ////
-//// ////
-//// Author(s): ////
-//// - gorban@opencores.org ////
-//// - Jacob Gorban ////
-//// ////
-//// Created: 2002/07/22 ////
-//// Last Updated: 2002/07/22 ////
-//// (See log for the revision history) ////
-//// ////
-//// Modified for use in the ZAP project by Revanth Kamaraj ////
-//// ////
-//////////////////////////////////////////////////////////////////////
-//// ////
-//// Copyright (C) 2000, 2001 Authors ////
-//// ////
-//// This source file may be used and distributed without ////
-//// restriction provided that this copyright statement is not ////
-//// removed from the file and that any derivative work contains ////
-//// the original copyright notice and the associated disclaimer. ////
-//// ////
-//// This source file is free software; you can redistribute it ////
-//// and/or modify it under the terms of the GNU Lesser General ////
-//// Public License as published by the Free Software Foundation; ////
-//// either version 2.1 of the License, or (at your option) any ////
-//// later version. ////
-//// ////
-//// This source 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 Lesser General Public License for more ////
-//// details. ////
-//// ////
-//// You should have received a copy of the GNU Lesser General ////
-//// Public License along with this source; if not, download it ////
-//// from http://www.opencores.org/lgpl.shtml ////
-//// ////
-//////////////////////////////////////////////////////////////////////
-//
-// CVS Revision History
-//
-// $Log: not supported by cvs2svn $
-// Revision 1.1 2002/07/22 23:02:23 gorban
-// Bug Fixes:
-// * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
-// Problem reported by Kenny.Tung.
-// * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
-//
-// Improvements:
-// * Made FIFO's as general inferrable memory where possible.
-// So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
-// This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
-//
-// * Added optional baudrate output (baud_o).
-// This is identical to BAUDOUT* signal on 16550 chip.
-// It outputs 16xbit_clock_rate - the divided clock.
-// It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use.
-//
-
-//Following is the Verilog code for a dual-port RAM with asynchronous read.
-module raminfr
- (clk, we, a, dpra, di, dpo);
-
-parameter addr_width = 4;
-parameter data_width = 8;
-parameter depth = 16;
-
-input clk;
-input we;
-input [addr_width-1:0] a;
-input [addr_width-1:0] dpra;
-input [data_width-1:0] di;
-//output [data_width-1:0] spo;
-output [data_width-1:0] dpo;
-reg [data_width-1:0] ram [depth-1:0];
-
-wire [data_width-1:0] dpo;
-wire [data_width-1:0] di;
-wire [addr_width-1:0] a;
-wire [addr_width-1:0] dpra;
-
- always @(posedge clk) begin
- if (we)
- ram[a] <= di;
- end
-// assign spo = ram[a];
- assign dpo = ram[dpra];
-endmodule
-
Index: trunk/src/testbench/External_IP/uart16550/rtl/uart_receiver.v
===================================================================
--- trunk/src/testbench/External_IP/uart16550/rtl/uart_receiver.v (revision 57)
+++ trunk/src/testbench/External_IP/uart16550/rtl/uart_receiver.v (nonexistent)
@@ -1,481 +0,0 @@
-//////////////////////////////////////////////////////////////////////
-//// ////
-//// uart_receiver.v ////
-//// ////
-//// ////
-//// This file is part of the "UART 16550 compatible" project ////
-//// http://www.opencores.org/cores/uart16550/ ////
-//// ////
-//// Documentation related to this project: ////
-//// - http://www.opencores.org/cores/uart16550/ ////
-//// ////
-//// Projects compatibility: ////
-//// - WISHBONE ////
-//// RS232 Protocol ////
-//// 16550D uart (mostly supported) ////
-//// ////
-//// Overview (main Features): ////
-//// UART core receiver logic ////
-//// ////
-//// Known problems (limits): ////
-//// None known ////
-//// ////
-//// To Do: ////
-//// Thourough testing. ////
-//// ////
-//// Author(s): ////
-//// - gorban@opencores.org ////
-//// - Jacob Gorban ////
-//// - Igor Mohor (igorm@opencores.org) ////
-//// ////
-//// Created: 2001/05/12 ////
-//// Last Updated: 2001/05/17 ////
-//// (See log for the revision history) ////
-//// ////
-//// Modified for use in the ZAP project by Revanth Kamaraj ////
-//// ////
-//////////////////////////////////////////////////////////////////////
-//// ////
-//// Copyright (C) 2000, 2001 Authors ////
-//// ////
-//// This source file may be used and distributed without ////
-//// restriction provided that this copyright statement is not ////
-//// removed from the file and that any derivative work contains ////
-//// the original copyright notice and the associated disclaimer. ////
-//// ////
-//// This source file is free software; you can redistribute it ////
-//// and/or modify it under the terms of the GNU Lesser General ////
-//// Public License as published by the Free Software Foundation; ////
-//// either version 2.1 of the License, or (at your option) any ////
-//// later version. ////
-//// ////
-//// This source 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 Lesser General Public License for more ////
-//// details. ////
-//// ////
-//// You should have received a copy of the GNU Lesser General ////
-//// Public License along with this source; if not, download it ////
-//// from http://www.opencores.org/lgpl.shtml ////
-//// ////
-//////////////////////////////////////////////////////////////////////
-//
-// CVS Revision History
-//
-// $Log: not supported by cvs2svn $
-// Revision 1.29 2002/07/29 21:16:18 gorban
-// The uart_defines.v file is included again in sources.
-//
-// Revision 1.28 2002/07/22 23:02:23 gorban
-// Bug Fixes:
-// * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
-// Problem reported by Kenny.Tung.
-// * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
-//
-// Improvements:
-// * Made FIFO's as general inferrable memory where possible.
-// So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
-// This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
-//
-// * Added optional baudrate output (baud_o).
-// This is identical to BAUDOUT* signal on 16550 chip.
-// It outputs 16xbit_clock_rate - the divided clock.
-// It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use.
-//
-// Revision 1.27 2001/12/30 20:39:13 mohor
-// More than one character was stored in case of break. End of the break
-// was not detected correctly.
-//
-// Revision 1.26 2001/12/20 13:28:27 mohor
-// Missing declaration of rf_push_q fixed.
-//
-// Revision 1.25 2001/12/20 13:25:46 mohor
-// rx push changed to be only one cycle wide.
-//
-// Revision 1.24 2001/12/19 08:03:34 mohor
-// Warnings cleared.
-//
-// Revision 1.23 2001/12/19 07:33:54 mohor
-// Synplicity was having troubles with the comment.
-//
-// Revision 1.22 2001/12/17 14:46:48 mohor
-// overrun signal was moved to separate block because many sequential lsr
-// reads were preventing data from being written to rx fifo.
-// underrun signal was not used and was removed from the project.
-//
-// Revision 1.21 2001/12/13 10:31:16 mohor
-// timeout irq must be set regardless of the rda irq (rda irq does not reset the
-// timeout counter).
-//
-// Revision 1.20 2001/12/10 19:52:05 gorban
-// Igor fixed break condition bugs
-//
-// Revision 1.19 2001/12/06 14:51:04 gorban
-// Bug in LSR[0] is fixed.
-// All WISHBONE signals are now sampled, so another wait-state is introduced on all transfers.
-//
-// Revision 1.18 2001/12/03 21:44:29 gorban
-// Updated specification documentation.
-// Added full 32-bit data bus interface, now as default.
-// Address is 5-bit wide in 32-bit data bus mode.
-// Added wb_sel_i input to the core. It's used in the 32-bit mode.
-// Added debug interface with two 32-bit read-only registers in 32-bit mode.
-// Bits 5 and 6 of LSR are now only cleared on TX FIFO write.
-// My small test bench is modified to work with 32-bit mode.
-//
-// Revision 1.17 2001/11/28 19:36:39 gorban
-// Fixed: timeout and break didn't pay attention to current data format when counting time
-//
-// Revision 1.16 2001/11/27 22:17:09 gorban
-// Fixed bug that prevented synthesis in uart_receiver.v
-//
-// Revision 1.15 2001/11/26 21:38:54 gorban
-// Lots of fixes:
-// Break condition wasn't handled correctly at all.
-// LSR bits could lose their values.
-// LSR value after reset was wrong.
-// Timing of THRE interrupt signal corrected.
-// LSR bit 0 timing corrected.
-//
-// Revision 1.14 2001/11/10 12:43:21 gorban
-// Logic Synthesis bugs fixed. Some other minor changes
-//
-// Revision 1.13 2001/11/08 14:54:23 mohor
-// Comments in Slovene language deleted, few small fixes for better work of
-// old tools. IRQs need to be fix.
-//
-// Revision 1.12 2001/11/07 17:51:52 gorban
-// Heavily rewritten interrupt and LSR subsystems.
-// Many bugs hopefully squashed.
-//
-// Revision 1.11 2001/10/31 15:19:22 gorban
-// Fixes to break and timeout conditions
-//
-// Revision 1.10 2001/10/20 09:58:40 gorban
-// Small synopsis fixes
-//
-// Revision 1.9 2001/08/24 21:01:12 mohor
-// Things connected to parity changed.
-// Clock devider changed.
-//
-// Revision 1.8 2001/08/23 16:05:05 mohor
-// Stop bit bug fixed.
-// Parity bug fixed.
-// WISHBONE read cycle bug fixed,
-// OE indicator (Overrun Error) bug fixed.
-// PE indicator (Parity Error) bug fixed.
-// Register read bug fixed.
-//
-// Revision 1.6 2001/06/23 11:21:48 gorban
-// DL made 16-bit long. Fixed transmission/reception bugs.
-//
-// Revision 1.5 2001/06/02 14:28:14 gorban
-// Fixed receiver and transmitter. Major bug fixed.
-//
-// Revision 1.4 2001/05/31 20:08:01 gorban
-// FIFO changes and other corrections.
-//
-// Revision 1.3 2001/05/27 17:37:49 gorban
-// Fixed many bugs. Updated spec. Changed FIFO files structure. See CHANGES.txt file.
-//
-// Revision 1.2 2001/05/21 19:12:02 gorban
-// Corrected some Linter messages.
-//
-// Revision 1.1 2001/05/17 18:34:18 gorban
-// First 'stable' release. Should be sythesizable now. Also added new header.
-//
-// Revision 1.0 2001-05-17 21:27:11+02 jacob
-// Initial revision
-//
-//
-//// Modified for use in the ZAP project by Revanth Kamaraj ////
-
-
-`include "uart_defines.v"
-
-module uart_receiver (clk, wb_rst_i, lcr, rf_pop, srx_pad_i, enable,
- counter_t, rf_count, rf_data_out, rf_error_bit, rf_overrun, rx_reset, lsr_mask, rstate, rf_push_pulse);
-
-input clk;
-input wb_rst_i;
-input [7:0] lcr;
-input rf_pop;
-input srx_pad_i;
-input enable;
-input rx_reset;
-input lsr_mask;
-
-output [9:0] counter_t;
-output [`UART_FIFO_COUNTER_W-1:0] rf_count;
-output [`UART_FIFO_REC_WIDTH-1:0] rf_data_out;
-output rf_overrun;
-output rf_error_bit;
-output [3:0] rstate;
-output rf_push_pulse;
-
-reg [3:0] rstate;
-reg [3:0] rcounter16;
-reg [2:0] rbit_counter;
-reg [7:0] rshift; // receiver shift register
-reg rparity; // received parity
-reg rparity_error;
-reg rframing_error; // framing error flag
-reg rbit_in;
-reg rparity_xor;
-reg [7:0] counter_b; // counts the 0 (low) signals
-reg rf_push_q;
-
-// RX FIFO signals
-reg [`UART_FIFO_REC_WIDTH-1:0] rf_data_in;
-wire [`UART_FIFO_REC_WIDTH-1:0] rf_data_out;
-wire rf_push_pulse;
-reg rf_push;
-wire rf_pop;
-wire rf_overrun;
-wire [`UART_FIFO_COUNTER_W-1:0] rf_count;
-wire rf_error_bit; // an error (parity or framing) is inside the fifo
-wire break_error = (counter_b == 0);
-
-// RX FIFO instance
-uart_rfifo #(`UART_FIFO_REC_WIDTH) fifo_rx(
- .clk( clk ),
- .wb_rst_i( wb_rst_i ),
- .data_in( rf_data_in ),
- .data_out( rf_data_out ),
- .push( rf_push_pulse ),
- .pop( rf_pop ),
- .overrun( rf_overrun ),
- .count( rf_count ),
- .error_bit( rf_error_bit ),
- .fifo_reset( rx_reset ),
- .reset_status(lsr_mask)
-);
-
-wire rcounter16_eq_7 = (rcounter16 == 4'd7);
-wire rcounter16_eq_0 = (rcounter16 == 4'd0);
-wire rcounter16_eq_1 = (rcounter16 == 4'd1);
-
-wire [3:0] rcounter16_minus_1 = rcounter16 - 1'b1;
-
-parameter sr_idle = 4'd0;
-parameter sr_rec_start = 4'd1;
-parameter sr_rec_bit = 4'd2;
-parameter sr_rec_parity = 4'd3;
-parameter sr_rec_stop = 4'd4;
-parameter sr_check_parity = 4'd5;
-parameter sr_rec_prepare = 4'd6;
-parameter sr_end_bit = 4'd7;
-parameter sr_ca_lc_parity = 4'd8;
-parameter sr_wait1 = 4'd9;
-parameter sr_push = 4'd10;
-
-
-always @(posedge clk or posedge wb_rst_i)
-begin
- if (wb_rst_i)
- begin
- rstate <= sr_idle;
- rbit_in <= 1'b0;
- rcounter16 <= 0;
- rbit_counter <= 0;
- rparity_xor <= 1'b0;
- rframing_error <= 1'b0;
- rparity_error <= 1'b0;
- rparity <= 1'b0;
- rshift <= 0;
- rf_push <= 1'b0;
- rf_data_in <= 0;
- end
- else
- if (enable)
- begin
- case (rstate)
- sr_idle : begin
- rf_push <= 1'b0;
- rf_data_in <= 0;
- rcounter16 <= 4'b1110;
- if (srx_pad_i==1'b0 & ~break_error) // detected a pulse (start bit?)
- begin
- rstate <= sr_rec_start;
- end
- end
- sr_rec_start : begin
- rf_push <= 1'b0;
- if (rcounter16_eq_7) // check the pulse
- if (srx_pad_i==1'b1) // no start bit
- rstate <= sr_idle;
- else // start bit detected
- rstate <= sr_rec_prepare;
- rcounter16 <= rcounter16_minus_1;
- end
- sr_rec_prepare:begin
- case (lcr[/*`UART_LC_BITS*/1:0]) // number of bits in a word
- 2'b00 : rbit_counter <= 3'b100;
- 2'b01 : rbit_counter <= 3'b101;
- 2'b10 : rbit_counter <= 3'b110;
- 2'b11 : rbit_counter <= 3'b111;
- endcase
- if (rcounter16_eq_0)
- begin
- rstate <= sr_rec_bit;
- rcounter16 <= 4'b1110;
- rshift <= 0;
- end
- else
- rstate <= sr_rec_prepare;
- rcounter16 <= rcounter16_minus_1;
- end
- sr_rec_bit : begin
- if (rcounter16_eq_0)
- rstate <= sr_end_bit;
- if (rcounter16_eq_7) // read the bit
- case (lcr[/*`UART_LC_BITS*/1:0]) // number of bits in a word
- 2'b00 : rshift[4:0] <= {srx_pad_i, rshift[4:1]};
- 2'b01 : rshift[5:0] <= {srx_pad_i, rshift[5:1]};
- 2'b10 : rshift[6:0] <= {srx_pad_i, rshift[6:1]};
- 2'b11 : rshift[7:0] <= {srx_pad_i, rshift[7:1]};
- endcase
- rcounter16 <= rcounter16_minus_1;
- end
- sr_end_bit : begin
- if (rbit_counter==3'b0) // no more bits in word
- if (lcr[`UART_LC_PE]) // choose state based on parity
- rstate <= sr_rec_parity;
- else
- begin
- rstate <= sr_rec_stop;
- rparity_error <= 1'b0; // no parity - no error :)
- end
- else // else we have more bits to read
- begin
- rstate <= sr_rec_bit;
- rbit_counter <= rbit_counter - 1'b1;
- end
- rcounter16 <= 4'b1110;
- end
- sr_rec_parity: begin
- if (rcounter16_eq_7) // read the parity
- begin
- rparity <= srx_pad_i;
- rstate <= sr_ca_lc_parity;
- end
- rcounter16 <= rcounter16_minus_1;
- end
- sr_ca_lc_parity : begin // rcounter equals 6
- rcounter16 <= rcounter16_minus_1;
- rparity_xor <= ^{rshift,rparity}; // calculate parity on all incoming data
- rstate <= sr_check_parity;
- end
- sr_check_parity: begin // rcounter equals 5
- case ({lcr[`UART_LC_EP],lcr[`UART_LC_SP]})
- 2'b00: rparity_error <= rparity_xor == 0; // no error if parity 1
- 2'b01: rparity_error <= ~rparity; // parity should sticked to 1
- 2'b10: rparity_error <= rparity_xor == 1; // error if parity is odd
- 2'b11: rparity_error <= rparity; // parity should be sticked to 0
- endcase
- rcounter16 <= rcounter16_minus_1;
- rstate <= sr_wait1;
- end
- sr_wait1 : if (rcounter16_eq_0)
- begin
- rstate <= sr_rec_stop;
- rcounter16 <= 4'b1110;
- end
- else
- rcounter16 <= rcounter16_minus_1;
- sr_rec_stop : begin
- if (rcounter16_eq_7) // read the parity
- begin
- rframing_error <= !srx_pad_i; // no framing error if input is 1 (stop bit)
- rstate <= sr_push;
- end
- rcounter16 <= rcounter16_minus_1;
- end
- sr_push : begin
-///////////////////////////////////////
-// $display($time, ": received: %b", rf_data_in);
- if(srx_pad_i | break_error)
- begin
- if(break_error)
- rf_data_in <= {8'b0, 3'b100}; // break input (empty character) to receiver FIFO
- else
- rf_data_in <= {rshift, 1'b0, rparity_error, rframing_error};
- rf_push <= 1'b1;
- rstate <= sr_idle;
- end
- else if(~rframing_error) // There's always a framing before break_error -> wait for break or srx_pad_i
- begin
- rf_data_in <= {rshift, 1'b0, rparity_error, rframing_error};
- rf_push <= 1'b1;
- rcounter16 <= 4'b1110;
- rstate <= sr_rec_start;
- end
-
- end
- default : rstate <= sr_idle;
- endcase
- end // if (enable)
-end // always of receiver
-
-always @ (posedge clk or posedge wb_rst_i)
-begin
- if(wb_rst_i)
- rf_push_q <= 0;
- else
- rf_push_q <= rf_push;
-end
-
-assign rf_push_pulse = rf_push & ~rf_push_q;
-
-
-//
-// Break condition detection.
-// Works in conjuction with the receiver state machine
-
-reg [9:0] toc_value; // value to be set to timeout counter
-
-always @(lcr)
- case (lcr[3:0])
- 4'b0000 : toc_value = 447; // 7 bits
- 4'b0100 : toc_value = 479; // 7.5 bits
- 4'b0001, 4'b1000 : toc_value = 511; // 8 bits
- 4'b1100 : toc_value = 543; // 8.5 bits
- 4'b0010, 4'b0101, 4'b1001 : toc_value = 575; // 9 bits
- 4'b0011, 4'b0110, 4'b1010, 4'b1101 : toc_value = 639; // 10 bits
- 4'b0111, 4'b1011, 4'b1110 : toc_value = 703; // 11 bits
- 4'b1111 : toc_value = 767; // 12 bits
- endcase // case(lcr[3:0])
-
-wire [7:0] brc_value; // value to be set to break counter
-assign brc_value = toc_value[9:2]; // the same as timeout but 1 insead of 4 character times
-
-always @(posedge clk or posedge wb_rst_i)
-begin
- if (wb_rst_i)
- counter_b <= 8'd159;
- else
- if (srx_pad_i)
- counter_b <= brc_value; // character time length - 1
- else
- if(enable & counter_b != 8'b0) // only work on enable times break not reached.
- counter_b <= counter_b - 1; // decrement break counter
-end // always of break condition detection
-
-///
-/// Timeout condition detection
-reg [9:0] counter_t; // counts the timeout condition clocks
-
-always @(posedge clk or posedge wb_rst_i)
-begin
- if (wb_rst_i)
- counter_t <= 10'd639; // 10 bits for the default 8N1
- else
- if(rf_push_pulse || rf_pop || rf_count == 0) // counter is reset when RX FIFO is empty, accessed or above trigger level
- counter_t <= toc_value;
- else
- if (enable && counter_t != 10'b0) // we don't want to underflow
- counter_t <= counter_t - 1;
-end
-
-endmodule
Index: trunk/src/testbench/External_IP/uart16550/rtl/uart_debug_if.v
===================================================================
--- trunk/src/testbench/External_IP/uart16550/rtl/uart_debug_if.v (revision 57)
+++ trunk/src/testbench/External_IP/uart16550/rtl/uart_debug_if.v (nonexistent)
@@ -1,124 +0,0 @@
-//////////////////////////////////////////////////////////////////////
-//// ////
-//// uart_debug_if.v ////
-//// ////
-//// ////
-//// This file is part of the "UART 16550 compatible" project ////
-//// http://www.opencores.org/cores/uart16550/ ////
-//// ////
-//// Documentation related to this project: ////
-//// - http://www.opencores.org/cores/uart16550/ ////
-//// ////
-//// Projects compatibility: ////
-//// - WISHBONE ////
-//// RS232 Protocol ////
-//// 16550D uart (mostly supported) ////
-//// ////
-//// Overview (main Features): ////
-//// UART core debug interface. ////
-//// ////
-//// Author(s): ////
-//// - gorban@opencores.org ////
-//// - Jacob Gorban ////
-//// ////
-//// Created: 2001/12/02 ////
-//// (See log for the revision history) ////
-//// Modified for use in the ZAP project by Revanth Kamaraj ////
-//// ////
-//////////////////////////////////////////////////////////////////////
-//// ////
-//// Copyright (C) 2000, 2001 Authors ////
-//// ////
-//// This source file may be used and distributed without ////
-//// restriction provided that this copyright statement is not ////
-//// removed from the file and that any derivative work contains ////
-//// the original copyright notice and the associated disclaimer. ////
-//// ////
-//// This source file is free software; you can redistribute it ////
-//// and/or modify it under the terms of the GNU Lesser General ////
-//// Public License as published by the Free Software Foundation; ////
-//// either version 2.1 of the License, or (at your option) any ////
-//// later version. ////
-//// ////
-//// This source 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 Lesser General Public License for more ////
-//// details. ////
-//// ////
-//// You should have received a copy of the GNU Lesser General ////
-//// Public License along with this source; if not, download it ////
-//// from http://www.opencores.org/lgpl.shtml ////
-//// ////
-//////////////////////////////////////////////////////////////////////
-//
-// CVS Revision History
-//
-// $Log: not supported by cvs2svn $
-// Revision 1.4 2002/07/22 23:02:23 gorban
-// Bug Fixes:
-// * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
-// Problem reported by Kenny.Tung.
-// * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
-//
-// Improvements:
-// * Made FIFO's as general inferrable memory where possible.
-// So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
-// This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
-//
-// * Added optional baudrate output (baud_o).
-// This is identical to BAUDOUT* signal on 16550 chip.
-// It outputs 16xbit_clock_rate - the divided clock.
-// It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use.
-//
-// Revision 1.3 2001/12/19 08:40:03 mohor
-// Warnings fixed (unused signals removed).
-//
-// Revision 1.2 2001/12/12 22:17:30 gorban
-// some synthesis bugs fixed
-//
-// Revision 1.1 2001/12/04 21:14:16 gorban
-// committed the debug interface file
-//
-
-
-`include "uart_defines.v"
-
-module uart_debug_if (/*AUTOARG*/
-// Outputs
-wb_dat32_o,
-// Inputs
-wb_adr_i, ier, iir, fcr, mcr, lcr, msr,
-lsr, rf_count, tf_count, tstate, rstate
-) ;
-
-input [`UART_ADDR_WIDTH-1:0] wb_adr_i;
-output [31:0] wb_dat32_o;
-input [3:0] ier;
-input [3:0] iir;
-input [1:0] fcr; /// bits 7 and 6 of fcr. Other bits are ignored
-input [4:0] mcr;
-input [7:0] lcr;
-input [7:0] msr;
-input [7:0] lsr;
-input [`UART_FIFO_COUNTER_W-1:0] rf_count;
-input [`UART_FIFO_COUNTER_W-1:0] tf_count;
-input [2:0] tstate;
-input [3:0] rstate;
-
-
-wire [`UART_ADDR_WIDTH-1:0] wb_adr_i;
-reg [31:0] wb_dat32_o;
-
-always @(/*AUTOSENSE*/fcr or ier or iir or lcr or lsr or mcr or msr
- or rf_count or rstate or tf_count or tstate or wb_adr_i)
- case (wb_adr_i)
- // 8 + 8 + 4 + 4 + 8
- 5'b01000: wb_dat32_o = {msr,lcr,iir,ier,lsr};
- // 5 + 2 + 5 + 4 + 5 + 3
- 5'b01100: wb_dat32_o = {8'b0, fcr,mcr, rf_count, rstate, tf_count, tstate};
- default: wb_dat32_o = 0;
- endcase // case(wb_adr_i)
-
-endmodule // uart_debug_if
-
Index: trunk/src/testbench/External_IP/uart16550/rtl/uart_rfifo.v
===================================================================
--- trunk/src/testbench/External_IP/uart16550/rtl/uart_rfifo.v (revision 57)
+++ trunk/src/testbench/External_IP/uart16550/rtl/uart_rfifo.v (nonexistent)
@@ -1,318 +0,0 @@
-//////////////////////////////////////////////////////////////////////
-//// ////
-//// uart_rfifo.v (Modified from uart_fifo.v) ////
-//// ////
-//// ////
-//// This file is part of the "UART 16550 compatible" project ////
-//// http://www.opencores.org/cores/uart16550/ ////
-//// ////
-//// Documentation related to this project: ////
-//// - http://www.opencores.org/cores/uart16550/ ////
-//// ////
-//// Projects compatibility: ////
-//// - WISHBONE ////
-//// RS232 Protocol ////
-//// 16550D uart (mostly supported) ////
-//// ////
-//// Overview (main Features): ////
-//// UART core receiver FIFO ////
-//// ////
-//// To Do: ////
-//// Nothing. ////
-//// ////
-//// Author(s): ////
-//// - gorban@opencores.org ////
-//// - Jacob Gorban ////
-//// - Igor Mohor (igorm@opencores.org) ////
-//// ////
-//// Created: 2001/05/12 ////
-//// Last Updated: 2002/07/22 ////
-//// (See log for the revision history) ////
-//// ////
-//// Modified for use in the ZAP project by Revanth Kamaraj ////
-//// ////
-//////////////////////////////////////////////////////////////////////
-//// ////
-//// Copyright (C) 2000, 2001 Authors ////
-//// ////
-//// This source file may be used and distributed without ////
-//// restriction provided that this copyright statement is not ////
-//// removed from the file and that any derivative work contains ////
-//// the original copyright notice and the associated disclaimer. ////
-//// ////
-//// This source file is free software; you can redistribute it ////
-//// and/or modify it under the terms of the GNU Lesser General ////
-//// Public License as published by the Free Software Foundation; ////
-//// either version 2.1 of the License, or (at your option) any ////
-//// later version. ////
-//// ////
-//// This source 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 Lesser General Public License for more ////
-//// details. ////
-//// ////
-//// You should have received a copy of the GNU Lesser General ////
-//// Public License along with this source; if not, download it ////
-//// from http://www.opencores.org/lgpl.shtml ////
-//// ////
-//////////////////////////////////////////////////////////////////////
-//
-// CVS Revision History
-//
-// $Log: not supported by cvs2svn $
-// Revision 1.3 2003/06/11 16:37:47 gorban
-// This fixes errors in some cases when data is being read and put to the FIFO at the same time. Patch is submitted by Scott Furman. Update is very recommended.
-//
-// Revision 1.2 2002/07/29 21:16:18 gorban
-// The uart_defines.v file is included again in sources.
-//
-// Revision 1.1 2002/07/22 23:02:23 gorban
-// Bug Fixes:
-// * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
-// Problem reported by Kenny.Tung.
-// * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
-//
-// Improvements:
-// * Made FIFO's as general inferrable memory where possible.
-// So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
-// This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
-//
-// * Added optional baudrate output (baud_o).
-// This is identical to BAUDOUT* signal on 16550 chip.
-// It outputs 16xbit_clock_rate - the divided clock.
-// It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use.
-//
-// Revision 1.16 2001/12/20 13:25:46 mohor
-// rx push changed to be only one cycle wide.
-//
-// Revision 1.15 2001/12/18 09:01:07 mohor
-// Bug that was entered in the last update fixed (rx state machine).
-//
-// Revision 1.14 2001/12/17 14:46:48 mohor
-// overrun signal was moved to separate block because many sequential lsr
-// reads were preventing data from being written to rx fifo.
-// underrun signal was not used and was removed from the project.
-//
-// Revision 1.13 2001/11/26 21:38:54 gorban
-// Lots of fixes:
-// Break condition wasn't handled correctly at all.
-// LSR bits could lose their values.
-// LSR value after reset was wrong.
-// Timing of THRE interrupt signal corrected.
-// LSR bit 0 timing corrected.
-//
-// Revision 1.12 2001/11/08 14:54:23 mohor
-// Comments in Slovene language deleted, few small fixes for better work of
-// old tools. IRQs need to be fix.
-//
-// Revision 1.11 2001/11/07 17:51:52 gorban
-// Heavily rewritten interrupt and LSR subsystems.
-// Many bugs hopefully squashed.
-//
-// Revision 1.10 2001/10/20 09:58:40 gorban
-// Small synopsis fixes
-//
-// Revision 1.9 2001/08/24 21:01:12 mohor
-// Things connected to parity changed.
-// Clock devider changed.
-//
-// Revision 1.8 2001/08/24 08:48:10 mohor
-// FIFO was not cleared after the data was read bug fixed.
-//
-// Revision 1.7 2001/08/23 16:05:05 mohor
-// Stop bit bug fixed.
-// Parity bug fixed.
-// WISHBONE read cycle bug fixed,
-// OE indicator (Overrun Error) bug fixed.
-// PE indicator (Parity Error) bug fixed.
-// Register read bug fixed.
-//
-// Revision 1.3 2001/05/31 20:08:01 gorban
-// FIFO changes and other corrections.
-//
-// Revision 1.3 2001/05/27 17:37:48 gorban
-// Fixed many bugs. Updated spec. Changed FIFO files structure. See CHANGES.txt file.
-//
-// Revision 1.2 2001/05/17 18:34:18 gorban
-// First 'stable' release. Should be sythesizable now. Also added new header.
-//
-// Revision 1.0 2001-05-17 21:27:12+02 jacob
-// Initial revision
-//
-//
-
-
-`include "uart_defines.v"
-
-module uart_rfifo (clk,
- wb_rst_i, data_in, data_out,
-// Control signals
- push, // push strobe, active high
- pop, // pop strobe, active high
-// status signals
- overrun,
- count,
- error_bit,
- fifo_reset,
- reset_status
- );
-
-
-// FIFO parameters
-parameter fifo_width = `UART_FIFO_WIDTH;
-parameter fifo_depth = `UART_FIFO_DEPTH;
-parameter fifo_pointer_w = `UART_FIFO_POINTER_W;
-parameter fifo_counter_w = `UART_FIFO_COUNTER_W;
-
-input clk;
-input wb_rst_i;
-input push;
-input pop;
-input [fifo_width-1:0] data_in;
-input fifo_reset;
-input reset_status;
-
-output [fifo_width-1:0] data_out;
-output overrun;
-output [fifo_counter_w-1:0] count;
-output error_bit;
-
-wire [fifo_width-1:0] data_out;
-wire [7:0] data8_out;
-// flags FIFO
-reg [2:0] fifo[fifo_depth-1:0];
-
-// FIFO pointers
-reg [fifo_pointer_w-1:0] top;
-reg [fifo_pointer_w-1:0] bottom;
-
-reg [fifo_counter_w-1:0] count;
-reg overrun;
-
-wire [fifo_pointer_w-1:0] top_plus_1 = top + 1'b1;
-
-raminfr #(fifo_pointer_w,8,fifo_depth) rfifo
- (.clk(clk),
- .we(push),
- .a(top),
- .dpra(bottom),
- .di(data_in[fifo_width-1:fifo_width-8]),
- .dpo(data8_out)
- );
-
-always @(posedge clk or posedge wb_rst_i) // synchronous FIFO
-begin
- if (wb_rst_i)
- begin
- top <= 0;
- bottom <= 1'b0;
- count <= 0;
- fifo[0] <= 0;
- fifo[1] <= 0;
- fifo[2] <= 0;
- fifo[3] <= 0;
- fifo[4] <= 0;
- fifo[5] <= 0;
- fifo[6] <= 0;
- fifo[7] <= 0;
- fifo[8] <= 0;
- fifo[9] <= 0;
- fifo[10] <= 0;
- fifo[11] <= 0;
- fifo[12] <= 0;
- fifo[13] <= 0;
- fifo[14] <= 0;
- fifo[15] <= 0;
- end
- else
- if (fifo_reset) begin
- top <= 0;
- bottom <= 1'b0;
- count <= 0;
- fifo[0] <= 0;
- fifo[1] <= 0;
- fifo[2] <= 0;
- fifo[3] <= 0;
- fifo[4] <= 0;
- fifo[5] <= 0;
- fifo[6] <= 0;
- fifo[7] <= 0;
- fifo[8] <= 0;
- fifo[9] <= 0;
- fifo[10] <= 0;
- fifo[11] <= 0;
- fifo[12] <= 0;
- fifo[13] <= 0;
- fifo[14] <= 0;
- fifo[15] <= 0;
- end
- else
- begin
- case ({push, pop})
- 2'b10 : if (count0)
- begin
- fifo[bottom] <= 0;
- bottom <= bottom + 1'b1;
- count <= count - 1'b1;
- end
- 2'b11 : begin
- bottom <= bottom + 1'b1;
- top <= top_plus_1;
- fifo[top] <= data_in[2:0];
- end
- default: ;
- endcase
- end
-end // always
-
-always @(posedge clk or posedge wb_rst_i) // synchronous FIFO
-begin
- if (wb_rst_i)
- overrun <= 1'b0;
- else
- if(fifo_reset | reset_status)
- overrun <= 1'b0;
- else
- if(push & ~pop & (count==fifo_depth))
- overrun <= 1'b1;
-end // always
-
-
-// please note though that data_out is only valid one clock after pop signal
-assign data_out = {data8_out,fifo[bottom]};
-
-// Additional logic for detection of error conditions (parity and framing) inside the FIFO
-// for the Line Status Register bit 7
-
-wire [2:0] word0 = fifo[0];
-wire [2:0] word1 = fifo[1];
-wire [2:0] word2 = fifo[2];
-wire [2:0] word3 = fifo[3];
-wire [2:0] word4 = fifo[4];
-wire [2:0] word5 = fifo[5];
-wire [2:0] word6 = fifo[6];
-wire [2:0] word7 = fifo[7];
-
-wire [2:0] word8 = fifo[8];
-wire [2:0] word9 = fifo[9];
-wire [2:0] word10 = fifo[10];
-wire [2:0] word11 = fifo[11];
-wire [2:0] word12 = fifo[12];
-wire [2:0] word13 = fifo[13];
-wire [2:0] word14 = fifo[14];
-wire [2:0] word15 = fifo[15];
-
-// a 1 is returned if any of the error bits in the fifo is 1
-assign error_bit = |(word0[2:0] | word1[2:0] | word2[2:0] | word3[2:0] |
- word4[2:0] | word5[2:0] | word6[2:0] | word7[2:0] |
- word8[2:0] | word9[2:0] | word10[2:0] | word11[2:0] |
- word12[2:0] | word13[2:0] | word14[2:0] | word15[2:0] );
-
-endmodule
Index: trunk/src/testbench/External_IP/uart16550/rtl/uart_tfifo.v
===================================================================
--- trunk/src/testbench/External_IP/uart16550/rtl/uart_tfifo.v (revision 57)
+++ trunk/src/testbench/External_IP/uart16550/rtl/uart_tfifo.v (nonexistent)
@@ -1,241 +0,0 @@
-//////////////////////////////////////////////////////////////////////
-//// ////
-//// uart_tfifo.v ////
-//// ////
-//// ////
-//// This file is part of the "UART 16550 compatible" project ////
-//// http://www.opencores.org/cores/uart16550/ ////
-//// ////
-//// Documentation related to this project: ////
-//// - http://www.opencores.org/cores/uart16550/ ////
-//// ////
-//// Projects compatibility: ////
-//// - WISHBONE ////
-//// RS232 Protocol ////
-//// 16550D uart (mostly supported) ////
-//// ////
-//// Overview (main Features): ////
-//// UART core transmitter FIFO ////
-//// ////
-//// To Do: ////
-//// Nothing. ////
-//// ////
-//// Author(s): ////
-//// - gorban@opencores.org ////
-//// - Jacob Gorban ////
-//// - Igor Mohor (igorm@opencores.org) ////
-//// ////
-//// Created: 2001/05/12 ////
-//// Last Updated: 2002/07/22 ////
-//// (See log for the revision history) ////
-//// Modified for use in the ZAP project by Revanth Kamaraj ////
-//// ////
-//// ////
-//////////////////////////////////////////////////////////////////////
-//// ////
-//// Copyright (C) 2000, 2001 Authors ////
-//// ////
-//// This source file may be used and distributed without ////
-//// restriction provided that this copyright statement is not ////
-//// removed from the file and that any derivative work contains ////
-//// the original copyright notice and the associated disclaimer. ////
-//// ////
-//// This source file is free software; you can redistribute it ////
-//// and/or modify it under the terms of the GNU Lesser General ////
-//// Public License as published by the Free Software Foundation; ////
-//// either version 2.1 of the License, or (at your option) any ////
-//// later version. ////
-//// ////
-//// This source 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 Lesser General Public License for more ////
-//// details. ////
-//// ////
-//// You should have received a copy of the GNU Lesser General ////
-//// Public License along with this source; if not, download it ////
-//// from http://www.opencores.org/lgpl.shtml ////
-//// ////
-//////////////////////////////////////////////////////////////////////
-//
-// CVS Revision History
-//
-// $Log: not supported by cvs2svn $
-// Revision 1.1 2002/07/22 23:02:23 gorban
-// Bug Fixes:
-// * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
-// Problem reported by Kenny.Tung.
-// * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
-//
-// Improvements:
-// * Made FIFO's as general inferrable memory where possible.
-// So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
-// This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
-//
-// * Added optional baudrate output (baud_o).
-// This is identical to BAUDOUT* signal on 16550 chip.
-// It outputs 16xbit_clock_rate - the divided clock.
-// It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use.
-//
-// Revision 1.16 2001/12/20 13:25:46 mohor
-// rx push changed to be only one cycle wide.
-//
-// Revision 1.15 2001/12/18 09:01:07 mohor
-// Bug that was entered in the last update fixed (rx state machine).
-//
-// Revision 1.14 2001/12/17 14:46:48 mohor
-// overrun signal was moved to separate block because many sequential lsr
-// reads were preventing data from being written to rx fifo.
-// underrun signal was not used and was removed from the project.
-//
-// Revision 1.13 2001/11/26 21:38:54 gorban
-// Lots of fixes:
-// Break condition wasn't handled correctly at all.
-// LSR bits could lose their values.
-// LSR value after reset was wrong.
-// Timing of THRE interrupt signal corrected.
-// LSR bit 0 timing corrected.
-//
-// Revision 1.12 2001/11/08 14:54:23 mohor
-// Comments in Slovene language deleted, few small fixes for better work of
-// old tools. IRQs need to be fix.
-//
-// Revision 1.11 2001/11/07 17:51:52 gorban
-// Heavily rewritten interrupt and LSR subsystems.
-// Many bugs hopefully squashed.
-//
-// Revision 1.10 2001/10/20 09:58:40 gorban
-// Small synopsis fixes
-//
-// Revision 1.9 2001/08/24 21:01:12 mohor
-// Things connected to parity changed.
-// Clock devider changed.
-//
-// Revision 1.8 2001/08/24 08:48:10 mohor
-// FIFO was not cleared after the data was read bug fixed.
-//
-// Revision 1.7 2001/08/23 16:05:05 mohor
-// Stop bit bug fixed.
-// Parity bug fixed.
-// WISHBONE read cycle bug fixed,
-// OE indicator (Overrun Error) bug fixed.
-// PE indicator (Parity Error) bug fixed.
-// Register read bug fixed.
-//
-// Revision 1.3 2001/05/31 20:08:01 gorban
-// FIFO changes and other corrections.
-//
-// Revision 1.3 2001/05/27 17:37:48 gorban
-// Fixed many bugs. Updated spec. Changed FIFO files structure. See CHANGES.txt file.
-//
-// Revision 1.2 2001/05/17 18:34:18 gorban
-// First 'stable' release. Should be sythesizable now. Also added new header.
-//
-// Revision 1.0 2001-05-17 21:27:12+02 jacob
-// Initial revision
-//
-//
-
-
-`include "uart_defines.v"
-
-module uart_tfifo (clk,
- wb_rst_i, data_in, data_out,
-// Control signals
- push, // push strobe, active high
- pop, // pop strobe, active high
-// status signals
- overrun,
- count,
- fifo_reset,
- reset_status
- );
-
-
-// FIFO parameters
-parameter fifo_width = `UART_FIFO_WIDTH;
-parameter fifo_depth = `UART_FIFO_DEPTH;
-parameter fifo_pointer_w = `UART_FIFO_POINTER_W;
-parameter fifo_counter_w = `UART_FIFO_COUNTER_W;
-
-input clk;
-input wb_rst_i;
-input push;
-input pop;
-input [fifo_width-1:0] data_in;
-input fifo_reset;
-input reset_status;
-
-output [fifo_width-1:0] data_out;
-output overrun;
-output [fifo_counter_w-1:0] count;
-
-wire [fifo_width-1:0] data_out;
-
-// FIFO pointers
-reg [fifo_pointer_w-1:0] top;
-reg [fifo_pointer_w-1:0] bottom;
-
-reg [fifo_counter_w-1:0] count;
-reg overrun;
-wire [fifo_pointer_w-1:0] top_plus_1 = top + 1'b1;
-
-raminfr #(fifo_pointer_w,fifo_width,fifo_depth) tfifo
- (.clk(clk),
- .we(push),
- .a(top),
- .dpra(bottom),
- .di(data_in),
- .dpo(data_out)
- );
-
-
-always @(posedge clk or posedge wb_rst_i) // synchronous FIFO
-begin
- if (wb_rst_i)
- begin
- top <= 0;
- bottom <= 1'b0;
- count <= 0;
- end
- else
- if (fifo_reset) begin
- top <= 0;
- bottom <= 1'b0;
- count <= 0;
- end
- else
- begin
- case ({push, pop})
- 2'b10 : if (count0)
- begin
- bottom <= bottom + 1'b1;
- count <= count - 1'b1;
- end
- 2'b11 : begin
- bottom <= bottom + 1'b1;
- top <= top_plus_1;
- end
- default: ;
- endcase
- end
-end // always
-
-always @(posedge clk or posedge wb_rst_i) // synchronous FIFO
-begin
- if (wb_rst_i)
- overrun <= 1'b0;
- else
- if(fifo_reset | reset_status)
- overrun <= 1'b0;
- else
- if(push & (count==fifo_depth))
- overrun <= 1'b1;
-end // always
-
-endmodule
Index: trunk/src/testbench/External_IP/uart16550/rtl/uart_wb.v
===================================================================
--- trunk/src/testbench/External_IP/uart16550/rtl/uart_wb.v (revision 57)
+++ trunk/src/testbench/External_IP/uart16550/rtl/uart_wb.v (nonexistent)
@@ -1,314 +0,0 @@
-//////////////////////////////////////////////////////////////////////
-//// ////
-//// uart_wb.v ////
-//// ////
-//// ////
-//// This file is part of the "UART 16550 compatible" project ////
-//// http://www.opencores.org/cores/uart16550/ ////
-//// ////
-//// Documentation related to this project: ////
-//// - http://www.opencores.org/cores/uart16550/ ////
-//// ////
-//// Projects compatibility: ////
-//// - WISHBONE ////
-//// RS232 Protocol ////
-//// 16550D uart (mostly supported) ////
-//// ////
-//// Overview (main Features): ////
-//// UART core WISHBONE interface. ////
-//// ////
-//// Known problems (limits): ////
-//// Inserts one wait state on all transfers. ////
-//// Note affected signals and the way they are affected. ////
-//// ////
-//// To Do: ////
-//// Nothing. ////
-//// ////
-//// Author(s): ////
-//// - gorban@opencores.org ////
-//// - Jacob Gorban ////
-//// - Igor Mohor (igorm@opencores.org) ////
-//// ////
-//// Created: 2001/05/12 ////
-//// Last Updated: 2001/05/17 ////
-//// (See log for the revision history) ////
-//// ////
-//// ////
-//////////////////////////////////////////////////////////////////////
-//// ////
-//// Copyright (C) 2000, 2001 Authors ////
-//// ////
-//// This source file may be used and distributed without ////
-//// restriction provided that this copyright statement is not ////
-//// removed from the file and that any derivative work contains ////
-//// the original copyright notice and the associated disclaimer. ////
-//// ////
-//// This source file is free software; you can redistribute it ////
-//// and/or modify it under the terms of the GNU Lesser General ////
-//// Public License as published by the Free Software Foundation; ////
-//// either version 2.1 of the License, or (at your option) any ////
-//// later version. ////
-//// ////
-//// This source 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 Lesser General Public License for more ////
-//// details. ////
-//// ////
-//// You should have received a copy of the GNU Lesser General ////
-//// Public License along with this source; if not, download it ////
-//// from http://www.opencores.org/lgpl.shtml ////
-//// ////
-//////////////////////////////////////////////////////////////////////
-//
-// CVS Revision History
-//
-// $Log: not supported by cvs2svn $
-// Revision 1.16 2002/07/29 21:16:18 gorban
-// The uart_defines.v file is included again in sources.
-//
-// Revision 1.15 2002/07/22 23:02:23 gorban
-// Bug Fixes:
-// * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
-// Problem reported by Kenny.Tung.
-// * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
-//
-// Improvements:
-// * Made FIFO's as general inferrable memory where possible.
-// So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
-// This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
-//
-// * Added optional baudrate output (baud_o).
-// This is identical to BAUDOUT* signal on 16550 chip.
-// It outputs 16xbit_clock_rate - the divided clock.
-// It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use.
-//
-// Revision 1.12 2001/12/19 08:03:34 mohor
-// Warnings cleared.
-//
-// Revision 1.11 2001/12/06 14:51:04 gorban
-// Bug in LSR[0] is fixed.
-// All WISHBONE signals are now sampled, so another wait-state is introduced on all transfers.
-//
-// Revision 1.10 2001/12/03 21:44:29 gorban
-// Updated specification documentation.
-// Added full 32-bit data bus interface, now as default.
-// Address is 5-bit wide in 32-bit data bus mode.
-// Added wb_sel_i input to the core. It's used in the 32-bit mode.
-// Added debug interface with two 32-bit read-only registers in 32-bit mode.
-// Bits 5 and 6 of LSR are now only cleared on TX FIFO write.
-// My small test bench is modified to work with 32-bit mode.
-//
-// Revision 1.9 2001/10/20 09:58:40 gorban
-// Small synopsis fixes
-//
-// Revision 1.8 2001/08/24 21:01:12 mohor
-// Things connected to parity changed.
-// Clock devider changed.
-//
-// Revision 1.7 2001/08/23 16:05:05 mohor
-// Stop bit bug fixed.
-// Parity bug fixed.
-// WISHBONE read cycle bug fixed,
-// OE indicator (Overrun Error) bug fixed.
-// PE indicator (Parity Error) bug fixed.
-// Register read bug fixed.
-//
-// Revision 1.4 2001/05/31 20:08:01 gorban
-// FIFO changes and other corrections.
-//
-// Revision 1.3 2001/05/21 19:12:01 gorban
-// Corrected some Linter messages.
-//
-// Revision 1.2 2001/05/17 18:34:18 gorban
-// First 'stable' release. Should be sythesizable now. Also added new header.
-//
-// Revision 1.0 2001-05-17 21:27:13+02 jacob
-// Initial revision
-//
-//
-
-// UART core WISHBONE interface
-//
-// Author: Jacob Gorban (jacob.gorban@flextronicssemi.com)
-// Company: Flextronics Semiconductor
-//
-
-`include "uart_defines.v"
-
-module uart_wb (clk, wb_rst_i,
- wb_we_i, wb_stb_i, wb_cyc_i, wb_ack_o, wb_adr_i,
- wb_adr_int, wb_dat_i, wb_dat_o, wb_dat8_i, wb_dat8_o, wb_dat32_o, wb_sel_i,
- we_o, re_o // Write and read enable output for the core
-);
-
-input clk;
-
-// WISHBONE interface
-input wb_rst_i;
-input wb_we_i;
-input wb_stb_i;
-input wb_cyc_i;
-input [3:0] wb_sel_i;
-input [`UART_ADDR_WIDTH-1:0] wb_adr_i; //WISHBONE address line
-
-`ifdef DATA_BUS_WIDTH_8
-input [7:0] wb_dat_i; //input WISHBONE bus
-output [7:0] wb_dat_o;
-reg [7:0] wb_dat_o;
-wire [7:0] wb_dat_i;
-reg [7:0] wb_dat_is;
-`else // for 32 data bus mode
-input [31:0] wb_dat_i; //input WISHBONE bus
-output [31:0] wb_dat_o;
-reg [31:0] wb_dat_o;
-wire [31:0] wb_dat_i;
-reg [31:0] wb_dat_is;
-`endif // !`ifdef DATA_BUS_WIDTH_8
-
-output [`UART_ADDR_WIDTH-1:0] wb_adr_int; // internal signal for address bus
-input [7:0] wb_dat8_o; // internal 8 bit output to be put into wb_dat_o
-output [7:0] wb_dat8_i;
-input [31:0] wb_dat32_o; // 32 bit data output (for debug interface)
-output wb_ack_o;
-output we_o;
-output re_o;
-
-wire we_o;
-reg wb_ack_o;
-reg [7:0] wb_dat8_i;
-wire [7:0] wb_dat8_o;
-wire [`UART_ADDR_WIDTH-1:0] wb_adr_int; // internal signal for address bus
-reg [`UART_ADDR_WIDTH-1:0] wb_adr_is;
-reg wb_we_is;
-reg wb_cyc_is;
-reg wb_stb_is;
-reg [3:0] wb_sel_is;
-wire [3:0] wb_sel_i;
-reg wre ;// timing control signal for write or read enable
-
-// wb_ack_o FSM
-reg [1:0] wbstate;
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) begin
- wb_ack_o <= 1'b0;
- wbstate <= 0;
- wre <= 1'b1;
- end else
- case (wbstate)
- 0: begin
- if (wb_stb_is & wb_cyc_is) begin
- wre <= 0;
- wbstate <= 1;
- wb_ack_o <= 1;
- end else begin
- wre <= 1;
- wb_ack_o <= 0;
- end
- end
- 1: begin
- wb_ack_o <= 0;
- wbstate <= 2;
- wre <= 0;
- end
- 2,3: begin
- wb_ack_o <= 0;
- wbstate <= 0;
- wre <= 0;
- end
- endcase
-
-assign we_o = wb_we_is & wb_stb_is & wb_cyc_is & wre ; //WE for registers
-assign re_o = ~wb_we_is & wb_stb_is & wb_cyc_is & wre ; //RE for registers
-
-// Sample input signals
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) begin
- wb_adr_is <= 0;
- wb_we_is <= 0;
- wb_cyc_is <= 0;
- wb_stb_is <= 0;
- wb_dat_is <= 0;
- wb_sel_is <= 0;
- end else begin
- wb_adr_is <= wb_adr_i;
- wb_we_is <= wb_we_i;
- wb_cyc_is <= wb_cyc_i;
- wb_stb_is <= wb_stb_i;
- wb_dat_is <= wb_dat_i;
- wb_sel_is <= wb_sel_i;
- end
-
-`ifdef DATA_BUS_WIDTH_8 // 8-bit data bus
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i)
- wb_dat_o <= 0;
- else
- wb_dat_o <= wb_dat8_o;
-
-always @(wb_dat_is)
- wb_dat8_i = wb_dat_is;
-
-assign wb_adr_int = wb_adr_is;
-
-`else // 32-bit bus
-// put output to the correct byte in 32 bits using select line
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i)
- wb_dat_o <= 0;
- else if (re_o)
- case (wb_sel_is)
- 4'b0001: wb_dat_o <= {24'b0, wb_dat8_o};
- 4'b0010: wb_dat_o <= {16'b0, wb_dat8_o, 8'b0};
- 4'b0100: wb_dat_o <= {8'b0, wb_dat8_o, 16'b0};
- 4'b1000: wb_dat_o <= {wb_dat8_o, 24'b0};
- 4'b1111: wb_dat_o <= wb_dat32_o; // debug interface output
- default: wb_dat_o <= 0;
- endcase // case(wb_sel_i)
-
-reg [1:0] wb_adr_int_lsb;
-
-always @(wb_sel_is or wb_dat_is)
-begin
- case (wb_sel_is)
- 4'b0001 : wb_dat8_i = wb_dat_is[7:0];
- 4'b0010 : wb_dat8_i = wb_dat_is[15:8];
- 4'b0100 : wb_dat8_i = wb_dat_is[23:16];
- 4'b1000 : wb_dat8_i = wb_dat_is[31:24];
- default : wb_dat8_i = wb_dat_is[7:0];
- endcase // case(wb_sel_i)
-
- `ifdef LITLE_ENDIAN
- case (wb_sel_is)
- 4'b0001 : wb_adr_int_lsb = 2'h0;
- 4'b0010 : wb_adr_int_lsb = 2'h1;
- 4'b0100 : wb_adr_int_lsb = 2'h2;
- 4'b1000 : wb_adr_int_lsb = 2'h3;
- default : wb_adr_int_lsb = 2'h0;
- endcase // case(wb_sel_i)
- `else
- case (wb_sel_is)
- 4'b0001 : wb_adr_int_lsb = 2'h3;
- 4'b0010 : wb_adr_int_lsb = 2'h2;
- 4'b0100 : wb_adr_int_lsb = 2'h1;
- 4'b1000 : wb_adr_int_lsb = 2'h0;
- default : wb_adr_int_lsb = 2'h0;
- endcase // case(wb_sel_i)
- `endif
-end
-
-assign wb_adr_int = {wb_adr_is[`UART_ADDR_WIDTH-1:2], wb_adr_int_lsb};
-
-`endif // !`ifdef DATA_BUS_WIDTH_8
-
-endmodule
-
-
-
-
-
-
-
-
-
-
Index: trunk/src/testbench/External_IP/uart16550/rtl/uart_transmitter.v
===================================================================
--- trunk/src/testbench/External_IP/uart16550/rtl/uart_transmitter.v (revision 57)
+++ trunk/src/testbench/External_IP/uart16550/rtl/uart_transmitter.v (nonexistent)
@@ -1,349 +0,0 @@
-//////////////////////////////////////////////////////////////////////
-//// ////
-//// uart_transmitter.v ////
-//// ////
-//// ////
-//// This file is part of the "UART 16550 compatible" project ////
-//// http://www.opencores.org/cores/uart16550/ ////
-//// ////
-//// Documentation related to this project: ////
-//// - http://www.opencores.org/cores/uart16550/ ////
-//// ////
-//// Projects compatibility: ////
-//// - WISHBONE ////
-//// RS232 Protocol ////
-//// 16550D uart (mostly supported) ////
-//// ////
-//// Overview (main Features): ////
-//// UART core transmitter logic ////
-//// ////
-//// Known problems (limits): ////
-//// None known ////
-//// ////
-//// To Do: ////
-//// Thourough testing. ////
-//// ////
-//// Author(s): ////
-//// - gorban@opencores.org ////
-//// - Jacob Gorban ////
-//// - Igor Mohor (igorm@opencores.org) ////
-//// ////
-//// Created: 2001/05/12 ////
-//// Last Updated: 2001/05/17 ////
-//// (See log for the revision history) ////
-//// ////
-//// Modified for use in the ZAP project by Revanth Kamaraj ////
-//// ////
-//////////////////////////////////////////////////////////////////////
-//// ////
-//// Copyright (C) 2000, 2001 Authors ////
-//// ////
-//// This source file may be used and distributed without ////
-//// restriction provided that this copyright statement is not ////
-//// removed from the file and that any derivative work contains ////
-//// the original copyright notice and the associated disclaimer. ////
-//// ////
-//// This source file is free software; you can redistribute it ////
-//// and/or modify it under the terms of the GNU Lesser General ////
-//// Public License as published by the Free Software Foundation; ////
-//// either version 2.1 of the License, or (at your option) any ////
-//// later version. ////
-//// ////
-//// This source 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 Lesser General Public License for more ////
-//// details. ////
-//// ////
-//// You should have received a copy of the GNU Lesser General ////
-//// Public License along with this source; if not, download it ////
-//// from http://www.opencores.org/lgpl.shtml ////
-//// ////
-//////////////////////////////////////////////////////////////////////
-//
-// CVS Revision History
-//
-// $Log: not supported by cvs2svn $
-// Revision 1.18 2002/07/22 23:02:23 gorban
-// Bug Fixes:
-// * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
-// Problem reported by Kenny.Tung.
-// * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
-//
-// Improvements:
-// * Made FIFO's as general inferrable memory where possible.
-// So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
-// This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
-//
-// * Added optional baudrate output (baud_o).
-// This is identical to BAUDOUT* signal on 16550 chip.
-// It outputs 16xbit_clock_rate - the divided clock.
-// It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use.
-//
-// Revision 1.16 2002/01/08 11:29:40 mohor
-// tf_pop was too wide. Now it is only 1 clk cycle width.
-//
-// Revision 1.15 2001/12/17 14:46:48 mohor
-// overrun signal was moved to separate block because many sequential lsr
-// reads were preventing data from being written to rx fifo.
-// underrun signal was not used and was removed from the project.
-//
-// Revision 1.14 2001/12/03 21:44:29 gorban
-// Updated specification documentation.
-// Added full 32-bit data bus interface, now as default.
-// Address is 5-bit wide in 32-bit data bus mode.
-// Added wb_sel_i input to the core. It's used in the 32-bit mode.
-// Added debug interface with two 32-bit read-only registers in 32-bit mode.
-// Bits 5 and 6 of LSR are now only cleared on TX FIFO write.
-// My small test bench is modified to work with 32-bit mode.
-//
-// Revision 1.13 2001/11/08 14:54:23 mohor
-// Comments in Slovene language deleted, few small fixes for better work of
-// old tools. IRQs need to be fix.
-//
-// Revision 1.12 2001/11/07 17:51:52 gorban
-// Heavily rewritten interrupt and LSR subsystems.
-// Many bugs hopefully squashed.
-//
-// Revision 1.11 2001/10/29 17:00:46 gorban
-// fixed parity sending and tx_fifo resets over- and underrun
-//
-// Revision 1.10 2001/10/20 09:58:40 gorban
-// Small synopsis fixes
-//
-// Revision 1.9 2001/08/24 21:01:12 mohor
-// Things connected to parity changed.
-// Clock devider changed.
-//
-// Revision 1.8 2001/08/23 16:05:05 mohor
-// Stop bit bug fixed.
-// Parity bug fixed.
-// WISHBONE read cycle bug fixed,
-// OE indicator (Overrun Error) bug fixed.
-// PE indicator (Parity Error) bug fixed.
-// Register read bug fixed.
-//
-// Revision 1.6 2001/06/23 11:21:48 gorban
-// DL made 16-bit long. Fixed transmission/reception bugs.
-//
-// Revision 1.5 2001/06/02 14:28:14 gorban
-// Fixed receiver and transmitter. Major bug fixed.
-//
-// Revision 1.4 2001/05/31 20:08:01 gorban
-// FIFO changes and other corrections.
-//
-// Revision 1.3 2001/05/27 17:37:49 gorban
-// Fixed many bugs. Updated spec. Changed FIFO files structure. See CHANGES.txt file.
-//
-// Revision 1.2 2001/05/21 19:12:02 gorban
-// Corrected some Linter messages.
-//
-// Revision 1.1 2001/05/17 18:34:18 gorban
-// First 'stable' release. Should be sythesizable now. Also added new header.
-//
-// Revision 1.0 2001-05-17 21:27:12+02 jacob
-// Initial revision
-//
-//
-
-
-`include "uart_defines.v"
-
-module uart_transmitter (clk, wb_rst_i, lcr, tf_push, wb_dat_i, enable, stx_pad_o, tstate, tf_count, tx_reset, lsr_mask);
-
-input clk;
-input wb_rst_i;
-input [7:0] lcr;
-input tf_push;
-input [7:0] wb_dat_i;
-input enable;
-input tx_reset;
-input lsr_mask; //reset of fifo
-output stx_pad_o;
-output [2:0] tstate;
-output [`UART_FIFO_COUNTER_W-1:0] tf_count;
-
-reg [2:0] tstate;
-reg [4:0] counter;
-reg [2:0] bit_counter; // counts the bits to be sent
-reg [6:0] shift_out; // output shift register
-reg stx_o_tmp;
-reg parity_xor; // parity of the word
-reg tf_pop;
-reg bit_out;
-
-// TX FIFO instance
-//
-// Transmitter FIFO signals
-wire [`UART_FIFO_WIDTH-1:0] tf_data_in;
-wire [`UART_FIFO_WIDTH-1:0] tf_data_out;
-wire tf_push;
-wire tf_overrun;
-wire [`UART_FIFO_COUNTER_W-1:0] tf_count;
-
-assign tf_data_in = wb_dat_i;
-
-uart_tfifo fifo_tx( // error bit signal is not used in transmitter FIFO
- .clk( clk ),
- .wb_rst_i( wb_rst_i ),
- .data_in( tf_data_in ),
- .data_out( tf_data_out ),
- .push( tf_push ),
- .pop( tf_pop ),
- .overrun( tf_overrun ),
- .count( tf_count ),
- .fifo_reset( tx_reset ),
- .reset_status(lsr_mask)
-);
-
-// TRANSMITTER FINAL STATE MACHINE
-
-parameter s_idle = 3'd0;
-parameter s_send_start = 3'd1;
-parameter s_send_byte = 3'd2;
-parameter s_send_parity = 3'd3;
-parameter s_send_stop = 3'd4;
-parameter s_pop_byte = 3'd5;
-
-always @(posedge clk or posedge wb_rst_i)
-begin
- if (wb_rst_i)
- begin
- tstate <= s_idle;
- stx_o_tmp <= 1'b1;
- counter <= 5'b0;
- shift_out <= 7'b0;
- bit_out <= 1'b0;
- parity_xor <= 1'b0;
- tf_pop <= 1'b0;
- bit_counter <= 3'b0;
- end
- else
- if (enable)
- begin
- case (tstate)
- s_idle : if (~|tf_count) // if tf_count==0
- begin
- tstate <= s_idle;
- stx_o_tmp <= 1'b1;
- end
- else
- begin
- tf_pop <= 1'b0;
- stx_o_tmp <= 1'b1;
- tstate <= s_pop_byte;
- end
- s_pop_byte : begin
- tf_pop <= 1'b1;
- case (lcr[/*`UART_LC_BITS*/1:0]) // number of bits in a word
- 2'b00 : begin
- bit_counter <= 3'b100;
- parity_xor <= ^tf_data_out[4:0];
- end
- 2'b01 : begin
- bit_counter <= 3'b101;
- parity_xor <= ^tf_data_out[5:0];
- end
- 2'b10 : begin
- bit_counter <= 3'b110;
- parity_xor <= ^tf_data_out[6:0];
- end
- 2'b11 : begin
- bit_counter <= 3'b111;
- parity_xor <= ^tf_data_out[7:0];
- end
- endcase
- {shift_out[6:0], bit_out} <= tf_data_out;
- tstate <= s_send_start;
- end
- s_send_start : begin
- tf_pop <= 1'b0;
- if (~|counter)
- counter <= 5'b01111;
- else
- if (counter == 5'b00001)
- begin
- counter <= 0;
- tstate <= s_send_byte;
- end
- else
- counter <= counter - 1'b1;
- stx_o_tmp <= 1'b0;
- end
- s_send_byte : begin
- if (~|counter)
- counter <= 5'b01111;
- else
- if (counter == 5'b00001)
- begin
- if (bit_counter > 3'b0)
- begin
- bit_counter <= bit_counter - 1'b1;
- {shift_out[5:0],bit_out } <= {shift_out[6:1], shift_out[0]};
- tstate <= s_send_byte;
- end
- else // end of byte
- if (~lcr[`UART_LC_PE])
- begin
- tstate <= s_send_stop;
- end
- else
- begin
- case ({lcr[`UART_LC_EP],lcr[`UART_LC_SP]})
- 2'b00: bit_out <= ~parity_xor;
- 2'b01: bit_out <= 1'b1;
- 2'b10: bit_out <= parity_xor;
- 2'b11: bit_out <= 1'b0;
- endcase
- tstate <= s_send_parity;
- end
- counter <= 0;
- end
- else
- counter <= counter - 1'b1;
- stx_o_tmp <= bit_out; // set output pin
- end
- s_send_parity : begin
- if (~|counter)
- counter <= 5'b01111;
- else
- if (counter == 5'b00001)
- begin
- counter <= 4'b0;
- tstate <= s_send_stop;
- end
- else
- counter <= counter - 1'b1;
- stx_o_tmp <= bit_out;
- end
- s_send_stop : begin
- if (~|counter)
- begin
- casex ({lcr[`UART_LC_SB],lcr[`UART_LC_BITS]})
- 3'b0xx: counter <= 5'b01101; // 1 stop bit ok igor
- 3'b100: counter <= 5'b10101; // 1.5 stop bit
- default: counter <= 5'b11101; // 2 stop bits
- endcase
- end
- else
- if (counter == 5'b00001)
- begin
- counter <= 0;
- tstate <= s_idle;
- end
- else
- counter <= counter - 1'b1;
- stx_o_tmp <= 1'b1;
- end
-
- default : // should never get here
- tstate <= s_idle;
- endcase
- end // end if enable
- else
- tf_pop <= 1'b0; // tf_pop must be 1 cycle width
-end // transmitter logic
-
-assign stx_pad_o = lcr[`UART_LC_BC] ? 1'b0 : stx_o_tmp; // Break condition
-
-endmodule
Index: trunk/src/testbench/External_IP/uart16550/rtl/uart_defines.v
===================================================================
--- trunk/src/testbench/External_IP/uart16550/rtl/uart_defines.v (revision 57)
+++ trunk/src/testbench/External_IP/uart16550/rtl/uart_defines.v (nonexistent)
@@ -1,249 +0,0 @@
-//////////////////////////////////////////////////////////////////////
-//// ////
-//// uart_defines.v ////
-//// ////
-//// ////
-//// This file is part of the "UART 16550 compatible" project ////
-//// http://www.opencores.org/cores/uart16550/ ////
-//// ////
-//// Documentation related to this project: ////
-//// - http://www.opencores.org/cores/uart16550/ ////
-//// ////
-//// Projects compatibility: ////
-//// - WISHBONE ////
-//// RS232 Protocol ////
-//// 16550D uart (mostly supported) ////
-//// ////
-//// Overview (main Features): ////
-//// Defines of the Core ////
-//// ////
-//// Known problems (limits): ////
-//// None ////
-//// ////
-//// To Do: ////
-//// Nothing. ////
-//// ////
-//// Author(s): ////
-//// - gorban@opencores.org ////
-//// - Jacob Gorban ////
-//// - Igor Mohor (igorm@opencores.org) ////
-//// ////
-//// Created: 2001/05/12 ////
-//// Last Updated: 2001/05/17 ////
-//// (See log for the revision history) ////
-///// Modified for use in the ZAP project by Revanth Kamaraj ////
-/// ////
-//// ////
-//////////////////////////////////////////////////////////////////////
-//// ////
-//// Copyright (C) 2000, 2001 Authors ////
-//// ////
-//// This source file may be used and distributed without ////
-//// restriction provided that this copyright statement is not ////
-//// removed from the file and that any derivative work contains ////
-//// the original copyright notice and the associated disclaimer. ////
-//// ////
-//// This source file is free software; you can redistribute it ////
-//// and/or modify it under the terms of the GNU Lesser General ////
-//// Public License as published by the Free Software Foundation; ////
-//// either version 2.1 of the License, or (at your option) any ////
-//// later version. ////
-//// ////
-//// This source 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 Lesser General Public License for more ////
-//// details. ////
-//// ////
-//// You should have received a copy of the GNU Lesser General ////
-//// Public License along with this source; if not, download it ////
-//// from http://www.opencores.org/lgpl.shtml ////
-//// ////
-//////////////////////////////////////////////////////////////////////
-//
-// CVS Revision History
-//
-// $Log: not supported by cvs2svn $
-// Revision 1.13 2003/06/11 16:37:47 gorban
-// This fixes errors in some cases when data is being read and put to the FIFO at the same time. Patch is submitted by Scott Furman. Update is very recommended.
-//
-// Revision 1.12 2002/07/22 23:02:23 gorban
-// Bug Fixes:
-// * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
-// Problem reported by Kenny.Tung.
-// * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
-//
-// Improvements:
-// * Made FIFO's as general inferrable memory where possible.
-// So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
-// This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
-//
-// * Added optional baudrate output (baud_o).
-// This is identical to BAUDOUT* signal on 16550 chip.
-// It outputs 16xbit_clock_rate - the divided clock.
-// It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use.
-//
-// Revision 1.10 2001/12/11 08:55:40 mohor
-// Scratch register define added.
-//
-// Revision 1.9 2001/12/03 21:44:29 gorban
-// Updated specification documentation.
-// Added full 32-bit data bus interface, now as default.
-// Address is 5-bit wide in 32-bit data bus mode.
-// Added wb_sel_i input to the core. It's used in the 32-bit mode.
-// Added debug interface with two 32-bit read-only registers in 32-bit mode.
-// Bits 5 and 6 of LSR are now only cleared on TX FIFO write.
-// My small test bench is modified to work with 32-bit mode.
-//
-// Revision 1.8 2001/11/26 21:38:54 gorban
-// Lots of fixes:
-// Break condition wasn't handled correctly at all.
-// LSR bits could lose their values.
-// LSR value after reset was wrong.
-// Timing of THRE interrupt signal corrected.
-// LSR bit 0 timing corrected.
-//
-// Revision 1.7 2001/08/24 21:01:12 mohor
-// Things connected to parity changed.
-// Clock devider changed.
-//
-// Revision 1.6 2001/08/23 16:05:05 mohor
-// Stop bit bug fixed.
-// Parity bug fixed.
-// WISHBONE read cycle bug fixed,
-// OE indicator (Overrun Error) bug fixed.
-// PE indicator (Parity Error) bug fixed.
-// Register read bug fixed.
-//
-// Revision 1.5 2001/05/31 20:08:01 gorban
-// FIFO changes and other corrections.
-//
-// Revision 1.4 2001/05/21 19:12:02 gorban
-// Corrected some Linter messages.
-//
-// Revision 1.3 2001/05/17 18:34:18 gorban
-// First 'stable' release. Should be sythesizable now. Also added new header.
-//
-// Revision 1.0 2001-05-17 21:27:11+02 jacob
-// Initial revision
-//
-//
-
-// remove comments to restore to use the new version with 8 data bit interface
-// in 32bit-bus mode, the wb_sel_i signal is used to put data in correct place
-// also, in 8-bit version there'll be no debugging features included
-// CAUTION: doesn't work with current version of OR1200
-//`define DATA_BUS_WIDTH_8
-
-`ifdef DATA_BUS_WIDTH_8
- `define UART_ADDR_WIDTH 3
- `define UART_DATA_WIDTH 8
-`else
- `define UART_ADDR_WIDTH 5
- `define UART_DATA_WIDTH 32
-`endif
-
-// Uncomment this if you want your UART to have
-// 16xBaudrate output port.
-// If defined, the enable signal will be used to drive baudrate_o signal
-// It's frequency is 16xbaudrate
-
-// `define UART_HAS_BAUDRATE_OUTPUT
-
-// Register addresses
-`define UART_REG_RB `UART_ADDR_WIDTH'd0 // receiver buffer
-`define UART_REG_TR `UART_ADDR_WIDTH'd0 // transmitter
-`define UART_REG_IE `UART_ADDR_WIDTH'd1 // Interrupt enable
-`define UART_REG_II `UART_ADDR_WIDTH'd2 // Interrupt identification
-`define UART_REG_FC `UART_ADDR_WIDTH'd2 // FIFO control
-`define UART_REG_LC `UART_ADDR_WIDTH'd3 // Line Control
-`define UART_REG_MC `UART_ADDR_WIDTH'd4 // Modem control
-`define UART_REG_LS `UART_ADDR_WIDTH'd5 // Line status
-`define UART_REG_MS `UART_ADDR_WIDTH'd6 // Modem status
-`define UART_REG_SR `UART_ADDR_WIDTH'd7 // Scratch register
-`define UART_REG_DL1 `UART_ADDR_WIDTH'd0 // Divisor latch bytes (1-2)
-`define UART_REG_DL2 `UART_ADDR_WIDTH'd1
-
-// Interrupt Enable register bits
-`define UART_IE_RDA 0 // Received Data available interrupt
-`define UART_IE_THRE 1 // Transmitter Holding Register empty interrupt
-`define UART_IE_RLS 2 // Receiver Line Status Interrupt
-`define UART_IE_MS 3 // Modem Status Interrupt
-
-// Interrupt Identification register bits
-`define UART_II_IP 0 // Interrupt pending when 0
-`define UART_II_II 3:1 // Interrupt identification
-
-// Interrupt identification values for bits 3:1
-`define UART_II_RLS 3'b011 // Receiver Line Status
-`define UART_II_RDA 3'b010 // Receiver Data available
-`define UART_II_TI 3'b110 // Timeout Indication
-`define UART_II_THRE 3'b001 // Transmitter Holding Register empty
-`define UART_II_MS 3'b000 // Modem Status
-
-// FIFO Control Register bits
-`define UART_FC_TL 1:0 // Trigger level
-
-// FIFO trigger level values
-`define UART_FC_1 2'b00
-`define UART_FC_4 2'b01
-`define UART_FC_8 2'b10
-`define UART_FC_14 2'b11
-
-// Line Control register bits
-`define UART_LC_BITS 1:0 // bits in character
-`define UART_LC_SB 2 // stop bits
-`define UART_LC_PE 3 // parity enable
-`define UART_LC_EP 4 // even parity
-`define UART_LC_SP 5 // stick parity
-`define UART_LC_BC 6 // Break control
-`define UART_LC_DL 7 // Divisor Latch access bit
-
-// Modem Control register bits
-`define UART_MC_DTR 0
-`define UART_MC_RTS 1
-`define UART_MC_OUT1 2
-`define UART_MC_OUT2 3
-`define UART_MC_LB 4 // Loopback mode
-
-// Line Status Register bits
-`define UART_LS_DR 0 // Data ready
-`define UART_LS_OE 1 // Overrun Error
-`define UART_LS_PE 2 // Parity Error
-`define UART_LS_FE 3 // Framing Error
-`define UART_LS_BI 4 // Break interrupt
-`define UART_LS_TFE 5 // Transmit FIFO is empty
-`define UART_LS_TE 6 // Transmitter Empty indicator
-`define UART_LS_EI 7 // Error indicator
-
-// Modem Status Register bits
-`define UART_MS_DCTS 0 // Delta signals
-`define UART_MS_DDSR 1
-`define UART_MS_TERI 2
-`define UART_MS_DDCD 3
-`define UART_MS_CCTS 4 // Complement signals
-`define UART_MS_CDSR 5
-`define UART_MS_CRI 6
-`define UART_MS_CDCD 7
-
-// FIFO parameter defines
-
-`define UART_FIFO_WIDTH 8
-`define UART_FIFO_DEPTH 16
-`define UART_FIFO_POINTER_W 4
-`define UART_FIFO_COUNTER_W 5
-// receiver fifo has width 11 because it has break, parity and framing error bits
-`define UART_FIFO_REC_WIDTH 11
-
-
-`define VERBOSE_WB 0 // All activity on the WISHBONE is recorded
-`define VERBOSE_LINE_STATUS 0 // Details about the lsr (line status register)
-`define FAST_TEST 1 // 64/1024 packets are sent
-
-// Added by Revanth to support LITTLE_ENDIAN mode of operation.
-`define LITLE_ENDIAN
-
-
-
-
-
Index: trunk/src/testbench/External_IP/uart16550/rtl/uart_sync_flops.v
===================================================================
--- trunk/src/testbench/External_IP/uart16550/rtl/uart_sync_flops.v (revision 57)
+++ trunk/src/testbench/External_IP/uart16550/rtl/uart_sync_flops.v (nonexistent)
@@ -1,122 +0,0 @@
-//////////////////////////////////////////////////////////////////////
-//// ////
-//// uart_sync_flops.v ////
-//// ////
-//// ////
-//// This file is part of the "UART 16550 compatible" project ////
-//// http://www.opencores.org/cores/uart16550/ ////
-//// ////
-//// Documentation related to this project: ////
-//// - http://www.opencores.org/cores/uart16550/ ////
-//// ////
-//// Projects compatibility: ////
-//// - WISHBONE ////
-//// RS232 Protocol ////
-//// 16550D uart (mostly supported) ////
-//// ////
-//// Overview (main Features): ////
-//// UART core receiver logic ////
-//// ////
-//// Known problems (limits): ////
-//// None known ////
-//// ////
-//// To Do: ////
-//// Thourough testing. ////
-//// ////
-//// Author(s): ////
-//// - Andrej Erzen (andreje@flextronics.si) ////
-//// - Tadej Markovic (tadejm@flextronics.si) ////
-//// ////
-//// Created: 2004/05/20 ////
-//// Last Updated: 2004/05/20 ////
-//// (See log for the revision history) ////
-//// Modified for use in the ZAP project by Revanth Kamaraj ////
-//// ////
-//// ////
-//////////////////////////////////////////////////////////////////////
-//// ////
-//// Copyright (C) 2000, 2001 Authors ////
-//// ////
-//// This source file may be used and distributed without ////
-//// restriction provided that this copyright statement is not ////
-//// removed from the file and that any derivative work contains ////
-//// the original copyright notice and the associated disclaimer. ////
-//// ////
-//// This source file is free software; you can redistribute it ////
-//// and/or modify it under the terms of the GNU Lesser General ////
-//// Public License as published by the Free Software Foundation; ////
-//// either version 2.1 of the License, or (at your option) any ////
-//// later version. ////
-//// ////
-//// This source 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 Lesser General Public License for more ////
-//// details. ////
-//// ////
-//// You should have received a copy of the GNU Lesser General ////
-//// Public License along with this source; if not, download it ////
-//// from http://www.opencores.org/lgpl.shtml ////
-//// ////
-//////////////////////////////////////////////////////////////////////
-//
-// CVS Revision History
-//
-// $Log: not supported by cvs2svn $
-//
-
-
-
-
-module uart_sync_flops
-(
- // internal signals
- rst_i,
- clk_i,
- stage1_rst_i,
- stage1_clk_en_i,
- async_dat_i,
- sync_dat_o
-);
-
-parameter Tp = 1;
-parameter width = 1;
-parameter init_value = 1'b0;
-
-input rst_i; // reset input
-input clk_i; // clock input
-input stage1_rst_i; // synchronous reset for stage 1 FF
-input stage1_clk_en_i; // synchronous clock enable for stage 1 FF
-input [width-1:0] async_dat_i; // asynchronous data input
-output [width-1:0] sync_dat_o; // synchronous data output
-
-
-//
-// Interal signal declarations
-//
-
-reg [width-1:0] sync_dat_o;
-reg [width-1:0] flop_0;
-
-
-// first stage
-always @ (posedge clk_i or posedge rst_i)
-begin
- if (rst_i)
- flop_0 <= #Tp {width{init_value}};
- else
- flop_0 <= #Tp async_dat_i;
-end
-
-// second stage
-always @ (posedge clk_i or posedge rst_i)
-begin
- if (rst_i)
- sync_dat_o <= #Tp {width{init_value}};
- else if (stage1_rst_i)
- sync_dat_o <= #Tp {width{init_value}};
- else if (stage1_clk_en_i)
- sync_dat_o <= #Tp flop_0;
-end
-
-endmodule
Index: trunk/src/testbench/External_IP/uart16550/rtl/uart_regs.v
===================================================================
--- trunk/src/testbench/External_IP/uart16550/rtl/uart_regs.v (revision 57)
+++ trunk/src/testbench/External_IP/uart16550/rtl/uart_regs.v (nonexistent)
@@ -1,892 +0,0 @@
-//////////////////////////////////////////////////////////////////////
-//// ////
-//// uart_regs.v ////
-//// ////
-//// ////
-//// This file is part of the "UART 16550 compatible" project ////
-//// http://www.opencores.org/cores/uart16550/ ////
-//// ////
-//// Documentation related to this project: ////
-//// - http://www.opencores.org/cores/uart16550/ ////
-//// ////
-//// Projects compatibility: ////
-//// - WISHBONE ////
-//// RS232 Protocol ////
-//// 16550D uart (mostly supported) ////
-//// ////
-//// Overview (main Features): ////
-//// Registers of the uart 16550 core ////
-//// ////
-//// Known problems (limits): ////
-//// Inserts 1 wait state in all WISHBONE transfers ////
-//// ////
-//// To Do: ////
-//// Nothing or verification. ////
-//// ////
-//// Author(s): ////
-//// - gorban@opencores.org ////
-//// - Jacob Gorban ////
-//// - Igor Mohor (igorm@opencores.org) ////
-//// ////
-//// Created: 2001/05/12 ////
-//// Last Updated: (See log for the revision history ////
-//// Modified for use in the ZAP project by Revanth Kamaraj ////
-//// ////
-//// ////
-//////////////////////////////////////////////////////////////////////
-//// ////
-//// Copyright (C) 2000, 2001 Authors ////
-//// ////
-//// This source file may be used and distributed without ////
-//// restriction provided that this copyright statement is not ////
-//// removed from the file and that any derivative work contains ////
-//// the original copyright notice and the associated disclaimer. ////
-//// ////
-//// This source file is free software; you can redistribute it ////
-//// and/or modify it under the terms of the GNU Lesser General ////
-//// Public License as published by the Free Software Foundation; ////
-//// either version 2.1 of the License, or (at your option) any ////
-//// later version. ////
-//// ////
-//// This source 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 Lesser General Public License for more ////
-//// details. ////
-//// ////
-//// You should have received a copy of the GNU Lesser General ////
-//// Public License along with this source; if not, download it ////
-//// from http://www.opencores.org/lgpl.shtml ////
-//// ////
-//////////////////////////////////////////////////////////////////////
-//
-// CVS Revision History
-//
-// $Log: not supported by cvs2svn $
-// Revision 1.41 2004/05/21 11:44:41 tadejm
-// Added synchronizer flops for RX input.
-//
-// Revision 1.40 2003/06/11 16:37:47 gorban
-// This fixes errors in some cases when data is being read and put to the FIFO at the same time. Patch is submitted by Scott Furman. Update is very recommended.
-//
-// Revision 1.39 2002/07/29 21:16:18 gorban
-// The uart_defines.v file is included again in sources.
-//
-// Revision 1.38 2002/07/22 23:02:23 gorban
-// Bug Fixes:
-// * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
-// Problem reported by Kenny.Tung.
-// * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
-//
-// Improvements:
-// * Made FIFO's as general inferrable memory where possible.
-// So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
-// This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
-//
-// * Added optional baudrate output (baud_o).
-// This is identical to BAUDOUT* signal on 16550 chip.
-// It outputs 16xbit_clock_rate - the divided clock.
-// It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use.
-//
-// Revision 1.37 2001/12/27 13:24:09 mohor
-// lsr[7] was not showing overrun errors.
-//
-// Revision 1.36 2001/12/20 13:25:46 mohor
-// rx push changed to be only one cycle wide.
-//
-// Revision 1.35 2001/12/19 08:03:34 mohor
-// Warnings cleared.
-//
-// Revision 1.34 2001/12/19 07:33:54 mohor
-// Synplicity was having troubles with the comment.
-//
-// Revision 1.33 2001/12/17 10:14:43 mohor
-// Things related to msr register changed. After THRE IRQ occurs, and one
-// character is written to the transmit fifo, the detection of the THRE bit in the
-// LSR is delayed for one character time.
-//
-// Revision 1.32 2001/12/14 13:19:24 mohor
-// MSR register fixed.
-//
-// Revision 1.31 2001/12/14 10:06:58 mohor
-// After reset modem status register MSR should be reset.
-//
-// Revision 1.30 2001/12/13 10:09:13 mohor
-// thre irq should be cleared only when being source of interrupt.
-//
-// Revision 1.29 2001/12/12 09:05:46 mohor
-// LSR status bit 0 was not cleared correctly in case of reseting the FCR (rx fifo).
-//
-// Revision 1.28 2001/12/10 19:52:41 gorban
-// Scratch register added
-//
-// Revision 1.27 2001/12/06 14:51:04 gorban
-// Bug in LSR[0] is fixed.
-// All WISHBONE signals are now sampled, so another wait-state is introduced on all transfers.
-//
-// Revision 1.26 2001/12/03 21:44:29 gorban
-// Updated specification documentation.
-// Added full 32-bit data bus interface, now as default.
-// Address is 5-bit wide in 32-bit data bus mode.
-// Added wb_sel_i input to the core. It's used in the 32-bit mode.
-// Added debug interface with two 32-bit read-only registers in 32-bit mode.
-// Bits 5 and 6 of LSR are now only cleared on TX FIFO write.
-// My small test bench is modified to work with 32-bit mode.
-//
-// Revision 1.25 2001/11/28 19:36:39 gorban
-// Fixed: timeout and break didn't pay attention to current data format when counting time
-//
-// Revision 1.24 2001/11/26 21:38:54 gorban
-// Lots of fixes:
-// Break condition wasn't handled correctly at all.
-// LSR bits could lose their values.
-// LSR value after reset was wrong.
-// Timing of THRE interrupt signal corrected.
-// LSR bit 0 timing corrected.
-//
-// Revision 1.23 2001/11/12 21:57:29 gorban
-// fixed more typo bugs
-//
-// Revision 1.22 2001/11/12 15:02:28 mohor
-// lsr1r error fixed.
-//
-// Revision 1.21 2001/11/12 14:57:27 mohor
-// ti_int_pnd error fixed.
-//
-// Revision 1.20 2001/11/12 14:50:27 mohor
-// ti_int_d error fixed.
-//
-// Revision 1.19 2001/11/10 12:43:21 gorban
-// Logic Synthesis bugs fixed. Some other minor changes
-//
-// Revision 1.18 2001/11/08 14:54:23 mohor
-// Comments in Slovene language deleted, few small fixes for better work of
-// old tools. IRQs need to be fix.
-//
-// Revision 1.17 2001/11/07 17:51:52 gorban
-// Heavily rewritten interrupt and LSR subsystems.
-// Many bugs hopefully squashed.
-//
-// Revision 1.16 2001/11/02 09:55:16 mohor
-// no message
-//
-// Revision 1.15 2001/10/31 15:19:22 gorban
-// Fixes to break and timeout conditions
-//
-// Revision 1.14 2001/10/29 17:00:46 gorban
-// fixed parity sending and tx_fifo resets over- and underrun
-//
-// Revision 1.13 2001/10/20 09:58:40 gorban
-// Small synopsis fixes
-//
-// Revision 1.12 2001/10/19 16:21:40 gorban
-// Changes data_out to be synchronous again as it should have been.
-//
-// Revision 1.11 2001/10/18 20:35:45 gorban
-// small fix
-//
-// Revision 1.10 2001/08/24 21:01:12 mohor
-// Things connected to parity changed.
-// Clock devider changed.
-//
-// Revision 1.9 2001/08/23 16:05:05 mohor
-// Stop bit bug fixed.
-// Parity bug fixed.
-// WISHBONE read cycle bug fixed,
-// OE indicator (Overrun Error) bug fixed.
-// PE indicator (Parity Error) bug fixed.
-// Register read bug fixed.
-//
-// Revision 1.10 2001/06/23 11:21:48 gorban
-// DL made 16-bit long. Fixed transmission/reception bugs.
-//
-// Revision 1.9 2001/05/31 20:08:01 gorban
-// FIFO changes and other corrections.
-//
-// Revision 1.8 2001/05/29 20:05:04 gorban
-// Fixed some bugs and synthesis problems.
-//
-// Revision 1.7 2001/05/27 17:37:49 gorban
-// Fixed many bugs. Updated spec. Changed FIFO files structure. See CHANGES.txt file.
-//
-// Revision 1.6 2001/05/21 19:12:02 gorban
-// Corrected some Linter messages.
-//
-// Revision 1.5 2001/05/17 18:34:18 gorban
-// First 'stable' release. Should be sythesizable now. Also added new header.
-//
-// Revision 1.0 2001-05-17 21:27:11+02 jacob
-// Initial revision
-//
-//
-//// Modified for use in the ZAP project by Revanth Kamaraj ////
-
-
-`include "uart_defines.v"
-
-`define UART_DL1 7:0
-`define UART_DL2 15:8
-
-module uart_regs (clk,
- wb_rst_i, wb_addr_i, wb_dat_i, wb_dat_o, wb_we_i, wb_re_i,
-
-// additional signals
- modem_inputs,
- stx_pad_o, srx_pad_i,
-
-`ifdef DATA_BUS_WIDTH_8
-`else
-// debug interface signals enabled
-ier, iir, fcr, mcr, lcr, msr, lsr, rf_count, tf_count, tstate, rstate,
-`endif
- rts_pad_o, dtr_pad_o, int_o
-`ifdef UART_HAS_BAUDRATE_OUTPUT
- , baud_o
-`endif
-
- );
-
-input clk;
-input wb_rst_i;
-input [`UART_ADDR_WIDTH-1:0] wb_addr_i;
-input [7:0] wb_dat_i;
-output [7:0] wb_dat_o;
-input wb_we_i;
-input wb_re_i;
-
-output stx_pad_o;
-input srx_pad_i;
-
-input [3:0] modem_inputs;
-output rts_pad_o;
-output dtr_pad_o;
-output int_o;
-`ifdef UART_HAS_BAUDRATE_OUTPUT
-output baud_o;
-`endif
-
-`ifdef DATA_BUS_WIDTH_8
-`else
-// if 32-bit databus and debug interface are enabled
-output [3:0] ier;
-output [3:0] iir;
-output [1:0] fcr; /// bits 7 and 6 of fcr. Other bits are ignored
-output [4:0] mcr;
-output [7:0] lcr;
-output [7:0] msr;
-output [7:0] lsr;
-output [`UART_FIFO_COUNTER_W-1:0] rf_count;
-output [`UART_FIFO_COUNTER_W-1:0] tf_count;
-output [2:0] tstate;
-output [3:0] rstate;
-
-`endif
-
-wire [3:0] modem_inputs;
-reg enable;
-`ifdef UART_HAS_BAUDRATE_OUTPUT
-assign baud_o = enable; // baud_o is actually the enable signal
-`endif
-
-
-wire stx_pad_o; // received from transmitter module
-wire srx_pad_i;
-wire srx_pad;
-
-reg [7:0] wb_dat_o;
-
-wire [`UART_ADDR_WIDTH-1:0] wb_addr_i;
-wire [7:0] wb_dat_i;
-
-
-reg [3:0] ier;
-reg [3:0] iir;
-reg [1:0] fcr; /// bits 7 and 6 of fcr. Other bits are ignored
-reg [4:0] mcr;
-reg [7:0] lcr;
-reg [7:0] msr;
-reg [15:0] dl; // 32-bit divisor latch
-reg [7:0] scratch; // UART scratch register
-reg start_dlc; // activate dlc on writing to UART_DL1
-reg lsr_mask_d; // delay for lsr_mask condition
-reg msi_reset; // reset MSR 4 lower bits indicator
-//reg threi_clear; // THRE interrupt clear flag
-reg [15:0] dlc; // 32-bit divisor latch counter
-reg int_o;
-
-reg [3:0] trigger_level; // trigger level of the receiver FIFO
-reg rx_reset;
-reg tx_reset;
-
-wire dlab; // divisor latch access bit
-wire cts_pad_i, dsr_pad_i, ri_pad_i, dcd_pad_i; // modem status bits
-wire loopback; // loopback bit (MCR bit 4)
-wire cts, dsr, ri, dcd; // effective signals
-wire cts_c, dsr_c, ri_c, dcd_c; // Complement effective signals (considering loopback)
-wire rts_pad_o, dtr_pad_o; // modem control outputs
-
-// LSR bits wires and regs
-wire [7:0] lsr;
-wire lsr0, lsr1, lsr2, lsr3, lsr4, lsr5, lsr6, lsr7;
-reg lsr0r, lsr1r, lsr2r, lsr3r, lsr4r, lsr5r, lsr6r, lsr7r;
-wire lsr_mask; // lsr_mask
-
-//
-// ASSINGS
-//
-
-assign lsr[7:0] = { lsr7r, lsr6r, lsr5r, lsr4r, lsr3r, lsr2r, lsr1r, lsr0r };
-
-assign {cts_pad_i, dsr_pad_i, ri_pad_i, dcd_pad_i} = modem_inputs;
-assign {cts, dsr, ri, dcd} = ~{cts_pad_i,dsr_pad_i,ri_pad_i,dcd_pad_i};
-
-assign {cts_c, dsr_c, ri_c, dcd_c} = loopback ? {mcr[`UART_MC_RTS],mcr[`UART_MC_DTR],mcr[`UART_MC_OUT1],mcr[`UART_MC_OUT2]}
- : {cts_pad_i,dsr_pad_i,ri_pad_i,dcd_pad_i};
-
-assign dlab = lcr[`UART_LC_DL];
-assign loopback = mcr[4];
-
-// assign modem outputs
-assign rts_pad_o = mcr[`UART_MC_RTS];
-assign dtr_pad_o = mcr[`UART_MC_DTR];
-
-// Interrupt signals
-wire rls_int; // receiver line status interrupt
-wire rda_int; // receiver data available interrupt
-wire ti_int; // timeout indicator interrupt
-wire thre_int; // transmitter holding register empty interrupt
-wire ms_int; // modem status interrupt
-
-// FIFO signals
-reg tf_push;
-reg rf_pop;
-wire [`UART_FIFO_REC_WIDTH-1:0] rf_data_out;
-wire rf_error_bit; // an error (parity or framing) is inside the fifo
-wire [`UART_FIFO_COUNTER_W-1:0] rf_count;
-wire [`UART_FIFO_COUNTER_W-1:0] tf_count;
-wire [2:0] tstate;
-wire [3:0] rstate;
-wire [9:0] counter_t;
-
-wire thre_set_en; // THRE status is delayed one character time when a character is written to fifo.
-reg [7:0] block_cnt; // While counter counts, THRE status is blocked (delayed one character cycle)
-reg [7:0] block_value; // One character length minus stop bit
-
-// Transmitter Instance
-wire serial_out;
-
-uart_transmitter transmitter(clk, wb_rst_i, lcr, tf_push, wb_dat_i, enable, serial_out, tstate, tf_count, tx_reset, lsr_mask);
-
- // Synchronizing and sampling serial RX input
- uart_sync_flops i_uart_sync_flops
- (
- .rst_i (wb_rst_i),
- .clk_i (clk),
- .stage1_rst_i (1'b0),
- .stage1_clk_en_i (1'b1),
- .async_dat_i (srx_pad_i),
- .sync_dat_o (srx_pad)
- );
- defparam i_uart_sync_flops.width = 1;
- defparam i_uart_sync_flops.init_value = 1'b1;
-
-// handle loopback
-wire serial_in = loopback ? serial_out : srx_pad;
-assign stx_pad_o = loopback ? 1'b1 : serial_out;
-
-// Receiver Instance
-uart_receiver receiver(clk, wb_rst_i, lcr, rf_pop, serial_in, enable,
- counter_t, rf_count, rf_data_out, rf_error_bit, rf_overrun, rx_reset, lsr_mask, rstate, rf_push_pulse);
-
-
-// Asynchronous reading here because the outputs are sampled in uart_wb.v file
-always @(dl or dlab or ier or iir or scratch
- or lcr or lsr or msr or rf_data_out or wb_addr_i or wb_re_i) // asynchrounous reading
-begin
- case (wb_addr_i)
- `UART_REG_RB : wb_dat_o = dlab ? dl[`UART_DL1] : rf_data_out[10:3];
- `UART_REG_IE : wb_dat_o = dlab ? dl[`UART_DL2] : ier;
- `UART_REG_II : wb_dat_o = {4'b1100,iir};
- `UART_REG_LC : wb_dat_o = lcr;
- `UART_REG_LS : wb_dat_o = lsr;
- `UART_REG_MS : wb_dat_o = msr;
- `UART_REG_SR : wb_dat_o = scratch;
- default: wb_dat_o = 8'b0; // ??
- endcase // case(wb_addr_i)
-end // always @ (dl or dlab or ier or iir or scratch...
-
-
-// rf_pop signal handling
-always @(posedge clk or posedge wb_rst_i)
-begin
- if (wb_rst_i)
- rf_pop <= 0;
- else
- if (rf_pop) // restore the signal to 0 after one clock cycle
- rf_pop <= 0;
- else
- if (wb_re_i && wb_addr_i == `UART_REG_RB && !dlab)
- rf_pop <= 1; // advance read pointer
-end
-
-wire lsr_mask_condition;
-wire iir_read;
-wire msr_read;
-wire fifo_read;
-wire fifo_write;
-
-assign lsr_mask_condition = (wb_re_i && wb_addr_i == `UART_REG_LS && !dlab);
-assign iir_read = (wb_re_i && wb_addr_i == `UART_REG_II && !dlab);
-assign msr_read = (wb_re_i && wb_addr_i == `UART_REG_MS && !dlab);
-assign fifo_read = (wb_re_i && wb_addr_i == `UART_REG_RB && !dlab);
-assign fifo_write = (wb_we_i && wb_addr_i == `UART_REG_TR && !dlab);
-
-// lsr_mask_d delayed signal handling
-always @(posedge clk or posedge wb_rst_i)
-begin
- if (wb_rst_i)
- lsr_mask_d <= 0;
- else // reset bits in the Line Status Register
- lsr_mask_d <= lsr_mask_condition;
-end
-
-// lsr_mask is rise detected
-assign lsr_mask = lsr_mask_condition && ~lsr_mask_d;
-
-// msi_reset signal handling
-always @(posedge clk or posedge wb_rst_i)
-begin
- if (wb_rst_i)
- msi_reset <= 1;
- else
- if (msi_reset)
- msi_reset <= 0;
- else
- if (msr_read)
- msi_reset <= 1; // reset bits in Modem Status Register
-end
-
-
-//
-// WRITES AND RESETS //
-//
-// Line Control Register
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i)
- lcr <= 8'b00000011; // 8n1 setting
- else
- if (wb_we_i && wb_addr_i==`UART_REG_LC)
- lcr <= wb_dat_i;
-
-// Interrupt Enable Register or UART_DL2
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i)
- begin
- ier <= 4'b0000; // no interrupts after reset
- dl[`UART_DL2] <= 8'b0;
- end
- else
- if (wb_we_i && wb_addr_i==`UART_REG_IE)
- if (dlab)
- begin
- dl[`UART_DL2] <= wb_dat_i;
- end
- else
- ier <= wb_dat_i[3:0]; // ier uses only 4 lsb
-
-
-// FIFO Control Register and rx_reset, tx_reset signals
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) begin
- fcr <= 2'b11;
- rx_reset <= 0;
- tx_reset <= 0;
- end else
- if (wb_we_i && wb_addr_i==`UART_REG_FC) begin
- fcr <= wb_dat_i[7:6];
- rx_reset <= wb_dat_i[1];
- tx_reset <= wb_dat_i[2];
- end else begin
- rx_reset <= 0;
- tx_reset <= 0;
- end
-
-// Modem Control Register
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i)
- mcr <= 5'b0;
- else
- if (wb_we_i && wb_addr_i==`UART_REG_MC)
- mcr <= wb_dat_i[4:0];
-
-// Scratch register
-// Line Control Register
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i)
- scratch <= 0; // 8n1 setting
- else
- if (wb_we_i && wb_addr_i==`UART_REG_SR)
- scratch <= wb_dat_i;
-
-// TX_FIFO or UART_DL1
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i)
- begin
- dl[`UART_DL1] <= 8'b0;
- tf_push <= 1'b0;
- start_dlc <= 1'b0;
- end
- else
- if (wb_we_i && wb_addr_i==`UART_REG_TR)
- if (dlab)
- begin
- dl[`UART_DL1] <= wb_dat_i;
- start_dlc <= 1'b1; // enable DL counter
- tf_push <= 1'b0;
- end
- else
- begin
- tf_push <= 1'b1;
- start_dlc <= 1'b0;
- end // else: !if(dlab)
- else
- begin
- start_dlc <= 1'b0;
- tf_push <= 1'b0;
- end // else: !if(dlab)
-
-// Receiver FIFO trigger level selection logic (asynchronous mux)
-always @(fcr)
- case (fcr[`UART_FC_TL])
- 2'b00 : trigger_level = 1;
- 2'b01 : trigger_level = 4;
- 2'b10 : trigger_level = 8;
- 2'b11 : trigger_level = 14;
- endcase // case(fcr[`UART_FC_TL])
-
-//
-// STATUS REGISTERS //
-//
-
-// Modem Status Register
-reg [3:0] delayed_modem_signals;
-always @(posedge clk or posedge wb_rst_i)
-begin
- if (wb_rst_i)
- begin
- msr <= 0;
- delayed_modem_signals[3:0] <= 0;
- end
- else begin
- msr[`UART_MS_DDCD:`UART_MS_DCTS] <= msi_reset ? 4'b0 :
- msr[`UART_MS_DDCD:`UART_MS_DCTS] | ({dcd, ri, dsr, cts} ^ delayed_modem_signals[3:0]);
- msr[`UART_MS_CDCD:`UART_MS_CCTS] <= {dcd_c, ri_c, dsr_c, cts_c};
- delayed_modem_signals[3:0] <= {dcd, ri, dsr, cts};
- end
-end
-
-
-// Line Status Register
-
-// activation conditions
-assign lsr0 = (rf_count==0 && rf_push_pulse); // data in receiver fifo available set condition
-assign lsr1 = rf_overrun; // Receiver overrun error
-assign lsr2 = rf_data_out[1]; // parity error bit
-assign lsr3 = rf_data_out[0]; // framing error bit
-assign lsr4 = rf_data_out[2]; // break error in the character
-assign lsr5 = (tf_count==5'b0 && thre_set_en); // transmitter fifo is empty
-assign lsr6 = (tf_count==5'b0 && thre_set_en && (tstate == /*`S_IDLE */ 0)); // transmitter empty
-assign lsr7 = rf_error_bit | rf_overrun;
-
-// lsr bit0 (receiver data available)
-reg lsr0_d;
-
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) lsr0_d <= 0;
- else lsr0_d <= lsr0;
-
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) lsr0r <= 0;
- else lsr0r <= (rf_count==1 && rf_pop && !rf_push_pulse || rx_reset) ? 0 : // deassert condition
- lsr0r || (lsr0 && ~lsr0_d); // set on rise of lsr0 and keep asserted until deasserted
-
-// lsr bit 1 (receiver overrun)
-reg lsr1_d; // delayed
-
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) lsr1_d <= 0;
- else lsr1_d <= lsr1;
-
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) lsr1r <= 0;
- else lsr1r <= lsr_mask ? 0 : lsr1r || (lsr1 && ~lsr1_d); // set on rise
-
-// lsr bit 2 (parity error)
-reg lsr2_d; // delayed
-
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) lsr2_d <= 0;
- else lsr2_d <= lsr2;
-
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) lsr2r <= 0;
- else lsr2r <= lsr_mask ? 0 : lsr2r || (lsr2 && ~lsr2_d); // set on rise
-
-// lsr bit 3 (framing error)
-reg lsr3_d; // delayed
-
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) lsr3_d <= 0;
- else lsr3_d <= lsr3;
-
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) lsr3r <= 0;
- else lsr3r <= lsr_mask ? 0 : lsr3r || (lsr3 && ~lsr3_d); // set on rise
-
-// lsr bit 4 (break indicator)
-reg lsr4_d; // delayed
-
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) lsr4_d <= 0;
- else lsr4_d <= lsr4;
-
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) lsr4r <= 0;
- else lsr4r <= lsr_mask ? 0 : lsr4r || (lsr4 && ~lsr4_d);
-
-// lsr bit 5 (transmitter fifo is empty)
-reg lsr5_d;
-
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) lsr5_d <= 1;
- else lsr5_d <= lsr5;
-
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) lsr5r <= 1;
- else lsr5r <= (fifo_write) ? 0 : lsr5r || (lsr5 && ~lsr5_d);
-
-// lsr bit 6 (transmitter empty indicator)
-reg lsr6_d;
-
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) lsr6_d <= 1;
- else lsr6_d <= lsr6;
-
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) lsr6r <= 1;
- else lsr6r <= (fifo_write) ? 0 : lsr6r || (lsr6 && ~lsr6_d);
-
-// lsr bit 7 (error in fifo)
-reg lsr7_d;
-
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) lsr7_d <= 0;
- else lsr7_d <= lsr7;
-
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) lsr7r <= 0;
- else lsr7r <= lsr_mask ? 0 : lsr7r || (lsr7 && ~lsr7_d);
-
-// Frequency divider
-always @(posedge clk or posedge wb_rst_i)
-begin
- if (wb_rst_i)
- dlc <= 0;
- else
- if (start_dlc | ~ (|dlc))
- dlc <= dl - 1; // preset counter
- else
- dlc <= dlc - 1; // decrement counter
-end
-
-// Enable signal generation logic
-always @(posedge clk or posedge wb_rst_i)
-begin
- if (wb_rst_i)
- enable <= 1'b0;
- else
- if (|dl & ~(|dlc)) // dl>0 & dlc==0
- enable <= 1'b1;
- else
- enable <= 1'b0;
-end
-
-// Delaying THRE status for one character cycle after a character is written to an empty fifo.
-always @(lcr)
- case (lcr[3:0])
- 4'b0000 : block_value = 95; // 6 bits
- 4'b0100 : block_value = 103; // 6.5 bits
- 4'b0001, 4'b1000 : block_value = 111; // 7 bits
- 4'b1100 : block_value = 119; // 7.5 bits
- 4'b0010, 4'b0101, 4'b1001 : block_value = 127; // 8 bits
- 4'b0011, 4'b0110, 4'b1010, 4'b1101 : block_value = 143; // 9 bits
- 4'b0111, 4'b1011, 4'b1110 : block_value = 159; // 10 bits
- 4'b1111 : block_value = 175; // 11 bits
- endcase // case(lcr[3:0])
-
-// Counting time of one character minus stop bit
-always @(posedge clk or posedge wb_rst_i)
-begin
- if (wb_rst_i)
- block_cnt <= 8'd0;
- else
- if(lsr5r & fifo_write) // THRE bit set & write to fifo occured
- block_cnt <= block_value;
- else
- if (enable & block_cnt != 8'b0) // only work on enable times
- block_cnt <= block_cnt - 1; // decrement break counter
-end // always of break condition detection
-
-// Generating THRE status enable signal
-assign thre_set_en = ~(|block_cnt);
-
-
-//
-// INTERRUPT LOGIC
-//
-
-assign rls_int = ier[`UART_IE_RLS] && (lsr[`UART_LS_OE] || lsr[`UART_LS_PE] || lsr[`UART_LS_FE] || lsr[`UART_LS_BI]);
-assign rda_int = ier[`UART_IE_RDA] && (rf_count >= {1'b0,trigger_level});
-assign thre_int = ier[`UART_IE_THRE] && lsr[`UART_LS_TFE];
-assign ms_int = ier[`UART_IE_MS] && (| msr[3:0]);
-assign ti_int = ier[`UART_IE_RDA] && (counter_t == 10'b0) && (|rf_count);
-
-reg rls_int_d;
-reg thre_int_d;
-reg ms_int_d;
-reg ti_int_d;
-reg rda_int_d;
-
-// delay lines
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) rls_int_d <= 0;
- else rls_int_d <= rls_int;
-
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) rda_int_d <= 0;
- else rda_int_d <= rda_int;
-
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) thre_int_d <= 0;
- else thre_int_d <= thre_int;
-
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) ms_int_d <= 0;
- else ms_int_d <= ms_int;
-
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) ti_int_d <= 0;
- else ti_int_d <= ti_int;
-
-// rise detection signals
-
-wire rls_int_rise;
-wire thre_int_rise;
-wire ms_int_rise;
-wire ti_int_rise;
-wire rda_int_rise;
-
-assign rda_int_rise = rda_int & ~rda_int_d;
-assign rls_int_rise = rls_int & ~rls_int_d;
-assign thre_int_rise = thre_int & ~thre_int_d;
-assign ms_int_rise = ms_int & ~ms_int_d;
-assign ti_int_rise = ti_int & ~ti_int_d;
-
-// interrupt pending flags
-reg rls_int_pnd;
-reg rda_int_pnd;
-reg thre_int_pnd;
-reg ms_int_pnd;
-reg ti_int_pnd;
-
-// interrupt pending flags assignments
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) rls_int_pnd <= 0;
- else
- rls_int_pnd <= lsr_mask ? 0 : // reset condition
- rls_int_rise ? 1 : // latch condition
- rls_int_pnd && ier[`UART_IE_RLS]; // default operation: remove if masked
-
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) rda_int_pnd <= 0;
- else
- rda_int_pnd <= ((rf_count == {1'b0,trigger_level}) && fifo_read) ? 0 : // reset condition
- rda_int_rise ? 1 : // latch condition
- rda_int_pnd && ier[`UART_IE_RDA]; // default operation: remove if masked
-
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) thre_int_pnd <= 0;
- else
- thre_int_pnd <= fifo_write || (iir_read & ~iir[`UART_II_IP] & iir[`UART_II_II] == `UART_II_THRE)? 0 :
- thre_int_rise ? 1 :
- thre_int_pnd && ier[`UART_IE_THRE];
-
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) ms_int_pnd <= 0;
- else
- ms_int_pnd <= msr_read ? 0 :
- ms_int_rise ? 1 :
- ms_int_pnd && ier[`UART_IE_MS];
-
-always @(posedge clk or posedge wb_rst_i)
- if (wb_rst_i) ti_int_pnd <= 0;
- else
- ti_int_pnd <= fifo_read ? 0 :
- ti_int_rise ? 1 :
- ti_int_pnd && ier[`UART_IE_RDA];
-// end of pending flags
-
-// INT_O logic
-always @(posedge clk or posedge wb_rst_i)
-begin
- if (wb_rst_i)
- int_o <= 1'b0;
- else
- int_o <=
- rls_int_pnd ? ~lsr_mask :
- rda_int_pnd ? 1 :
- ti_int_pnd ? ~fifo_read :
- thre_int_pnd ? !(fifo_write & iir_read) :
- ms_int_pnd ? ~msr_read :
- 0; // if no interrupt are pending
-end
-
-
-// Interrupt Identification register
-always @(posedge clk or posedge wb_rst_i)
-begin
- if (wb_rst_i)
- iir <= 1;
- else
- if (rls_int_pnd) // interrupt is pending
- begin
- iir[`UART_II_II] <= `UART_II_RLS; // set identification register to correct value
- iir[`UART_II_IP] <= 1'b0; // and clear the IIR bit 0 (interrupt pending)
- end else // the sequence of conditions determines priority of interrupt identification
- if (rda_int)
- begin
- iir[`UART_II_II] <= `UART_II_RDA;
- iir[`UART_II_IP] <= 1'b0;
- end
- else if (ti_int_pnd)
- begin
- iir[`UART_II_II] <= `UART_II_TI;
- iir[`UART_II_IP] <= 1'b0;
- end
- else if (thre_int_pnd)
- begin
- iir[`UART_II_II] <= `UART_II_THRE;
- iir[`UART_II_IP] <= 1'b0;
- end
- else if (ms_int_pnd)
- begin
- iir[`UART_II_II] <= `UART_II_MS;
- iir[`UART_II_IP] <= 1'b0;
- end else // no interrupt is pending
- begin
- iir[`UART_II_II] <= 0;
- iir[`UART_II_IP] <= 1'b1;
- end
-end
-
-endmodule
Index: trunk/src/testbench/External_IP/uart16550/rtl/uart_top.v
===================================================================
--- trunk/src/testbench/External_IP/uart16550/rtl/uart_top.v (revision 57)
+++ trunk/src/testbench/External_IP/uart16550/rtl/uart_top.v (nonexistent)
@@ -1,338 +0,0 @@
-//////////////////////////////////////////////////////////////////////
-//// ////
-//// uart_top.v ////
-//// ////
-//// ////
-//// This file is part of the "UART 16550 compatible" project ////
-//// http://www.opencores.org/cores/uart16550/ ////
-//// ////
-//// Documentation related to this project: ////
-//// - http://www.opencores.org/cores/uart16550/ ////
-//// ////
-//// Projects compatibility: ////
-//// - WISHBONE ////
-//// RS232 Protocol ////
-//// 16550D uart (mostly supported) ////
-//// ////
-//// Overview (main Features): ////
-//// UART core top level. ////
-//// ////
-//// Known problems (limits): ////
-//// Note that transmitter and receiver instances are inside ////
-//// the uart_regs.v file. ////
-//// ////
-//// To Do: ////
-//// Nothing so far. ////
-//// ////
-//// Author(s): ////
-//// - gorban@opencores.org ////
-//// - Jacob Gorban ////
-//// - Igor Mohor (igorm@opencores.org) ////
-//// ////
-//// Created: 2001/05/12 ////
-//// Last Updated: 2001/05/17 ////
-//// (See log for the revision history) ////
-//// ////
-//// Modified for use in the ZAP project by Revanth Kamaraj ////
-//// ////
-//////////////////////////////////////////////////////////////////////
-//// ////
-//// Copyright (C) 2000, 2001 Authors ////
-//// ////
-//// This source file may be used and distributed without ////
-//// restriction provided that this copyright statement is not ////
-//// removed from the file and that any derivative work contains ////
-//// the original copyright notice and the associated disclaimer. ////
-//// ////
-//// This source file is free software; you can redistribute it ////
-//// and/or modify it under the terms of the GNU Lesser General ////
-//// Public License as published by the Free Software Foundation; ////
-//// either version 2.1 of the License, or (at your option) any ////
-//// later version. ////
-//// ////
-//// This source 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 Lesser General Public License for more ////
-//// details. ////
-//// ////
-//// You should have received a copy of the GNU Lesser General ////
-//// Public License along with this source; if not, download it ////
-//// from http://www.opencores.org/lgpl.shtml ////
-//// ////
-//////////////////////////////////////////////////////////////////////
-//
-// CVS Revision History
-//
-// $Log: not supported by cvs2svn $
-// Revision 1.18 2002/07/22 23:02:23 gorban
-// Bug Fixes:
-// * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
-// Problem reported by Kenny.Tung.
-// * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
-//
-// Improvements:
-// * Made FIFO's as general inferrable memory where possible.
-// So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
-// This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
-//
-// * Added optional baudrate output (baud_o).
-// This is identical to BAUDOUT* signal on 16550 chip.
-// It outputs 16xbit_clock_rate - the divided clock.
-// It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use.
-//
-// Revision 1.17 2001/12/19 08:40:03 mohor
-// Warnings fixed (unused signals removed).
-//
-// Revision 1.16 2001/12/06 14:51:04 gorban
-// Bug in LSR[0] is fixed.
-// All WISHBONE signals are now sampled, so another wait-state is introduced on all transfers.
-//
-// Revision 1.15 2001/12/03 21:44:29 gorban
-// Updated specification documentation.
-// Added full 32-bit data bus interface, now as default.
-// Address is 5-bit wide in 32-bit data bus mode.
-// Added wb_sel_i input to the core. It's used in the 32-bit mode.
-// Added debug interface with two 32-bit read-only registers in 32-bit mode.
-// Bits 5 and 6 of LSR are now only cleared on TX FIFO write.
-// My small test bench is modified to work with 32-bit mode.
-//
-// Revision 1.14 2001/11/07 17:51:52 gorban
-// Heavily rewritten interrupt and LSR subsystems.
-// Many bugs hopefully squashed.
-//
-// Revision 1.13 2001/10/20 09:58:40 gorban
-// Small synopsis fixes
-//
-// Revision 1.12 2001/08/25 15:46:19 gorban
-// Modified port names again
-//
-// Revision 1.11 2001/08/24 21:01:12 mohor
-// Things connected to parity changed.
-// Clock devider changed.
-//
-// Revision 1.10 2001/08/23 16:05:05 mohor
-// Stop bit bug fixed.
-// Parity bug fixed.
-// WISHBONE read cycle bug fixed,
-// OE indicator (Overrun Error) bug fixed.
-// PE indicator (Parity Error) bug fixed.
-// Register read bug fixed.
-//
-// Revision 1.4 2001/05/31 20:08:01 gorban
-// FIFO changes and other corrections.
-//
-// Revision 1.3 2001/05/21 19:12:02 gorban
-// Corrected some Linter messages.
-//
-// Revision 1.2 2001/05/17 18:34:18 gorban
-// First 'stable' release. Should be sythesizable now. Also added new header.
-//
-// Revision 1.0 2001-05-17 21:27:12+02 jacob
-// Initial revision
-//
-//
-
-`include "uart_defines.v"
-
-module uart_top (
- wb_clk_i,
-
- // Wishbone signals
- wb_rst_i, wb_adr_i, wb_dat_i, wb_dat_o, wb_we_i, wb_stb_i, wb_cyc_i, wb_ack_o, wb_sel_i,
- int_o, // interrupt request
-
- // UART signals
- // serial input/output
- stx_pad_o, srx_pad_i,
-
- // modem signals
- rts_pad_o, cts_pad_i, dtr_pad_o, dsr_pad_i, ri_pad_i, dcd_pad_i
-`ifdef UART_HAS_BAUDRATE_OUTPUT
- , baud_o
-`endif
- );
-
-parameter uart_data_width = `UART_DATA_WIDTH;
-parameter uart_addr_width = `UART_ADDR_WIDTH;
-
-input wb_clk_i;
-
-// WISHBONE interface
-input wb_rst_i;
-input [uart_addr_width-1:0] wb_adr_i;
-input [uart_data_width-1:0] wb_dat_i;
-output [uart_data_width-1:0] wb_dat_o;
-input wb_we_i;
-input wb_stb_i;
-input wb_cyc_i;
-input [3:0] wb_sel_i;
-output wb_ack_o;
-output int_o;
-
-// UART signals
-input srx_pad_i;
-output stx_pad_o;
-output rts_pad_o;
-input cts_pad_i;
-output dtr_pad_o;
-input dsr_pad_i;
-input ri_pad_i;
-input dcd_pad_i;
-
-// optional baudrate output
-`ifdef UART_HAS_BAUDRATE_OUTPUT
-output baud_o;
-`endif
-
-
-wire stx_pad_o;
-wire rts_pad_o;
-wire dtr_pad_o;
-
-wire [uart_addr_width-1:0] wb_adr_i;
-wire [uart_data_width-1:0] wb_dat_i;
-wire [uart_data_width-1:0] wb_dat_o;
-
-wire [7:0] wb_dat8_i; // 8-bit internal data input
-wire [7:0] wb_dat8_o; // 8-bit internal data output
-wire [31:0] wb_dat32_o; // debug interface 32-bit output
-wire [3:0] wb_sel_i; // WISHBONE select signal
-wire [uart_addr_width-1:0] wb_adr_int;
-wire we_o; // Write enable for registers
-wire re_o; // Read enable for registers
-//
-// MODULE INSTANCES
-//
-
-`ifdef DATA_BUS_WIDTH_8
-`else
-// debug interface wires
-wire [3:0] ier;
-wire [3:0] iir;
-wire [1:0] fcr;
-wire [4:0] mcr;
-wire [7:0] lcr;
-wire [7:0] msr;
-wire [7:0] lsr;
-wire [`UART_FIFO_COUNTER_W-1:0] rf_count;
-wire [`UART_FIFO_COUNTER_W-1:0] tf_count;
-wire [2:0] tstate;
-wire [3:0] rstate;
-`endif
-
-`ifdef DATA_BUS_WIDTH_8
-//// WISHBONE interface module
-uart_wb wb_interface(
- .clk( wb_clk_i ),
- .wb_rst_i( wb_rst_i ),
- .wb_dat_i(wb_dat_i),
- .wb_dat_o(wb_dat_o),
- .wb_dat8_i(wb_dat8_i),
- .wb_dat8_o(wb_dat8_o),
- .wb_dat32_o(32'b0),
- .wb_sel_i(4'b0),
- .wb_we_i( wb_we_i ),
- .wb_stb_i( wb_stb_i ),
- .wb_cyc_i( wb_cyc_i ),
- .wb_ack_o( wb_ack_o ),
- .wb_adr_i(wb_adr_i),
- .wb_adr_int(wb_adr_int),
- .we_o( we_o ),
- .re_o(re_o)
- );
-`else
-uart_wb wb_interface(
- .clk( wb_clk_i ),
- .wb_rst_i( wb_rst_i ),
- .wb_dat_i(wb_dat_i),
- .wb_dat_o(wb_dat_o),
- .wb_dat8_i(wb_dat8_i),
- .wb_dat8_o(wb_dat8_o),
- .wb_sel_i(wb_sel_i),
- .wb_dat32_o(wb_dat32_o),
- .wb_we_i( wb_we_i ),
- .wb_stb_i( wb_stb_i ),
- .wb_cyc_i( wb_cyc_i ),
- .wb_ack_o( wb_ack_o ),
- .wb_adr_i(wb_adr_i),
- .wb_adr_int(wb_adr_int),
- .we_o( we_o ),
- .re_o(re_o)
- );
-`endif
-
-// Registers
-uart_regs regs(
- .clk( wb_clk_i ),
- .wb_rst_i( wb_rst_i ),
- .wb_addr_i( wb_adr_int ),
- .wb_dat_i( wb_dat8_i ),
- .wb_dat_o( wb_dat8_o ),
- .wb_we_i( we_o ),
- .wb_re_i(re_o),
- .modem_inputs( {cts_pad_i, dsr_pad_i,
- ri_pad_i, dcd_pad_i} ),
- .stx_pad_o( stx_pad_o ),
- .srx_pad_i( srx_pad_i ),
-`ifdef DATA_BUS_WIDTH_8
-`else
-// debug interface signals enabled
-.ier(ier),
-.iir(iir),
-.fcr(fcr),
-.mcr(mcr),
-.lcr(lcr),
-.msr(msr),
-.lsr(lsr),
-.rf_count(rf_count),
-.tf_count(tf_count),
-.tstate(tstate),
-.rstate(rstate),
-`endif
- .rts_pad_o( rts_pad_o ),
- .dtr_pad_o( dtr_pad_o ),
- .int_o( int_o )
-`ifdef UART_HAS_BAUDRATE_OUTPUT
- , .baud_o(baud_o)
-`endif
-
-);
-
-`ifdef DATA_BUS_WIDTH_8
-`else
-uart_debug_if dbg(/*AUTOINST*/
- // Outputs
- .wb_dat32_o (wb_dat32_o[31:0]),
- // Inputs
- .wb_adr_i (wb_adr_int[`UART_ADDR_WIDTH-1:0]),
- .ier (ier[3:0]),
- .iir (iir[3:0]),
- .fcr (fcr[1:0]),
- .mcr (mcr[4:0]),
- .lcr (lcr[7:0]),
- .msr (msr[7:0]),
- .lsr (lsr[7:0]),
- .rf_count (rf_count[`UART_FIFO_COUNTER_W-1:0]),
- .tf_count (tf_count[`UART_FIFO_COUNTER_W-1:0]),
- .tstate (tstate[2:0]),
- .rstate (rstate[3:0]));
-`endif
-
-initial
-begin
- `ifdef DATA_BUS_WIDTH_8
- $display("(%m) UART INFO: Data bus width is 8. No Debug interface.\n");
- `else
- $display("(%m) UART INFO: Data bus width is 32. Debug Interface present.\n");
- `endif
- `ifdef UART_HAS_BAUDRATE_OUTPUT
- $display("(%m) UART INFO: Has baudrate output\n");
- `else
- $display("(%m) UART INFO: Doesn't have baudrate output\n");
- `endif
-end
-
-endmodule
-
-
Index: trunk/src/rtl/cpu/zap_wb_adapter.v
===================================================================
--- trunk/src/rtl/cpu/zap_wb_adapter.v (revision 57)
+++ 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: trunk/src/rtl/cpu/zap_shifter_main.v
===================================================================
--- trunk/src/rtl/cpu/zap_shifter_main.v (revision 57)
+++ 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: trunk/src/rtl/cpu/zap_writeback.v
===================================================================
--- trunk/src/rtl/cpu/zap_writeback.v (revision 57)
+++ 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: trunk/src/rtl/cpu/zap_cp15_cb.v
===================================================================
--- trunk/src/rtl/cpu/zap_cp15_cb.v (revision 57)
+++ 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: trunk/src/rtl/cpu/zap_tlb_check.v
===================================================================
--- trunk/src/rtl/cpu/zap_tlb_check.v (revision 57)
+++ 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: trunk/src/rtl/cpu/zap_functions.vh
===================================================================
--- trunk/src/rtl/cpu/zap_functions.vh (revision 57)
+++ 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: trunk/src/rtl/cpu/zap_decode.v
===================================================================
--- trunk/src/rtl/cpu/zap_decode.v (revision 57)
+++ 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: trunk/src/rtl/cpu/zap_register_file.v
===================================================================
--- trunk/src/rtl/cpu/zap_register_file.v (revision 57)
+++ 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: trunk/src/rtl/cpu/zap_alu_main.v
===================================================================
--- trunk/src/rtl/cpu/zap_alu_main.v (revision 57)
+++ 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: trunk/src/rtl/cpu/zap_tlb_fsm.v
===================================================================
--- trunk/src/rtl/cpu/zap_tlb_fsm.v (revision 57)
+++ 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: trunk/src/rtl/cpu/zap_core.v
===================================================================
--- trunk/src/rtl/cpu/zap_core.v (revision 57)
+++ 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: trunk/src/rtl/cpu/zap_ram_simple.v
===================================================================
--- trunk/src/rtl/cpu/zap_ram_simple.v (revision 57)
+++ 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 : 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: trunk/src/rtl/cpu/zap_predecode_coproc.v
===================================================================
--- trunk/src/rtl/cpu/zap_predecode_coproc.v (revision 57)
+++ 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: trunk/src/rtl/cpu/zap_decompile.v
===================================================================
--- trunk/src/rtl/cpu/zap_decompile.v (revision 57)
+++ 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: trunk/src/rtl/cpu/zap_shift_shifter.v
===================================================================
--- trunk/src/rtl/cpu/zap_shift_shifter.v (revision 57)
+++ 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: trunk/src/rtl/cpu/zap_top.v
===================================================================
--- trunk/src/rtl/cpu/zap_top.v (revision 57)
+++ 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: trunk/src/rtl/cpu/zap_shifter_multiply.v
===================================================================
--- trunk/src/rtl/cpu/zap_shifter_multiply.v (revision 57)
+++ 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: trunk/src/rtl/cpu/zap_thumb_decoder.v
===================================================================
--- trunk/src/rtl/cpu/zap_thumb_decoder.v (revision 57)
+++ 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: trunk/src/rtl/cpu/zap_predecode_compress.v
===================================================================
--- trunk/src/rtl/cpu/zap_predecode_compress.v (revision 57)
+++ 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: trunk/src/rtl/cpu/zap_cache_fsm.v
===================================================================
--- trunk/src/rtl/cpu/zap_cache_fsm.v (revision 57)
+++ 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: trunk/src/rtl/cpu/zap_wb_merger.v
===================================================================
--- trunk/src/rtl/cpu/zap_wb_merger.v (revision 57)
+++ 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: trunk/src/rtl/cpu/zap_memory_main.v
===================================================================
--- trunk/src/rtl/cpu/zap_memory_main.v (revision 57)
+++ 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: trunk/src/rtl/cpu/zap_sync_fifo.v
===================================================================
--- trunk/src/rtl/cpu/zap_sync_fifo.v (revision 57)
+++ 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: trunk/src/rtl/cpu/zap_tlb.v
===================================================================
--- trunk/src/rtl/cpu/zap_tlb.v (revision 57)
+++ 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: trunk/src/rtl/cpu/zap_fifo.v
===================================================================
--- trunk/src/rtl/cpu/zap_fifo.v (revision 57)
+++ 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: trunk/src/rtl/cpu/zap_defines.vh
===================================================================
--- trunk/src/rtl/cpu/zap_defines.vh (revision 57)
+++ 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: trunk/src/rtl/cpu/zap_decode_main.v
===================================================================
--- trunk/src/rtl/cpu/zap_decode_main.v (revision 57)
+++ 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: trunk/src/rtl/cpu/zap_cache_tag_ram.v
===================================================================
--- trunk/src/rtl/cpu/zap_cache_tag_ram.v (revision 57)
+++ trunk/src/rtl/cpu/zap_cache_tag_ram.v (nonexistent)
@@ -1,458 +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 tag RAM and data RAM unit. The tag RAM holds both the --
-// -- virtual tag and the physical address. The physical address is used to --
-// -- avoid translation during clean operations. The cache data RAM is also --
-// -- present in this unit. This unit has a dedicated memory interface --
-// -- because it can perform global clean and flush by itself without --
-// -- depending on the cache controller. Only for FPGA. --
-// -- --
-// -----------------------------------------------------------------------------
-
-`default_nettype none
-
-`include "zap_defines.vh"
-
-module zap_cache_tag_ram #(
-
-parameter CACHE_SIZE = 1024 // Bytes.
-
-)(
-
-input wire i_clk,
-input wire i_reset,
-input wire [31:0] i_address_nxt,
-input wire [31:0] i_address,
-input wire i_cache_en,
-input wire [127:0] i_cache_line,
-input wire [15:0] i_cache_line_ben,
-output reg [127:0] o_cache_line,
-input wire i_cache_tag_wr_en,
-input wire [`CACHE_TAG_WDT-1:0] i_cache_tag,
-input wire i_cache_tag_dirty,
-
-output reg [`CACHE_TAG_WDT-1:0] o_cache_tag,
-output reg o_cache_tag_valid,
-output reg o_cache_tag_dirty,
-input wire i_cache_clean_req,
-output reg o_cache_clean_done,
-input wire i_cache_inv_req,
-output reg o_cache_inv_done,
-
-/*
- * Cache clean operations occur through these ports.
- * 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 [31:0] i_wb_dat,
-input wire i_wb_ack
-
-);
-
-// ----------------------------------------------------------------------------
-
-`include "zap_localparams.vh"
-
-localparam NUMBER_OF_DIRTY_BLOCKS = ((CACHE_SIZE/16)/16); // Keep cache size > 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: trunk/src/rtl/cpu/zap_predecode_mem_fsm.v
===================================================================
--- trunk/src/rtl/cpu/zap_predecode_mem_fsm.v (revision 57)
+++ 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: trunk/src/rtl/cpu/zap_predecode_main.v
===================================================================
--- trunk/src/rtl/cpu/zap_predecode_main.v (revision 57)
+++ 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: trunk/src/rtl/cpu/zap_cache.v
===================================================================
--- trunk/src/rtl/cpu/zap_cache.v (revision 57)
+++ 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: trunk/src/rtl/cpu/zap_mem_inv_block.v
===================================================================
--- trunk/src/rtl/cpu/zap_mem_inv_block.v (revision 57)
+++ 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: trunk/src/rtl/cpu/zap_localparams.vh
===================================================================
--- trunk/src/rtl/cpu/zap_localparams.vh (revision 57)
+++ 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: trunk/src/ts/factorial/makefile
===================================================================
--- trunk/src/ts/factorial/makefile (revision 57)
+++ trunk/src/ts/factorial/makefile (nonexistent)
@@ -1,2 +0,0 @@
-# Call original makefile
-include ../../scripts/makefile
Index: trunk/src/ts/factorial/Description.txt
===================================================================
--- trunk/src/ts/factorial/Description.txt (revision 57)
+++ trunk/src/ts/factorial/Description.txt (nonexistent)
@@ -1,7 +0,0 @@
-This test mainly runs a program to find factorial of 5 and write
-the value 3.14 to a memory location. This setup uses the MMU but is set up for
-identity mapping using sections. IRQs are generated using the timer in the
-testbench. At the end an SWI is called which performs a bunch of multiplications
-and serial load/store. FIQs are enabled in testbench to be periodically generated
-every 256 clock cycles.
-
Index: trunk/src/ts/factorial/factorial.ld
===================================================================
--- trunk/src/ts/factorial/factorial.ld (revision 57)
+++ trunk/src/ts/factorial/factorial.ld (nonexistent)
@@ -1,16 +0,0 @@
-
-/* Linker Script */
-
-ENTRY(_Reset) /* _Reset is the entry point. This is the entry point in the bootstrap assembler */
-
-/* Define how sections of the program are organized. */
-SECTIONS
-{
- . = 0x00000; /* Location Counter. */
- .text : { *(.text) } /* Text section is expected to be starting at 0x0.*/
- .data : { *(.data) } /* Immediately followed by data section */
- .bss : { *(.bss) *(COMMON) } /* Immediately followed by BSS section. Common sections are also included in BSS. */
- . = ALIGN(8); /* Align the location counter. */
- . = . + 0x1000; /* 4kB of descending stack memory */
- stack_top = .; /* Make stack_top same as location counter. */
-}
Index: trunk/src/ts/factorial/Config.cfg
===================================================================
--- trunk/src/ts/factorial/Config.cfg (revision 57)
+++ trunk/src/ts/factorial/Config.cfg (nonexistent)
@@ -1,49 +0,0 @@
-# TC config.
-
-%Config = (
- # CPU configuration.
- DATA_CACHE_SIZE => 4096, # Data cache size in bytes
- CODE_CACHE_SIZE => 4096, # Instruction cache size in bytes
- CODE_SECTION_TLB_ENTRIES => 512, # Instruction section TLB entries.
- CODE_SPAGE_TLB_ENTRIES => 512, # Instruction small page TLB entries.
- CODE_LPAGE_TLB_ENTRIES => 512, # Instruction large page TLB entries.
- DATA_SECTION_TLB_ENTRIES => 512, # Data section TLB entries.
- DATA_SPAGE_TLB_ENTRIES => 512, # Data small page TLB entries.
- DATA_LPAGE_TLB_ENTRIES => 512, # Data large page TLB entries.
- BP_DEPTH => 1024, # Branch predictor depth.
- INSTR_FIFO_DEPTH => 4, # Instruction buffer depth.
- STORE_BUFFER_DEPTH => 16, # Store buffer depth.
- SYNTHESIS => 0, # 0 allows debug messages.
-
- # Testbench configuration.
- WAVES => 1,
- EXT_RAM_SIZE => 32768, # External RAM size.
- SEED => -1, # Seed. Use -1 to use random seed.
- DUMP_START => 2000, # Starting memory address from which to dump.
- DUMP_SIZE => 200, # Length of dump in bytes.
- MAX_CLOCK_CYCLES => 6500, # Clock cycles to run the simulation for.
- DEFINE_TLB_DEBUG => 0, # Make this 1 to define TLB_DEBUG. Useful for debugging the TLB.
- REG_CHECK => {}, # Registers to examine.
- FINAL_CHECK => {
- # Values of memory for test to succeed.
- # LOCATION => VALUE
- "32'd2000" => "32'h00007805",
- "32'd2004" => "32'h4048f5c3",
- "32'd2008" => "32'h00000001",
- "32'd2012" => "32'h00000000",
- "32'd2016" => "32'h00000001",
- "32'd2020" => "32'hfffffffe",
- "32'd2024" => "32'h00000001",
- "32'd2028" => "32'h00000001",
- "32'd2032" => "32'hfffffffe",
- "32'd2036" => "32'h00000001",
- "32'd2040" => "32'h00000000",
- "32'd2044" => "32'h00000001"
- }
-);
-
-##########################
-# #
-# END OF FILE #
-# #
-##########################
Index: trunk/src/ts/factorial/factorial.c
===================================================================
--- trunk/src/ts/factorial/factorial.c (revision 57)
+++ trunk/src/ts/factorial/factorial.c (nonexistent)
@@ -1,44 +0,0 @@
-/* Computes factorial and stores 3.14 in 2004 memory location. */
-
-void main (void)
-{
- char *x = (char *)2000;
- float *y = (float*) 2004;
- x[0] = 5;
- x[1] = fact(x[0]);
- *y = 3.14;
-}
-
-int fact (int x)
-{
- if ( x == 0 )
- return 1;
- else
- return x * fact(x-1);
-}
-
-////////////////// VECTORS /////////////////////////
-
-void __undef(void) {
- return;
-}
-
-void __swi (void) {
- return;
-}
-
-void __pabt (void) {
- return;
-}
-
-void __dabt (void) {
- return;
-}
-
-void __irq (void) {
- return;
-}
-
-void __fiq (void) {
- return;
-}
Index: trunk/src/ts/factorial/factorial.s
===================================================================
--- trunk/src/ts/factorial/factorial.s (revision 57)
+++ trunk/src/ts/factorial/factorial.s (nonexistent)
@@ -1,227 +0,0 @@
-//
-// Startup file for factorial.
-//
-
-.global _Reset
-
-// Set up an interrupt vector table.
-_Reset : b there
-_Undef : b UNDEF
-_Swi : b SWI
-_Pabt : b __pabt
-_Dabt : b __dabt
-reserved : b _Reset
-irq : b IRQ
-fiq : b FIQ
-
-UNDEF:
-
-// Undefined vector.
-// LR Points to next instruction.
-stmfa sp!, {r0-r12, r14}
-
-// Corrupt registers.
-mov r0, #1
-mov r1, #2
-mov r2, #3
-mov r3, #4
-mov r4, #5
-mov r5, #6
-mov r6, #7
-mov r7, #8
-mov r8, #9
-mov r9, #10
-mov r10, #12
-mov r11, #13
-mov r12, #14
-mov r14, #15
-
-// Restore them.
-ldmfa sp!, {r0-r12, pc}^
-
-// IRQ.
-IRQ:
-sub r14, r14, #4
-stmfd sp!, {r0-r12, r14}
-
-mov r0, #1
-mov r1, #2
-mov r2, #3
-mov r3, #4
-mov r4, #5
-mov r5, #6
-mov r6, #7
-mov r7, #8
-mov r8, #9
-mov r9, #10
-mov r10, #12
-mov r11, #13
-mov r12, #14
-mov r14, #15
-
-.set TIMER_BASE_ADDRESS, 0xFFFFFFC0
-
-# Restart timer
-ldr r0,=TIMER_BASE_ADDRESS // Timer base address.
-add r0, r0, #12
-mov r1, #1
-str r1, [r0] // Restart the timer.
-
-.set VIC_BASE_ADDRESS, 0xFFFFFFA0
-.set CLEAR_ALL_PENDING, 0xFFFFFFFF
-
-# Clear interrupt in VIC.
-ldr r0, =VIC_BASE_ADDRESS // VIC base address
-add r0, r0, #8
-ldr r1, =CLEAR_ALL_PENDING
-str r1, [r0] // Clear all interrupt pending status
-
-# Restore
-ldmfd sp!, {r0-r12, pc}^
-
-FIQ:
-# Return from FIQ after writing to FIQ registers - shouldn't affect other things.
-mov r8, #9
-mov r9, #10
-mov r10, #12
-mov r11, #13
-mov r12, #14
-subs pc, r14, #4
-
-SWI:
-.set SWI_SP_VALUE, 2500
-.set SWI_R11_VALUE, 2004
-ldr sp,=SWI_SP_VALUE
-ldr r11,=SWI_R11_VALUE
-mov r0, #12
-mov r1, #0
-mov r2, r0, lsr #32
-mov r3, r0, lsr r1
-mov r4, #-1
-mov r5, #-1
-muls r6, r5, r4
-umull r8, r7, r5, r4
-smull r10, r9, r5, r4
-mov r2, r10
-str r10, [r11, #4]!
-str r9, [r11, #4]!
-add r11, r11, #4
-str r8, [r11], #4
-str r7, [r11], #4
-str r6, [r11]
-stmib r11, {r6-r10}
-stmfd sp!, {r0-r12, r14}
-mrs r1, spsr
-orr r1, r1, #0x80
-msr spsr_c, r1
-mov r4, #0
-mcr p15, 0, r4, c7, c15, 0
-mov r4, #-1
-ldmfd sp!, {r0-r12, pc}^
-
-there:
-// Switch to IRQ mode.
-mrs r2, cpsr
-bic r2, r2, #31
-orr r2, r2, #18
-msr cpsr_c, r2
-
-.set IRQ_SP_VALUE, 3000
-ldr sp,=IRQ_SP_VALUE
-
-// Switch to UND mode.
-mrs r3, cpsr
-bic r3, r3, #31
-orr r3, r3, #27
-msr cpsr_c, r3
-mov r4, #1
-
-.set UND_SP_VALUE, 3500
-ldr sp, =UND_SP_VALUE
-
-// Enable interrupts (FIQ and IRQ).
-mrs r1, cpsr
-bic r1, r1, #0xC0
-msr cpsr_c, r1
-
-// Enable cache (Uses a single bit to enable both caches).
-.set ENABLE_CACHE_CP_WORD, 4100
-ldr r1, =ENABLE_CACHE_CP_WORD
-mcr p15, 0, r1, c1, c1, 0
-
-// Write out identitiy section mapping. Write 16KB to register 2.
-mov r1, #1
-mov r1, r1, lsl #14
-mcr p15, 0, r1, c2, c0, 1
-
-// Set domain access control to all 1s.
-mvn r1, #0
-mcr p15, 0, r1, c3, c0, 0
-
-// Set up a section desctiptor for identity mapping that is Cachaeable.
-mov r1, #1
-mov r1, r1, lsl #14 // 16KB
-mov r2, #14 // Cacheable identity descriptor.
-str r2, [r1] // Write identity section desctiptor to 16KB location.
-ldr r6, [r1] // R6 holds the descriptor.
-mov r7, r1 // R7 holds the address.
-
-// Set up a section descriptor for upper 1MB of virtual address space.
-// This is identity mapping. Uncacheable.
-mov r1, #1
-mov r1, r1, lsl #14 // 16KB. This is descriptor 0.
-
-// Go to descriptor 4095. This is the address BASE + (#DESC * 4).
-.set DESCRIPTOR_IO_SECTION_OFFSET, 16380 // 4095 x 4
-ldr r2,=DESCRIPTOR_IO_SECTION_OFFSET
-add r1, r1, r2
-
-// Prepare a descriptor. Descriptor = 0xFFF00002 (Uncacheable section descriptor).
-.set DESCRIPTOR_IO_SECTION, 0xFFF00002
-ldr r2 ,=DESCRIPTOR_IO_SECTION
-str r2, [r1]
-ldr r6, [r1]
-mov r7, r1
-
-// ENABLE MMU
-.set ENABLE_MMU_CP_WORD, 4101
-ldr r1, =ENABLE_MMU_CP_WORD
-mcr p15, 0, r1, c1, c1, 0
-
-// Switch mode.
-mrs r2, cpsr
-bic r2, r2, #31
-orr r2, r2, #16
-msr cpsr_c, r2
-
-.set USR_SP_VALUE, 4000
-ldr sp,=USR_SP_VALUE
-
-// Run main loop.
-
-// Program VIC to allow timer interrupts.
-ldr r0, =VIC_BASE_ADDRESS // VIC base address.
-add r0, r0, #4 // Move to INT_MASK
-mov r1, #0 // Prepare mask value
-str r1, [r0] // Unmask all interrupt sources.
-
-// Program timer peripheral to tick every 32 clock cycles.
-ldr r0 ,=TIMER_BASE_ADDRESS // Timer base address.
-mov r1 , #1
-str r1, [r0] // Enable timer
-add r0, r0, #4
-mov r1, #32
-str r1, [r0] // Program to 255 clocks.
-add r0, r0, #8
-mov r1, #0x1
-str r1, [r0] // Start the timer.
-
-// Call C code
-bl main
-
-// Do SWI 0x0
-swi #0x00
-
-// Loop forever
-here: b here
-
Index: trunk/src/ts/uart/Config.cfg
===================================================================
--- trunk/src/ts/uart/Config.cfg (revision 57)
+++ trunk/src/ts/uart/Config.cfg (nonexistent)
@@ -1,30 +0,0 @@
-# TC config.
-
-%Config = (
- # CPU configuration.
- DATA_CACHE_SIZE => 4096, # Data cache size in bytes
- CODE_CACHE_SIZE => 4096, # Instruction cache size in bytes
- CODE_SECTION_TLB_ENTRIES => 8, # Instruction section TLB entries.
- CODE_SPAGE_TLB_ENTRIES => 32, # Instruction small page TLB entries.
- CODE_LPAGE_TLB_ENTRIES => 16, # Instruction large page TLB entries.
- DATA_SECTION_TLB_ENTRIES => 8, # Data section TLB entries.
- DATA_SPAGE_TLB_ENTRIES => 32, # Data small page TLB entries.
- DATA_LPAGE_TLB_ENTRIES => 16, # Data large page TLB entries.
- BP_DEPTH => 1024, # Branch predictor depth.
- INSTR_FIFO_DEPTH => 4, # Instruction buffer depth.
- STORE_BUFFER_DEPTH => 16, # Store buffer depth.
- SYNTHESIS => 0, # 0 allows debug messages.
-
- # Testbench configuration.
- WAVES => 1, # Generate waveform.
- UART0_TX_TERMINAL => 1, # Show TX terminal.
- UART0_RX_TERMINAL => 1, # Show RX terminal.
- EXT_RAM_SIZE => 32768, # External RAM size.
- SEED => -1, # Seed. Use -1 to use random seed.
- DUMP_START => 2000, # Starting memory address from which to dump.
- DUMP_SIZE => 200, # Length of dump in bytes.
- MAX_CLOCK_CYCLES => 0, # Clock cycles to run the simulation for. 0 is forever.
- REG_CHECK => {}, # No registers to check.
- FINAL_CHECK => {} # No memory locations to check.
-);
-
Index: trunk/src/ts/uart/main.c
===================================================================
--- trunk/src/ts/uart/main.c (revision 57)
+++ trunk/src/ts/uart/main.c (nonexistent)
@@ -1,12 +0,0 @@
-#include "uart.h"
-
-int main(void)
-{
- // Just bringup the UART TX and RX - enable interrupts and exit.
- UARTInit();
- UARTWrite("TX testing...");
- UARTEnableRXInterrupt();
- return 0;
-}
-
-
Index: trunk/src/ts/uart/irq_handler.c
===================================================================
--- trunk/src/ts/uart/irq_handler.c (revision 57)
+++ trunk/src/ts/uart/irq_handler.c (nonexistent)
@@ -1,14 +0,0 @@
-#include "uart.h"
-
-void irq_handler ()
-{
- // Wait for space to be available.
- while ( !UARTTransmitEmpty() );
-
- // Write character
- UARTWriteByte ( UARTGetChar() );
-
- // Clear interrupt pending register in VIC.
- *VIC_INT_CLEAR = 0xffffffff;
-}
-
Index: trunk/src/ts/uart/uart.ld
===================================================================
--- trunk/src/ts/uart/uart.ld (revision 57)
+++ trunk/src/ts/uart/uart.ld (nonexistent)
@@ -1,16 +0,0 @@
-
-/* Linker Script */
-
-ENTRY(_Reset) /* _Reset is the entry point. This is the entry point in the bootstrap assembler */
-
-/* Define how sections of the program are organized. */
-SECTIONS
-{
- . = 0x00000; /* Location Counter. */
- .text : { *(.text) } /* Text section is expected to be starting at 0x0.*/
- .data : { *(.data) } /* Immediately followed by data section */
- .bss : { *(.bss) *(COMMON) } /* Immediately followed by BSS section. Common sections are also included in BSS. */
- . = ALIGN(8); /* Align the location counter. */
- . = . + 0x1000; /* 4kB of descending stack memory */
- stack_top = .; /* Make stack_top same as location counter. */
-}
Index: trunk/src/ts/uart/uart.c
===================================================================
--- trunk/src/ts/uart/uart.c (revision 57)
+++ trunk/src/ts/uart/uart.c (nonexistent)
@@ -1,76 +0,0 @@
-#include "uart.h"
-
-/* Sets up rate as 1 baud = 16 CPU clocks. Also resets TX and RX logic */
-void UARTInit()
-{
- // Set up frequency of operation. 1 bit time = 16 CPU clocks.
- *UART0_LCR = (*UART0_LCR) | (1 << 7);
- *UART0_DLAB1 = 1;
- *UART0_DLAB2 = 0;
- *UART0_LCR = (*UART0_LCR) & ~(1 << 7);
-
- // Enable TX and RX.
- UARTEnableTX();
- UARTEnableRX();
-}
-
-/* Write a string to the UART device. This is an open loop function. */
-void UARTWrite(char* s)
-{
- int len;
- int i;
-
- len = strlen(s);
-
- for(i=0;i 4096, # Data cache size in bytes
- CODE_CACHE_SIZE => 4096, # Instruction cache size in bytes
- CODE_SECTION_TLB_ENTRIES => 8, # Instruction section TLB entries.
- CODE_SPAGE_TLB_ENTRIES => 32, # Instruction small page TLB entries.
- CODE_LPAGE_TLB_ENTRIES => 16, # Instruction large page TLB entries.
- DATA_SECTION_TLB_ENTRIES => 8, # Data section TLB entries.
- DATA_SPAGE_TLB_ENTRIES => 32, # Data small page TLB entries.
- DATA_LPAGE_TLB_ENTRIES => 16, # Data large page TLB entries.
- BP_DEPTH => 1024, # Branch predictor depth.
- INSTR_FIFO_DEPTH => 4, # Instruction buffer depth.
- STORE_BUFFER_DEPTH => 16, # Store buffer depth.
- SYNTHESIS => 0, # 0 allows debug messages.
-
- # Testbench configuration.
- EXT_RAM_SIZE => 32768, # External RAM size.
- SEED => -1, # Seed. Use -1 to use random seed.
- DUMP_START => 2000, # Starting memory address from which to dump.
- DUMP_SIZE => 200, # Length of dump in bytes.
- MAX_CLOCK_CYCLES => 1000, # Clock cycles to run the simulation for.
- REG_CHECK => {
- "r0" => "32'hFFFFFFFF",
- "r1" => "32'd10",
- "r2" => "32'd10",
- "r3" => "32'd10",
- "r4" => "32'd10",
- "r5" => "32'd10",
- "r6" => "32'd10",
- "r7" => "32'd10"
- },
- FINAL_CHECK => {}
-);
-
Index: trunk/src/ts/thumb_test/main.c
===================================================================
--- trunk/src/ts/thumb_test/main.c (revision 57)
+++ trunk/src/ts/thumb_test/main.c (nonexistent)
@@ -1,4 +0,0 @@
-int main()
-{
- return 0;
-}
Index: trunk/src/ts/arm_test/arm_test.ld
===================================================================
--- trunk/src/ts/arm_test/arm_test.ld (revision 57)
+++ trunk/src/ts/arm_test/arm_test.ld (nonexistent)
@@ -1,16 +0,0 @@
-
-/* Linker Script */
-
-ENTRY(_Reset) /* _Reset is the entry point. This is the entry point in the bootstrap assembler */
-
-/* Define how sections of the program are organized. */
-SECTIONS
-{
- . = 0x00000; /* Location Counter. */
- .text : { *(.text) } /* Text section is expected to be starting at 0x0.*/
- .data : { *(.data) } /* Immediately followed by data section */
- .bss : { *(.bss) *(COMMON) } /* Immediately followed by BSS section. Common sections are also included in BSS. */
- . = ALIGN(8); /* Align the location counter. */
- . = . + 0x1000; /* 4kB of descending stack memory */
- stack_top = .; /* Make stack_top same as location counter. */
-}
Index: trunk/src/ts/arm_test/makefile
===================================================================
--- trunk/src/ts/arm_test/makefile (revision 57)
+++ trunk/src/ts/arm_test/makefile (nonexistent)
@@ -1,2 +0,0 @@
-# Execute the main Makefile.
-include ../../scripts/makefile
Index: trunk/src/ts/arm_test/arm_test.c
===================================================================
--- trunk/src/ts/arm_test/arm_test.c (revision 57)
+++ trunk/src/ts/arm_test/arm_test.c (nonexistent)
@@ -1,3 +0,0 @@
-void main() {
-
-}
Index: trunk/src/ts/arm_test/arm_test.s
===================================================================
--- trunk/src/ts/arm_test/arm_test.s (revision 57)
+++ trunk/src/ts/arm_test/arm_test.s (nonexistent)
@@ -1,1302 +0,0 @@
-@
-@
-@ This file is taken from the ARM4U CPU project.
-@
-@ This is a creation of the Laboratory of Processor Architecture
-@ of Ecole Polytechnique Fédérale de Lausanne ( http://lap.epfl.ch )
-@
-@ asm_test.s --- Test program which uses all the instruction set
-@ to be assembled with GCC assembler
-@
-@ Written By - Jonathan Masur and Xavier Jimenez (2013)
-@
-@ 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, 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.
-@
-@ In other words, you are welcome to use, share and improve this program.
-@ You are forbidden to forbid anyone else to use, share and improve
-@ what you give them. Help stamp out software-hoarding!
-@
-@ MODIFICATION --
-@ Modified by Revanth Kamaraj for the ZAP ARM processor. The original code
-@ attempts to change modes from USER mode itself, changed it to SYS mode.
-@ NOTE: When running this code, do not enable interrupts as service routines
-@ are not set up properly in this code.
-@
-@
-
- .text
- .global test_cond, test_fwd, test_bshift, test_logic, test_adder, test_bshift_reg, test_load
- .global test_store, test_byte, test_cpsr, test_mul, test_ldmstm, test_r15jumps, test_rti
-
-_Reset:
- bl test_cond
-fail1:
- teq r0, #0
- mov r1, #1
- bne fail1
-
- bl test_fwd
-fail2:
- teq r0, #0
- mov r1, #2
- bne fail2
-
- bl test_bshift
-fail3:
- teq r0, #0
- mov r1, #3
- bne fail3
-
- bl test_logic
-fail4:
- teq r0, #0
- mov r1, #4
- bne fail4
-
- bl test_adder
-fail5:
- teq r0, #0
- mov r1, #5
- bne fail5
-
- bl test_bshift_reg
-fail6:
- teq r0, #0
- mov r1, #6
- bne fail6
-
- bl test_load
-fail7:
- teq r0, #0
- mov r1, #7
- bne fail7
-
- bl test_store
-fail8:
- teq r0, #0
- mov r1, #8
- bne fail8
-
- bl test_byte
-fail9:
- teq r0, #0
- mov r1, #9
- bne fail9
-
- bl test_cpsr
-fail10:
- teq r0, #0
- mov r1, #10
- bne fail10
-
- bl test_mul
-fail11:
- teq r0, #0
- mov r1, #11
- bne fail11
-
- bl test_ldmstm
-fail12:
- teq r0, #0
- mov r1, #12
- bne fail12
-
- bl test_r15jumps
-fail13:
- teq r0, #0
- mov r12, #13
- bne fail13
-
- bl test_rti
-passed:
- mvn r0, #0
- mvn r1, #0
- mvn r2, #0
- mvn r3, #0
- mvn r4, #0
- mvn r5, #0
- mvn r6, #0
- mvn r7, #0
- mvn r8, #0
- mvn r9, #0
- mvn r10, #0
- mvn r11, #0
- mvn r12, #0
- mvn r13, #0
- mvn r14, #0
- b passed
-
- @test N and Z flags conditional execution
-test_cond:
- mov r0, #1
-
- @ test 1 - test that the Z flag is set properly, and N flag clear properly
- movs r5, #0
- bne fail
- bmi fail
- add r0, #1
-
- @test 2 - test that an instruction without 'S' does not affect the flags
- movs r5, #1
- mov r5, #0
- beq fail
- bmi fail
- add r0, #1
-
- @test 3 - test that the N flag is set properly
- movs r5, #-2
- mov r5, #0
- beq fail
- bpl fail
- add r0, #1
-
- @test4 - make sure conditional MOV are skipped, and that flags are not updated on a skipped instruction
- movs r5, #1
- movpls r5, #0 @valid
- movnes r5, #1 @invalid
- movmis r5, #2 @invalid
- bne fail
- cmp r5, #0
- bne fail
- add r0, #1
-
- @ test 5 - make sure instructions after a branch are skipped completely
- b .dummy
- movs r5, #-1
- movs r5, #-2
- movs r5, #-3
-.dummy:
- bne fail
- bmi fail
-
- @condition test passed
- mov r0, #0
-fail:
- bx lr
-
-test_fwd:
- mov r0, #1
-
- @test forwarding and register file for OPA
- mov r1, #1
- add r1, r1, #1
- add r1, r1, #1
- add r1, r1, #1
- add r1, r1, #1
- add r1, r1, #1
- cmp r1, #6
- bne fail
- add r0, #1
-
- @test forwarding priority for opb
- mov r1, #1
- mov r1, #2
- mov r1, #3
- mov r1, #4
- mov r1, #5
- cmp r1, #5
- bne fail
- add r0, #1
-
- @forwarding test passed
- mov r0, #0
- bx lr
-
-test_bshift:
- @test barrel shifter all modes (shift by literal const. only for now)
- mov r0, #1
-
- @test 1 - test LSL output
- movs r5, #0xf0000000
- mov r1, #0x0f
- mov r2, r1, lsl #28
- cmp r5, r2
- bne fail
- add r0, #1
-
- @test 2 - test ROR output
- mov r3, r1, ror #4
- cmp r5, r3
- bne fail
- add r0, #1
-
- @test 3 - test LSR output
- mov r4, r5, lsr #28
- cmp r4, r1
- bne fail
- add r0, #1
-
- @test 4 - test ASR output
- mov r1, #0x80000000
- mov r2, r1, asr #3
- cmp r5 ,r2
- bne fail
- add r0, #1
-
- @test 5 - test RRX output and carry
- mov r1, #1
- movs r1, r1, rrx
- bcc fail
- movs r1, r1, rrx
- beq fail
- bcs fail
- add r0, #1
-
- @test 6 - test carry output from rotated constant
- movs r5, #0xf0000000
- bcc fail
- movs r5, #0xf
- bcc fail
- movs r5, #0x100
- bcs fail
- add r0, #1
-
- @test 7 - test carry output from LSL
- mov r5, #0x1
- movs r5, r5, lsl #1
- bcs fail
- mov r5, #0x80000000
- movs r5, r5, lsl #1
- bcc fail
- add r0, #1
-
- @test 8 - test carry output from LSR
- mov r5, #2
- movs r5, r5, lsr #1
- bcs fail
- movs r5, r5, lsr #1
- bcc fail
- bne fail
- add r0, #1
-
- @test 9 - test carry output from ASR
- mvn r5, #0x01
- movs r5, r5, asr #1
- bcs fail
- movs r5, r5, asr #1
- bcc fail
- add r0, #1
-
- @test 10 - check for LSR #32 to behave correctly
- mov r1, #0xa5000000
- mvn r2, r1
- lsrs r3, r1, #32
- bcc fail
- lsrs r3, r2, #32
- bcs fail
- add r0, #1
-
- @test 11 - check for ASR #32 to behave correctly
- asrs r3, r1, #32
- bcc fail
- cmp r3, #-1
- bne fail
- asrs r3, r2, #32
- bcs fail
- bne fail
-
- @barrelshift test passed
- mov r0, #0
- bx lr
-
- @test logical operations
-test_logic:
- mov r0, #1
-
- @test 1 - NOT operation
- mov r5, #-1
- mvns r5, r5
- bne fail
- add r0, #1
-
- @test 2 - AND operation
- mov r5, #0xa0
- mov r1, #0x0b
- mov r2, #0xab
- mov r3, #0xba
-
- ands r4, r5, r1
- bne fail
- ands r4, r5, r2
- cmp r4, r5
- bne fail
- add r0, #1
-
- @test 3 - ORR and EOR operations
- orr r4, r5, r1
- eors r4, r2, r4
- bne fail
- orr r4, r1, r5
- teq r4, r2
- bne fail
- add r0, #1
-
- @test 4 - TST opcode
- tst r1, r5
- bne fail
- tst r4, r2
- beq fail
- add r0, #1
-
- @test 5 - BIC opcode
- bics r4, r2, r3
- cmp r4, #1
- bne fail
-
- @logical test passed
- mov r0, #0
- bx lr
-
- @test adder, substracter, C and V flags
-test_adder:
- mov r0, #1
-
- @test 1 - check for carry when adding
- mov r5, #0xf0000000
- mvn r1, r5 @0x0fffffff
- adds r2, r1, r5
- bcs fail
- bvs fail
-
- adds r2, #1
- bcc fail
- bvs fail
-
- adc r2, #120
- cmp r2, #121
- bne fail
- bvs fail
- add r0, #1
-
- @test 2 - check for overflow when adding
- mov r3, #0x8fffffff @two large negative numbers become positive
- adds r3, r5
- bvc fail
- bcc fail
- bmi fail
-
- mov r3, #0x10000000
- adds r3, r1 @r3 = 0x1fffffff
- bvs fail
- bcs fail
-
- adds r3, #0x60000001 @two large positive numbers become negative
- bvc fail
- bpl fail
-
- add r0, #1
-
- @test 3 - check for carry when substracting
- mov r5, #0x10000000
- subs r2, r5, r1
- bcc fail
- bvs fail
-
- subs r2, #1
- bcc fail
- bvs fail
-
- subs r2, #1
- bcs fail
- bvs fail
-
- add r0, #1
-
- @test 4 - check for overflow when substracting
- mov r3, #0x90000000
- subs r3, r5
- bvs fail
- bcc fail
-
- subs r3, #1 @substract a positive num from a large negative make the result positive
- bvc fail
- bcc fail
-
- @test 5 - check for carry when reverse substracting
- mov r3, #1
- rsbs r2, r1, r5
- bcc fail
- bvs fail
- rsbs r2, r3, r2
- bcc fail
- bvs fail
- rscs r2, r3, r2
- bcs fail
- bvs fail
-
- add r0, #1
-
- @test 6 - check for overflow when reverse substracting
- mov r2, #0x80000000
- mov r1, #-1
- rsbs r2, r1
- bvs fail
- bmi fail
- bcc fail
-
- mov r0, #0
- bx lr
-
-@test barrelshift with register controler rotates
-test_bshift_reg:
- mov r0, #1
-
- mov r1, #0
- mov r2, #7
- mov r3, #32
- mov r4, #33
- mov r5, #127
- mov r6, #256
- add r7, r6, #7
- mov r8, #0xff000000
-
- @test 1 LSL mode with register shift
- movs r9, r8, lsl r2
- bpl fail
- bcc fail
- @make sure lsl #0 does not affect carry
- movs r9, r2, lsl r1
- bcc fail
- @test using the same register twice
- mov r9, r2, lsl r2
- cmp r9, #0x380
- bne fail
-
- add r0, #1
-
- @test 2 - LSL mode with barrelshift > 31
- movs r9, r2, lsl r3
- bcc fail
- bne fail
- movs r9, r2, lsl r4
- bcs fail
- bne fail
- add r0, #1
-
- @test 3 - LSL mode with barrelshift >= 256 (only 8 bits used)
- movs r9, r2, lsl r6
- bcs fail
- cmp r9, #7
- bne fail
-
- mov r9, r2, lsl r7
- cmp r9, #0x380
- bne fail
-
- movs r9, r8, lsl r7
- bpl fail
- bcc fail
-
- add r0, #1
-
- @test 4 - LSR mode with register shift
- mov r2, #4
- add r7, r6, #4
-
- movs r9, r8, lsr r2
- bmi fail
- bcs fail
- @make sure lsr #0 does not affect carry
- movs r9, r2, lsr r1
- bcs fail
- cmp r9, #4
- bne fail
-
- movs r9, r8, lsr r2
- bcs fail
- cmp r9, #0xff00000
- bne fail
-
- add r0, #1
-
- @test 5 - LSR mode with barrelshift > 31
- movs r9, r8, lsr r3
- bcc fail
- bne fail
- movs r9, r8, lsr r4
- bcs fail
- bne fail
- add r0, #1
-
- @test 6 - LSR mode with barrelshift >= 256 (only 8 bits used)
- movs r9, r8, lsr r6
- bcs fail
- cmp r9, #0xff000000
- bne fail
-
- movs r9, r8, lsr r7
- cmp r9, #0xff00000
- bne fail
-
- mov r0, #0
- bx lr
-
-array:
- .word 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
-array2:
- .word 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
-
-test_load:
- mov r0, #1
-
- @ Test1 basic load operations
- ldr r1, .larray1
- ldr r2, .larray2
-
- ldr r3, [r1]
- teq r3, #0
- bne fail
-
- ldr r3, [r2]
- teq r3, #16
- bne fail
- add r0, #1
-
- @ Test 2 load operations with offsets
- ldr r3, [r2, #-60]
- teq r3, #1
- bne fail
-
- ldr r3, [r1, #20]
- teq r3, #5
- bne fail
- add r0, #1
-
- @ Test 3 - test positive register offset addressing
- mov r3, #124
-.lloop:
- ldr r4, [r1, r3]
- cmp r4, r3, lsr #2
- bne fail
- subs r3, #4
- bpl .lloop
- add r0, #1
-
- @ Test 4 - test negative register offset addressing
- mov r3, #64
-.lloop2:
- ldr r4, [r2, -r3]
- rsb r4, #0x10
- cmp r4, r3, lsr #2
- bne fail
- subs r3, #4
- bne .lloop2
- add r0, #1
-
- @ Test 5 - test positive register offset addressing with shift
- mov r3, #0
-.lloop3:
- ldr r4, [r1, r3, lsl #2]
- cmp r4, r3
- bne fail
- add r3, #1
- cmp r3, #32
- bne .lloop3
- add r0, #1
-
- @ Test 6 - test negative register offset addressing with shift
- mov r3, #0
-.lloop4:
- ldr r4, [r2, -r3, lsl #2]
- rsb r4, #0x10
- cmp r4, r3
- bne fail
- add r3, #1
- cmp r3, #16
- bne .lloop4
- add r0, #1
-
- @ Test 7 - test offset with pre-increment
- mov r3, #31
- mov r5, r1
-.lloop5:
- ldr r4, [r5, #4]!
- rsb r4, #32
- cmp r4, r3
- bne fail
- subs r3, #1
- bne .lloop5
- add r0, #1
-
- @ Test 8 - test offset with pre-degrement
- mov r3, #31
- add r5, r1, #128
-.lloop6:
- ldr r4, [r5, #-4]!
- cmp r4, r3
- bne fail
- subs r3, #1
- bpl .lloop6
- add r0, #1
-
- @ Test 9 - test offset with post-increment
- mov r3, #32
- mov r5, r1
-.lloop7:
- ldr r4, [r5], #4
- rsb r4, #32
- cmp r4, r3
- bne fail
- subs r3, #1
- bne .lloop7
- add r0, #1
-
- @ Test 10 - test offset with post-decrement
- mov r3, #31
- add r5, r1, #124
-.lloop8:
- ldr r4, [r5], #-4
- cmp r3, r4
- bne fail
- subs r3, #1
- bpl .lloop8
- add r0, #1
-
- @ Test 11 - test register post-increment with a negative value
- mov r6, #0xfffffff0
- mov r5, r2
- mov r3, #16
-.lloop9:
- ldr r4, [r5], r6, asr #2
- cmp r4, r3
- bne fail
- subs r3, #1
- bpl .lloop9
-
- mov r0, #0
- bx lr
-
-.larray1:
- .word array
-.larray2:
- .word array2
-
-test_store:
- mov r0, #1
-
- @ Test 1 - test basic store opperation
- ldr r1, .larray1
- mov r2, #0x24
- str r2, [r1]
- ldr r2, [r1]
- cmp r2, #0x24
- bne fail
- add r0, #1
-
- @ Test 2 - check for post-increment and pre-decrement writes
- mov r2, #0xab
- mov r3, #0xbc
- str r2, [r1, #4]! @ array[1] = 0xab
- str r3, [r1], #4 @ array[1] = 0xbc
- ldr r2, [r1, #-4]! @ read 0xbc
- ldr r3, [r1, #-4]! @ read 0x24
- cmp r3, #0x24
- bne fail
- cmp r2, #0xbc
- bne fail
- add r0, #1
-
- @ Test 3 - check for register post-increment addressing
- mov r2, #8
- mov r3, #20
- mov r4, r1
- str r2, [r4], r2
- str r3, [r4], r2
- sub r4, #16
- cmp r4, r1
- bne fail
- ldr r2, [r1]
- cmp r2, #8
- bne fail
- ldr r2, [r1, #8]
- cmp r2, #20
- bne fail
-
- mov r0, #0
- bx lr
-
- @ Tests byte loads and store
-test_byte:
- mov r0, #1
-
- @ test 1 - test store bytes
- ldr r1, .larray1
- mov r2, #8
-.bloop:
- strb r2, [r1], #1
- subs r2, #1
- bne .bloop
-
- ldr r2, .ref_words+4
- ldr r3, [r1, #-4]!
- cmp r2, r3
- bne fail
-
- ldr r2, .ref_words
- ldr r3, [r1, #-4]!
- cmp r2, r3
- bne fail
- add r0, #1
-
- @ test 2 - test load bytes
- mov r2, #8
-.bloop2:
- ldrb r3, [r1], #1
- cmp r3, r2
- bne fail
- subs r2, #1
- bne .bloop2
-
- mov r0, #0
- bx lr
-
-.ref_words:
- @ Table for ARMs who access bytes in a little-endian order
- .word 0x05060708, 0x01020304
-
- @ Table for ARMs who access bytes in a big-endian order
-@ .word 0x08070605, 0x04030201
-
- @ Good source for flags info :
- @ http://blogs.arm.com/software-enablement/206-condition-codes-1-condition-flags-and-codes/
-
-test_cpsr:
- @ Enter SYS mode.
- msr cpsr_c, #0x1f
- mov r0, #1
-
- @ Test 1 - in depth test for the condition flags
- mrs r1, cpsr
- and r1, #0x000000ff
- msr cpsr_flg, r1
- @ NZCV = {0000}
- bvs fail
- bcs fail
- beq fail
- bmi fail
- bhi fail @ bhi <-> bls
- blt fail @ blt <-> bge
- ble fail @ ble <-> bgt
-
- add r1, #0x10000000
- msr cpsr, r1
- @ NZCV = {0001}
- bvc fail
- bhi fail
- bge fail
- bgt fail
-
- add r1, #0x10000000
- msr cpsr, r1
- @ NZCV = {0010}
- bvs fail
- bcc fail
- bls fail
-
- add r1, #0x10000000
- msr cpsr, r1
- @ NZCV = {0011}
- bls fail
- bge fail
- bgt fail
-
- add r1, #0x10000000
- msr cpsr, r1
- @ NZCV = {0100}
- bne fail
- bhi fail
- bgt fail
-
- add r1, #0x10000000
- msr cpsr, r1
- @ NZCV = {0101}
- bgt fail
-
- add r1, #0x10000000
- msr cpsr, r1
- @ NZCV = {0110}
- bhi fail
-
- add r1, #0x20000000
- msr cpsr, r1
- @ NZCV = {1000}
- bpl fail
- bge fail
- bgt fail
-
- add r1, #0x10000000
- msr cpsr, r1
- @ NZCV = {1001}
- blt fail
-
- add r1, #0x30000000
- msr cpsr, r1
- @ NZCV = {1100}
- bgt fail
-
- add r0, #1
-
- @ Test 2 - test for the FIQ processor mode
- mov r1, r14 @ save our link register and stack pointer
- mov r2, r13
- mov r3, #30
- mov r4, #40
- mov r5, #50
- mov r6, #60
- mov r7, #70
- mov r8, #80
- mov r9, #90
- mov r10, #100
- mov r11, #110
- mov r12, #120
- mov r13, #130
- mov r14, #140
-
- msr cpsr, #0xd1 @ go into FIQ mode, disable all interrupts (F and I bits set)
- cmp r3, #30
- bne .fail
- mov r8, #8 @ overwrite fiq regs...
- mov r9, #9
- mov r10, #10
- mov r11, #11
- mov r12, #12
- mov r13, #13
- mov r14, #14
- mov r3, #3 @ also overwrite some user regs
- mov r4, #4
- mov r5, #5
- mov r6, #6
- mov r7, #7
- msr cpsr, #0x1f @ back to SYS mode
- cmp r3, #3 @ r3-7 should have been affected, but not r8-r14
- bne .fail
- cmp r4, #4
- bne .fail
- cmp r5, #5
- bne .fail
- cmp r6, #6
- bne .fail
- cmp r7, #7
- bne .fail
- cmp r8, #80
- bne .fail
- cmp r9, #90
- bne .fail
- cmp r10, #100
- bne .fail
- cmp r11, #110
- bne .fail
- cmp r12, #120
- bne .fail
- cmp r13, #130
- bne .fail
- cmp r14, #140
- bne .fail
- add r0, #1
-
-
- @ Test 3 - test for the SUP processor mode
- mov r12, #120
- mov r13, #130
- mov r14, #140
- msr cpsr, #0x13 @ enter SUP mode
- cmp r12, #120
- bne .fail
- mov r12, #12
- mov r13, #13
- mov r14, #14
- msr cpsr, #0x1f @ back into SYS mode
- cmp r12, #12
- bne .fail
- cmp r13, #130
- bne .fail
- cmp r14, #140
- bne .fail
- add r0, #1
-
- @ Test 4 - test for the UND processor mode
- mov r12, #120
- mov r13, #130
- mov r14, #140
- msr cpsr, #0x1b @ enter UND mode
- cmp r12, #120
- bne .fail
- mov r12, #12
- mov r13, #13
- mov r14, #14
- msr cpsr, #0x1f @ back into SYS mode
- cmp r12, #12
- bne .fail
- cmp r13, #130
- bne .fail
- cmp r14, #140
- bne .fail
- add r0, #1
-
- @ Test 5 - test for the IRQ processor mode
- mov r12, #120
- mov r13, #130
- mov r14, #140
- msr cpsr, #0x92 @ enter IRQ mode, IRQ disabled
- cmp r12, #120
- bne .fail
- mov r12, #12
- mov r13, #13
- mov r14, #14
- msr cpsr, #0x1f @ back into SYS mode
- cmp r12, #12
- bne .fail
- cmp r13, #130
- bne .fail
- cmp r14, #140
- bne .fail
-
- mov r0, #0
-
-.fail:
- msr cpsr, #0x1f @ back into SYS mode
- mov r13, r2
- bx r1 @ return
-
- @ Test multiplier and how it affects the flags
-test_mul:
- mov r0, #1
-
- @ Test 1 - MUL instruction
- mov r1, #0
- mov r2, #2
- mov r3, #3
- mul r4, r2, r3
- cmp r4, #6
- bne fail
- bmi fail
-
- muls r5, r1, r2
- bne fail
- bmi fail
-
- muls r4, r2
- cmp r4, #12
- bne fail
- bmi fail
-
-@ mul r3, r3, r4 @ no joke, verified to fail on a real ARM !
-@ cmp r4, #36
-@ bne fail
-
- mov r3, #-3 @ multiply positive * negative
- muls r5, r2, r3
- bpl fail
- cmp r5, #-6
- bne fail
-
- mov r2, #-2 @ multiply negative * negative
- muls r5, r2, r3
- bmi fail
- cmp r5, #6
- bne fail
- add r0, #1
-
- @ Test 2 - MLA instruction
- mov r1, #10
- mov r2, #2
- mov r3, #5
- mlas r4, r1, r2, r3 @ 2*10 + 5 = 25
- bmi fail
-@ bcs fail @ on a real ARM, C flag after MLA is unpredictable
- bvs fail
- cmp r4, #25
- bne fail
-
- mov r1, #-10
- mlas r4, r1, r2, r3 @ 2*-10 + 5 = -15
- bpl fail
- bvs fail
- cmp r4, #-15
- bne fail
-
- mov r3, #0x80000001 @ causes addition overflow
- mlas r4, r1, r2, r3
- bmi fail
-@ bvc fail @ on a real ARM, V flag is not updated ?
-
- mov r0, #0
- bx lr
-
- @ Test load multiple and store multiple instructions
-test_ldmstm:
- mov r0, #1
-
- @ Test 1 - STMIA
- mov r1, #1
- mov r2, #2
- mov r3, #3
- mov r4, #4
- ldr r5, .larray1
- mov r6, r5
-
- stmia r6!, {r1-r4}
- sub r6, r5
- cmp r6, #16
- bne fail
-
- ldr r6, [r5]
- cmp r6, #1
- bne fail
- ldr r6, [r5, #4]
- cmp r6, #2
- bne fail
- ldr r6, [r5, #8]
- cmp r6, #3
- bne fail
- ldr r6, [r5, #12]
- cmp r6, #4
- bne fail
- add r0, #1
-
- @ Test 2 - STMIB
- mov r6, r5
- stmib r6!, {r1-r3}
- sub r6, r5
- cmp r6, #12
- bne fail
-
- ldr r6, [r5, #4]
- cmp r6, #1
- bne fail
- ldr r6, [r5, #8]
- cmp r6, #2
- bne fail
- ldr r6, [r5, #12]
- cmp r6, #3
- bne fail
- add r0, #1
-
- @ Test 3 - STMDB
- add r6, r5, #12
- stmdb r6!, {r1-r3}
- cmp r6, r5
- bne fail
-
- ldr r6, [r5]
- cmp r6, #1
- bne fail
- ldr r6, [r5, #8]
- cmp r6, #3
- bne fail
- add r0, #1
-
- @ Test 4 - STMDA
- add r6, r5, #12
- stmda r6!, {r1-r3}
- cmp r6, r5
- bne fail
- ldr r6, [r5, #4]
- cmp r6, #1
- bne fail
- ldr r6, [r5, #12]
- cmp r6, #3
- bne fail
- add r0, #1
-
- @ Test 5 - LDMIA
- ldr r5, .larray2
- ldmia r5, {r1-r4}
- cmp r1, #16
- bne fail
- cmp r2, #17
- bne fail
- cmp r3, #18
- bne fail
- cmp r4, #19
- bne fail
- add r0, #1
-
- @ Test 6 - LDMIB
- ldmib r5!, {r1-r4}
- cmp r1, #17
- bne fail
- cmp r2, #18
- bne fail
- cmp r3, #19
- bne fail
- cmp r4, #20
- bne fail
- add r0, #1
-
- @ Test 7 - LDMDB
- ldmdb r5!, {r1-r3}
- cmp r3, #19
- bne fail
- cmp r2, #18
- bne fail
- cmp r1, #17
- bne fail
- add r0, #1
-
- @ Test 8 - LDMDA
- ldmda r5, {r1-r2}
- cmp r1, #16
- bne fail
- cmp r2, #17
- bne fail
-
- mov r0, #0
- bx lr
-
- @ Test proper jumping on instructions that affect R15
-test_r15jumps:
- mov r0, #1
-
- @ Test 1 - a standard, conditional jump instruction
- ldr r3, .llabels
- mov r1, #0
- movs r2, #0
- moveq r15, r3 @ jump to label 1
- movs r2, #12
- movs r1, #13 @ make sure fetched/decoded instructions do no execute
-.label1:
- bne fail
- cmp r1, #0
- bne fail
- cmp r2, #0
- bne fail
- add r0, #1
-
- @ Test 2 - a jump instruction is not executed
- ldr r3, .llabels+4
- movs r2, #12
- moveq r15, r3
- movs r2, #0
-.label2:
- cmp r2, #0
- bne fail
- add r0, #1
-
- @ Test 3 - add instruction to calculate new address
- ldr r3, .llabels+8
- movs r1, #0
- movs r2, #0
- add r15, r3, #8 @go 2 instructions after label 3
-.label3:
- movs r1, #12
- movs r2, #13
- bne fail @ program executions continues here
- bne fail
- add r0, #1
-
- @ Test 4 - use an addition directly from PC+8 (r15)
- movs r2, #0
- movs r1, #0
- add r15, r15, #4 @ Skip 2 instructions This could actually be used for a nice jump table if a register were used instead of #4
- movs r1, #1
- movs r2, #2
- bne fail
- bne fail
- add r0, #1
-
- @ Test 5 - load r15 directly from memory
- movs r1, #1
- movs r2, #2
- ldrne r15, .llabels+12 @ Makes sure code after a ldr r15 is not executed
- movs r1, #0
- movs r2, #0
-.label4:
- beq fail
- beq fail
-
- ldreq r15, .llabels+16 @ Makes sure everything is right when a ldr r15 is not taken
- movs r2, #-2
-.label5:
- bpl fail
- cmp r2, #-2
- bne fail
- add r0, #1
-
- @ Test 6 - load r15 as the last step of a LDM instruction
- ldr r3, .llabels + 6*4
- movs r1, #0
- movs r2, #0
- ldmia r3, {r4-r8, r15} @jump to label6
- movs r1, #4
- movs r2, #2
-.label6:
- bne fail
- bne fail
-
- mov r0, #0
- bx lr
-
-.align 8
-.llabels:
- .word .label1, .label2, .label3, .label4, .label5, .label6, .llabels
-
-test_rti:
- mov r0, #1
- mov r12, #14
-
- @ Test 1 - test normal RTI
- msr cpsr, #0xd1 @ enter into FIQ mode (interrupt disabled)
- msr spsr, #0x4000001f @ emulate a saved CPSR in SYS mode, with NZCV = {0100}
-
- movs r8, #-12 @ now the FIQ sets it's CPSR to NZCV = {1000}
- ldr r8, .rtilabels @ simulate an interrupt return
- movs r15, r8 @ return from interrupt and move SPSR to CPSR
-
-.rtilabel1:
- mov r12, #1000
- bmi .rtifail @ ?!? WTF !?!
- bne .rtifail
- mov r12, #2000
- add r0, #1
-
- @ Test 2 - test LDM instruction with S flag
- msr cpsr, #0xd1
- ldr r8, .rtilabels + 20
- ldmib r8!, {r9, r10} @ fiq_r9 = 1, fiq_r10 = 2
- ldmib r8, {r9, r10}^ @ r8 = 3, r9 = 4 ( ^ => load to user registers )
- cmp r9, #1
- bne .rtifail
- cmp r10, #2
- bne .rtifail
- msr cpsr, #0x1f
- cmp r9, #3
- bne .rtifail
- cmp r10, #4
- bne .rtifail
- add r0, #1
-
- mov r12, #4000
-
- @ Test 3 - test LDM instruction with S flag for returning from an interrupt
- msr cpsr, #0xd1 @ FIQ mode, NZCV = {0000}
- msr spsr, #0x80000010 @ saved is normal mode with NZCV = {1000}
-
- ldr r8, .rtilabels + 20
- add r8, #8
-
- movs r9, #0 @ NZCV = {0100}
- ldmib r8, {r9-r11, r15}^ @ This should return to user mode and restore CPSR to NZCV = {1000}
-
-.rtilabel2:
- bpl .rtifail
- beq .rtifail
- b passed
-
-.rtifail:
- msr cpsr, #0x10
- mov r12, #100
- b .rtifail
- bx lr
-
-
-.rtilabels:
- .word .rtilabel1, 1, 2, 3, 4, .rtilabels, .rtilabel2
Index: trunk/src/ts/arm_test/Description.txt
===================================================================
--- trunk/src/ts/arm_test/Description.txt (revision 57)
+++ trunk/src/ts/arm_test/Description.txt (nonexistent)
@@ -1,3 +0,0 @@
-This test is taken from the ARM4U CPU project. It is a comprehensive test
-and exercises a bunch of different ARM instructions. Interrupts must not
-be enabled during the test since handlers are not properly setup.
Index: trunk/src/ts/arm_test/Config.cfg
===================================================================
--- trunk/src/ts/arm_test/Config.cfg (revision 57)
+++ trunk/src/ts/arm_test/Config.cfg (nonexistent)
@@ -1,47 +0,0 @@
-# TC config.
-
-%Config = (
- # CPU configuration.
- DATA_CACHE_SIZE => 4096, # Data cache size in bytes
- CODE_CACHE_SIZE => 4096, # Instruction cache size in bytes
- CODE_SECTION_TLB_ENTRIES => 8, # Instruction section TLB entries.
- CODE_SPAGE_TLB_ENTRIES => 32, # Instruction small page TLB entries.
- CODE_LPAGE_TLB_ENTRIES => 16, # Instruction large page TLB entries.
- DATA_SECTION_TLB_ENTRIES => 8, # Data section TLB entries.
- DATA_SPAGE_TLB_ENTRIES => 32, # Data small page TLB entries.
- DATA_LPAGE_TLB_ENTRIES => 16, # Data large page TLB entries.
- BP_DEPTH => 1024, # Branch predictor depth.
- INSTR_FIFO_DEPTH => 4, # Instruction buffer depth.
- STORE_BUFFER_DEPTH => 16, # Store buffer depth.
- SYNTHESIS => 0, # 0 allows debug messages.
-
- # Testbench configuration.
- WAVES => 0, # Log VCD
- EXT_RAM_SIZE => 32768, # External RAM size.
- SEED => -1, # Seed. Use -1 to use random seed.
- DUMP_START => 2000, # Starting memory address from which to dump.
- DUMP_SIZE => 200, # Length of dump in bytes.
- MAX_CLOCK_CYCLES => 40000, # Clock cycles to run the simulation for.
- DEFINE_TLB_DEBUG => 0, # Make this 1 to define TLB_DEBUG. Useful for debugging the TLB.
- REG_CHECK => {
- # Value of registers(Post Translate) at the end of the test.
- # "r => Verilog_value"
- "r0" => "32'hFFFFFFFF",
- "r1" => "32'hFFFFFFFF",
- "r2" => "32'hFFFFFFFF",
- "r3" => "32'hFFFFFFFF",
- "r4" => "32'hFFFFFFFF",
- "r5" => "32'hFFFFFFFF",
- "r6" => "32'hFFFFFFFF",
- "r7" => "32'hFFFFFFFF",
- "r8" => "32'hFFFFFFFF",
- "r9" => "32'hFFFFFFFF",
- "r10" => "32'hFFFFFFFF",
- "r11" => "32'hFFFFFFFF",
- "r12" => "32'hFFFFFFFF",
- "r13" => "32'hFFFFFFFF",
- "r14" => "32'hFFFFFFFF"
- },
- FINAL_CHECK => {}
-);
-
Index: trunk/src/scripts/uart_input.bash
===================================================================
--- trunk/src/scripts/uart_input.bash (revision 57)
+++ trunk/src/scripts/uart_input.bash (nonexistent)
@@ -1,18 +0,0 @@
-#!/bin/bash
-
-##############################################
-# This file reads characters into a file. The
-# Verilog testbench then opens this file and
-# writes it to the UART RX character wise.
-#
-# Call this like:
-# bash uart_input.bash
-##############################################
-
-IFS=""
-
-while true
-do
- read -n1 -r -d "" char
- echo -n "$char" >> "$1"
-done
Index: trunk/src/scripts/run_sim.pl
===================================================================
--- trunk/src/scripts/run_sim.pl (revision 57)
+++ trunk/src/scripts/run_sim.pl (nonexistent)
@@ -1,220 +0,0 @@
-#!/usr/bin/perl -w
-
-# -----------------------------------------------------------------------------
-# -- --
-# -- (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. --
-# -- --
-# -----------------------------------------------------------------------------
-
-
-use strict;
-use warnings;
-
-my %Config = do "./Config.cfg";
-
-# Extract from config
-my $WAVES = $Config{'WAVES'};
-my $RAM_SIZE = $Config{'EXT_RAM_SIZE'};
-my $SEED = $Config{'SEED'};
-my $SYNTHESIS = $Config{'SYNTHESIS'};
-my $DUMP_START = $Config{'DUMP_START'};
-my $DUMP_SIZE = $Config{'DUMP_SIZE'};
-my $MAX_CLOCK_CYCLES = $Config{'MAX_CLOCK_CYCLES'};
-my $TLB_DEBUG = $Config{'DEFINE_TLB_DEBUG'};
-my $TX_TERM0 = $Config{'UART0_TX_TERMINAL'};
-my $TX_TERM1 = $Config{'UART1_TX_TERMINAL'};
-my $RX_TERM0 = $Config{'UART0_RX_TERMINAL'};
-my $RX_TERM1 = $Config{'UART1_RX_TERMINAL'};
-my $IRQ_EN = $Config{'IRQ_EN'};
-my $FIQ_EN = $Config{'FIQ_EN'};
-my $DATA_CACHE_SIZE = $Config{'DATA_CACHE_SIZE'};
-my $CODE_CACHE_SIZE = $Config{'CODE_CACHE_SIZE'};
-my $CODE_SECTION_TLB_ENTRIES = $Config{'CODE_SECTION_TLB_ENTRIES'};
-my $CODE_SPAGE_TLB_ENTRIES = $Config{'CODE_SPAGE_TLB_ENTRIES'};
-my $CODE_LPAGE_TLB_ENTRIES = $Config{'CODE_LPAGE_TLB_ENTRIES'};
-my $DATA_SECTION_TLB_ENTRIES = $Config{'DATA_SECTION_TLB_ENTRIES'};
-my $DATA_SPAGE_TLB_ENTRIES = $Config{'DATA_SPAGE_TLB_ENTRIES'};
-my $DATA_LPAGE_TLB_ENTRIES = $Config{'DATA_LPAGE_TLB_ENTRIES'};
-my $BP = $Config{'BP_DEPTH'};
-my $FIFO = $Config{'INSTR_FIFO_DEPTH'};
-my $SBUF_DEPTH = $Config{'STORE_BUFFER_DEPTH'};
-
-# Leave this as is.
-my $ZAP_HOME = "../../../";
-my $TEST = "null";
-my $SCRATCH = "/dev/null";
-
-# Generate a random seed if needed
-if ( $SEED == -1 ) {
- $SEED = int rand (0xffffffff);
-}
-
-# Parse arguments.
-foreach(@ARGV) {
- if (/^\+test\+(.*)/) {
- $SCRATCH = "$ZAP_HOME/obj/ts/$1"; $TEST = $1;
- } else {
- die "Unrecognized option to run_sim.pl\n";
- }
-}
-
-# Log file - the final file is compressed.
-my $LOG_FILE_PATH = "$SCRATCH/zap.log";
-my $COMPRESSED_LOG_FILE_PATH = "$SCRATCH/zap.log.gz";
-
-# VCD file - the final file is compressed.
-my $VCD_PATH = "$SCRATCH/zap.vcd";
-my $COMPRESSED_VCD_PATH = "$SCRATCH/zap.vcd.gz";
-
-# Paths
-my $VVP_PATH = "$SCRATCH/zap.vvp";
-my $PROG_PATH = "$SCRATCH/zap_mem.v";
-my $TARGET_BIN_PATH = "$SCRATCH/zap.bin";
-my $UART0_PATH_TX = "$SCRATCH/zapuart0.tx";
-my $UART1_PATH_TX = "$SCRATCH/zapuart1.tx";
-my $UART0_PATH_RX = "$SCRATCH/zapuart0.rx";
-my $UART1_PATH_RX = "$SCRATCH/zapuart1.rx";
-
-# Generate IVL options including VCD generation path.
-my $IVL_OPTIONS = "";
-
- # Compile CPU
- $IVL_OPTIONS .= " -I$ZAP_HOME/src/rtl/cpu -I$ZAP_HOME/obj/ts/$TEST ";
- $IVL_OPTIONS .= " $ZAP_HOME/src/rtl/cpu/*.v ";
-
- # Compile other TB components
- $IVL_OPTIONS .= " -I$ZAP_HOME/src/testbench/External_IP/uart16550/rtl ";
- $IVL_OPTIONS .= " $ZAP_HOME/src/testbench/External_IP/uart16550/rtl/*.v ";
- $IVL_OPTIONS .= " $ZAP_HOME/src/testbench/*.v ";
- $IVL_OPTIONS .= " -o $VVP_PATH -gstrict-ca-eval -Wall -g2001 -Winfloop -DSEED=$SEED -DMEMORY_IMAGE=\\\"$PROG_PATH\\\" ";
- $IVL_OPTIONS .= " -DVCD_FILE_PATH=\\\"$VCD_PATH\\\" ";
-
-# Generate UART related defines for both the UARTs.
-if ( $TX_TERM0 ) { $IVL_OPTIONS .= " -DUART0_FILE_PATH_TX=\\\"$UART0_PATH_TX\\\" "; } else { $IVL_OPTIONS .= " -DUART0_FILE_PATH_TX=\\\"/dev/null\\\" "; }
-if ( $TX_TERM1 ) { $IVL_OPTIONS .= " -DUART1_FILE_PATH_TX=\\\"$UART1_PATH_TX\\\" "; } else { $IVL_OPTIONS .= " -DUART1_FILE_PATH_TX=\\\"/dev/null\\\" "; }
-if ( $RX_TERM0 ) { $IVL_OPTIONS .= " -DUART0_FILE_PATH_RX=\\\"$UART0_PATH_RX\\\" "; } else { $IVL_OPTIONS .= " -DUART0_FILE_PATH_RX=\\\"/dev/null\\\" "; }
-if ( $RX_TERM1 ) { $IVL_OPTIONS .= " -DUART1_FILE_PATH_RX=\\\"$UART1_PATH_RX\\\" "; } else { $IVL_OPTIONS .= " -DUART1_FILE_PATH_RX=\\\"/dev/null\\\" "; }
-
-# CPU / TB configuration related parameters.
-$IVL_OPTIONS .= " -Pzap_test.RAM_SIZE=$RAM_SIZE -Pzap_test.START=$DUMP_START -Pzap_test.COUNT=$DUMP_SIZE -DLINUX -Pzap_test.STORE_BUFFER_DEPTH=$SBUF_DEPTH ";
-$IVL_OPTIONS .= " -Pzap_test.BP_ENTRIES=$BP -Pzap_test.FIFO_DEPTH=$FIFO ";
-$IVL_OPTIONS .= " -Pzap_test.DATA_SECTION_TLB_ENTRIES=$DATA_SECTION_TLB_ENTRIES ";
-$IVL_OPTIONS .= " -Pzap_test.DATA_LPAGE_TLB_ENTRIES=$DATA_LPAGE_TLB_ENTRIES -Pzap_test.DATA_SPAGE_TLB_ENTRIES=$DATA_SPAGE_TLB_ENTRIES -Pzap_test.DATA_CACHE_SIZE=$DATA_CACHE_SIZE ";
-$IVL_OPTIONS .= " -Pzap_test.CODE_SECTION_TLB_ENTRIES=$CODE_SECTION_TLB_ENTRIES -Pzap_test.CODE_LPAGE_TLB_ENTRIES=$CODE_LPAGE_TLB_ENTRIES -Pzap_test.CODE_SPAGE_TLB_ENTRIES=$CODE_SPAGE_TLB_ENTRIES ";
-$IVL_OPTIONS .= " -Pzap_test.CODE_CACHE_SIZE=$CODE_CACHE_SIZE ";
-
-# Defines
-if ( 1 ) { $IVL_OPTIONS .= " -DMAX_CLOCK_CYCLES=$MAX_CLOCK_CYCLES " }
-if ( $IRQ_EN ) { $IVL_OPTIONS .= "-DIRQ_EN "; }
-if ( $FIQ_EN ) { $IVL_OPTIONS .= "-DFIQ_EN "; }
-if ( $SYNTHESIS ) { $IVL_OPTIONS .= "-DSYNTHESIS "; }
-if ( $TLB_DEBUG ) { $IVL_OPTIONS .= "-DTLB_DEBUG "; }
-if ( $WAVES ) { $IVL_OPTIONS .= "-DWAVES "; }
-
-###########################################################################################################################################
-# Create checker assertion verilog include file.
-###########################################################################################################################################
-
-open(HH, ">$ZAP_HOME/obj/ts/$TEST/zap_check.vh") or die "Could not write to ../../../obj/ts/$TEST/zap_check.vh";
-
-my $REG_HIER = "u_chip_top.u_zap_top.u_zap_core.u_zap_writeback.u_zap_register_file";
-my $RAM_HIER = "u_chip_top.u_ram.ram";
-my $X = $Config{'FINAL_CHECK'};
-
-foreach(keys (%$X)) {
- my $string = "$_, $$X{$_}, ${RAM_HIER}[$_/4]";
- print "if ( ${RAM_HIER}[$_/4] != ", $$X{"$_"}, ') begin $display("Error: Memory values not matched. PTR = %d EXP = %x REC = %x", ', $string , ' ); $finish; end else $display("RAM check passed!");',"\n";
- print HH "if ( ${RAM_HIER}[$_/4] != ", $$X{"$_"}, ') begin $display("Error: Memory values not matched. PTR = %d EXP = %x REC = %x", ', $string , ' ); $finish; end else $display("RAM check passed!");',"\n";
-}
-
-$X = $Config{'REG_CHECK'};
-
-foreach(keys (%$X)) {
- my $string = "\"$_\", $$X{$_}, $REG_HIER.$_";
- print "if ( $REG_HIER.$_ != ", $$X{"$_"}, ') begin $display("Error: Register values not matched. PTR = %s EXP = %x REC = %x", ', $string , ' ); $finish; end else $display("Reg check passed!");',"\n";
- print HH "if ( $REG_HIER.$_ != ", $$X{"$_"}, ') begin $display("Error: Register values not matched. PTR = %s EXP = %x REC = %x", ', $string , ' ); $finish; end else $display("Reg check passed!");',"\n";
-}
-
-print HH '$display("Simulation Complete. All checks (if any) passed.");$finish;';
-
-############################################################################################################################################
-# Set up UART terminals
-############################################################################################################################################
-
-if ( $TX_TERM0 ) {
- system1("rm -f $UART0_PATH_TX"); # Remove UART file.
- system1("mknod $UART0_PATH_TX p"); # Create a UART output FIFO file.
-}
-
-if ( $TX_TERM1 ) {
- system1("rm -f $UART1_PATH_TX"); # Remove UART file.
- system1("mknod $UART1_PATH_TX p"); # Create a UART output FIFO file.
-}
-
-if ( $RX_TERM0 ) {
- system1("rm -f $UART0_PATH_RX"); # Remove UART file.
- system1("touch $UART0_PATH_RX"); # Create file.
-}
-
-if ( $RX_TERM1 ) {
- system1("rm -f $UART1_PATH_RX"); # Remove UART file.
- system1("touch $UART1_PATH_RX"); # Create file.
-}
-
-die "Error: XTerm could not be found!" if system("which xterm");
-
-if ( $TX_TERM0 ) { die "Failed to open UART TX terminal 0." if system1("xterm -T 'TB UART Output' -hold -e 'cat $UART0_PATH_TX' &"); }
-if ( $TX_TERM1 ) { die "Failed to open UART TX terminal 1." if system1("xterm -T 'TB UART Output' -hold -e 'cat $UART1_PATH_TX' &"); }
-if ( $RX_TERM0 ) { die "Failed to open UART RX terminal 0." if system1("xterm -T 'TB UART Input' -hold -e 'bash $ZAP_HOME/src/scripts/uart_input.bash $UART0_PATH_RX' &"); }
-if ( $RX_TERM1 ) { die "Failed to open UART RX terminal 1." if system1("xterm -T 'TB UART Input' -hold -e 'bash $ZAP_HOME/src/scripts/uart_input.bash $UART1_PATH_RX' &"); }
-
-#############################################################################################################################################
-# Compile using VVP
-#############################################################################################################################################
-
-die "*E: Verilog Compilation Failed!\n" if system1("iverilog $IVL_OPTIONS");
-die "*E: Failed to read out Log FIFO!\n" if system1("rm -f $LOG_FILE_PATH ; mkfifo $LOG_FILE_PATH ; cat $LOG_FILE_PATH | gzip > $COMPRESSED_LOG_FILE_PATH &");
-
-if ( $WAVES ) {
- die "*E: Failed to read out VCD FIFO!\n" if system1("rm -f $VCD_PATH ; mkfifo $VCD_PATH ; cat $VCD_PATH | gzip > $COMPRESSED_VCD_PATH &");
-}
-
-die "*E: VVP execution error!\n" if system1("vvp $VVP_PATH | tee $LOG_FILE_PATH");
-
-###############################################################################################################################################
-# Scan for errors and warnings.
-###############################################################################################################################################
-
-die "*E: Errors occurred! Please grep for Errors in $COMPRESSED_LOG_FILE_PATH\n" unless system("zcat $COMPRESSED_LOG_FILE_PATH | grep Error");
-die "*E: There were Warnings! Please grep for Warnings in $COMPRESSED_LOG_FILE_PATH\n" unless system("zcat $COMPRESSED_LOG_FILE_PATH | grep Warning");
-
-###############################################################################################################################################
-# Functions
-###############################################################################################################################################
-
-sub system1 {
- my $x = $_[0];
- print "#SystemCommand: $x\n";
- system("$x");
-}
-
-exit 0;
-
-
Index: trunk/src/scripts/bin2vlog.pl
===================================================================
--- trunk/src/scripts/bin2vlog.pl (revision 57)
+++ trunk/src/scripts/bin2vlog.pl (nonexistent)
@@ -1,79 +0,0 @@
-#!/usr/bin/perl -w
-
-#// -----------------------------------------------------------------------------
-#// -- --
-#// -- (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. --
-#// -- --
-#// -----------------------------------------------------------------------------
-
-###############################################################################
-# Perl script to translate GCC generated binary files into Verilog memory
-# files.
-#
-# Usage: perl bin2vlog.pl
-###############################################################################
-
-use strict;
-use warnings;
-
-# Read command line arguments.
-my $bin_file = $ARGV[0];
-my $target_verilog_file = $ARGV[1];
-
-# Generate Verilog file.
-die "*E: Verilog file creation error...\n" if
- system("rm -f $target_verilog_file ; touch $target_verilog_file");
-
-# Open the binary and Verilog file using different file handles.
-open(my $fh, "<$bin_file") or die
- "Bin file $ARGV[0] could not be opened for reading...!\n";
-
-open(GH, ">$target_verilog_file") or die
- "Target verilog file could not be opened for writing...\n";
-
-# Read file in binary mode.
-binmode $fh;
-
-# Memory pointer.
-my $counter = 0;
-
-#
-# As long as there are bytes to read from the binary file, we will write out
-# those bytes. The ord function returns to numeric value of the byte from 0
-# to 255 corresponding to bytes 8'b0000_0000 to 8'b1111_1111.
-#
-while (read($fh, my $buf, 1) == 1) { # Get a byte from the file.
-
- # Print the numeric value of the byte.
- my $line = sprintf("mem[$counter] = 8'h%x;\n", ord $buf);
-
- # Print to the Verilog file.
- print GH $line;
-
- # Increment memory pointer by 1 since we are dealing with bytes.
- $counter++;
-}
-
-# Close both the files.
-close($fh);
-close(GH);
-
-print "Done...\n";
-exit 0;
Index: trunk/src/scripts/makefile
===================================================================
--- trunk/src/scripts/makefile (revision 57)
+++ trunk/src/scripts/makefile (nonexistent)
@@ -1,99 +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 common makefile to be used for all #
-# testcases. Note that all paths are relative #
-# to the testcase directory. Do a make c2asm #
-# if you need the assembly version of C files. #
-# #
-##################################################
-
-.DEFAULT_GOAL = all
-
-.PHONY: clean
-.PHONY: c2asm
-.PHONY: compiler
-.PHONY: dirs
-
-ARCH := armv5t
-TC := $(shell basename `pwd`)
-SCRIPT_PATH := ../../scripts/
-C_FILES := $(wildcard *.c)
-S_FILES := $(wildcard *.s)
-H_FILES := $(wildcard *.h)
-LD_FILE := $(wildcard *.ld)
-COBJFILES := $(patsubst %.c,../../../obj/ts/$(TC)/%_c.o,$(C_FILES))
-AOBJFILES := $(patsubst %.s,../../../obj/ts/$(TC)/%_s.o,$(S_FILES))
-CFLAGS := -c -msoft-float -mfloat-abi=soft -march=$(ARCH) -g
-SFLAGS := -march=$(ARCH) -g
-LFLAGS := -T
-OFLAGS := -O binary
-CC := arm-none-eabi-gcc
-AS := arm-none-eabi-as
-LD := arm-none-eabi-ld
-OB := arm-none-eabi-objcopy
-
-# This rule will convert every ASM to file its corresponding object file.
-../../../obj/ts/$(TC)/%_s.o: %.s
- $(AS) $(SFLAGS) $^ -o $@
-
-# This rule will convert every C file to its corresponding object file.
-../../../obj/ts/$(TC)/%_c.o: %.c $(H_FILES)
- $(CC) $(CFLAGS) $< -o $@
-
-# Rule to convert the object files to an ELF file.
-../../../obj/ts/$(TC)/$(TC).elf: $(LD_FILE) $(AOBJFILES) $(COBJFILES)
- $(LD) $(LFLAGS) $^ -o $@
-
-# Rule to generate a BIN file.
-../../../obj/ts/$(TC)/$(TC).bin: ../../../obj/ts/$(TC)/$(TC).elf
- $(OB) $(OFLAGS) $^ $@
-
-# Rule to convert the bin file to a Verilog image.
-../../../obj/ts/$(TC)/zap_mem.v: ../../../obj/ts/$(TC)/$(TC).bin
- perl $(SCRIPT_PATH)/bin2vlog.pl $< $@
-
-# Rule to run the simulation.
-all: dirs $(CC) ../../../obj/ts/$(TC)/zap_mem.v
- perl $(SCRIPT_PATH)/run_sim.pl +test+$(TC)
-
-$(CC):
-$(AS):
-$(LD):
-$(OB):
-
-dirs:
- mkdir -p ../../../obj/ts/$(TC)/
- touch ../../../obj/ts/$(TC)/
-
-clean:
- mkdir -p ../../../obj/ts/$(TC)/
- rm -fv ../../../obj/ts/$(TC)/*
-
-c2asm:
- $(CC) -S $(CFLAGS) $(X) -o ../../../obj/ts/$(TC)/$(X).asm
-
-print-% : ; @echo $* = $($*)
-
Index: trunk/src/scripts/Config.cfg_template
===================================================================
--- trunk/src/scripts/Config.cfg_template (revision 57)
+++ trunk/src/scripts/Config.cfg_template (nonexistent)
@@ -1,58 +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. --
-#// -- --
-#// -----------------------------------------------------------------------------
-
-
-# Basic template for use in other TCs.
-
-%Config = (
- # CPU configuration.
- DATA_CACHE_SIZE => 4096, # Data cache size in bytes
- CODE_CACHE_SIZE => 4096, # Instruction cache size in bytes
- CODE_SECTION_TLB_ENTRIES => 8, # Instruction section TLB entries.
- CODE_SPAGE_TLB_ENTRIES => 32, # Instruction small page TLB entries.
- CODE_LPAGE_TLB_ENTRIES => 16, # Instruction large page TLB entries.
- DATA_SECTION_TLB_ENTRIES => 8, # Data section TLB entries.
- DATA_SPAGE_TLB_ENTRIES => 32, # Data small page TLB entries.
- DATA_LPAGE_TLB_ENTRIES => 16, # Data large page TLB entries.
- BP_DEPTH => 1024, # Branch predictor depth.
- INSTR_FIFO_DEPTH => 4, # Instruction buffer depth.
- STORE_BUFFER_DEPTH => 8, # Store buffer depth.
- SYNTHESIS => 1, # Make this to 1 to simulate compile from a synthesis perspective.
-
- # Testbench configuration.
- WAVES => 0, # 1 Enables wave logging.
- UART0_TX_TERMINAL => 1, # 1 Enables UART TX terminal 0. 0 disables it.
- UART1_TX_TERMINAL => 1, # 1 Enables UART TX terminal 1. 0 disables it.
- UART0_RX_TERMINAL => 1, # RX terminal 0. Characters typed go to UART RX.
- UART1_RX_TERMINAL => 1, # RX terminal 1. Characters typed go to UART RX.
- EXT_RAM_SIZE => 32768, # External RAM size.
- SEED => -1, # Seed. Use -1 to use random seed.
- DUMP_START => 2000, # Starting memory address from which to dump.
- DUMP_SIZE => 200, # Length of dump in bytes.
- MAX_CLOCK_CYCLES => 100000, # Clock cycles to run the simulation for.
- REG_CHECK => {"r1" => "32'h4",
- "r2" => "32'd3"}, # Make this an anonymous has with entries like "r10" => "32'h0" etc.
- FINAL_CHECK => {"32'h100" => "32'd4",
- "32'h66" => "32'h4"} # Make this an anonymous hash with entries like verilog_address => verilog_value etc.
-);
-
Index: trunk/makefile
===================================================================
--- trunk/makefile (revision 57)
+++ 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: trunk/README.md
===================================================================
--- trunk/README.md (revision 57)
+++ 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