Skip to content
Browse files

lm32: use submodule

  • Loading branch information...
1 parent 0caac22 commit 43343b131f4cc1e7ea910a89f67c8633daa2bd2c @sbourdeauducq sbourdeauducq committed
View
3 .gitmodules
@@ -0,0 +1,3 @@
+[submodule "verilog/lm32/submodule"]
+ path = verilog/lm32/submodule
+ url = git://github.com/milkymist/lm32.git
View
5 build.py
@@ -49,13 +49,14 @@ def main():
# add Verilog sources
for d in ["generic", "m1crg", "s6ddrphy", "minimac3"]:
plat.add_source_dir(os.path.join("verilog", d))
- plat.add_sources(os.path.join("verilog", "lm32"),
+ plat.add_sources(os.path.join("verilog", "lm32", "submodule", "rtl"),
"lm32_cpu.v", "lm32_instruction_unit.v", "lm32_decoder.v",
"lm32_load_store_unit.v", "lm32_adder.v", "lm32_addsub.v", "lm32_logic_op.v",
- "lm32_shifter.v", "lm32_multiplier_spartan6.v", "lm32_mc_arithmetic.v",
+ "lm32_shifter.v", "lm32_multiplier.v", "lm32_mc_arithmetic.v",
"lm32_interrupt.v", "lm32_ram.v", "lm32_dp_ram.v", "lm32_icache.v",
"lm32_dcache.v", "lm32_top.v", "lm32_debug.v", "lm32_jtag.v", "jtag_cores.v",
"jtag_tap_spartan6.v")
+ plat.add_sources(os.path.join("verilog", "lm32"), "lm32_config.v")
plat.build_cmdline(soc.get_fragment(), clock_domains=soc.crg.get_clock_domains())
View
86 verilog/lm32/jtag_cores.v
@@ -1,86 +0,0 @@
-/*
- * Milkymist SoC
- * Copyright (c) 2010 Michael Walle
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-module jtag_cores (
- input [7:0] reg_d,
- input [2:0] reg_addr_d,
- output reg_update,
- output [7:0] reg_q,
- output [2:0] reg_addr_q,
- output jtck,
- output jrstn
-);
-
-wire tck;
-wire tdi;
-wire tdo;
-wire shift;
-wire update;
-wire reset;
-
-jtag_tap jtag_tap (
- .tck(tck),
- .tdi(tdi),
- .tdo(tdo),
- .shift(shift),
- .update(update),
- .reset(reset)
-);
-
-reg [10:0] jtag_shift;
-reg [10:0] jtag_latched;
-
-always @(posedge tck or posedge reset)
-begin
- if(reset)
- jtag_shift <= 11'b0;
- else begin
- if(shift)
- jtag_shift <= {tdi, jtag_shift[10:1]};
- else
- jtag_shift <= {reg_d, reg_addr_d};
- end
-end
-
-assign tdo = jtag_shift[0];
-
-always @(posedge reg_update or posedge reset)
-begin
- if(reset)
- jtag_latched <= 11'b0;
- else
- jtag_latched <= jtag_shift;
-end
-
-assign reg_update = update;
-assign reg_q = jtag_latched[10:3];
-assign reg_addr_q = jtag_latched[2:0];
-assign jtck = tck;
-assign jrstn = ~reset;
-
-endmodule
View
60 verilog/lm32/jtag_tap_spartan6.v
@@ -1,60 +0,0 @@
-/*
- * Milkymist SoC
- * Copyright (c) 2010 Michael Walle
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-module jtag_tap(
- output tck,
- output tdi,
- input tdo,
- output shift,
- output update,
- output reset
-);
-
-wire g_shift;
-wire g_update;
-
-assign shift = g_shift & sel;
-assign update = g_update & sel;
-
-BSCAN_SPARTAN6 #(
- .JTAG_CHAIN(1)
-) bscan (
- .CAPTURE(),
- .DRCK(tck),
- .RESET(reset),
- .RUNTEST(),
- .SEL(sel),
- .SHIFT(g_shift),
- .TCK(),
- .TDI(tdi),
- .TMS(),
- .UPDATE(g_update),
- .TDO(tdo)
-);
-
-endmodule
View
136 verilog/lm32/lm32_adder.v
@@ -1,136 +0,0 @@
-// ==================================================================
-// >>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
-// ------------------------------------------------------------------
-// Copyright (c) 2006-2011 by Lattice Semiconductor Corporation
-// ALL RIGHTS RESERVED
-// ------------------------------------------------------------------
-//
-// IMPORTANT: THIS FILE IS AUTO-GENERATED BY THE LATTICEMICO SYSTEM.
-//
-// Permission:
-//
-// Lattice Semiconductor grants permission to use this code
-// pursuant to the terms of the Lattice Semiconductor Corporation
-// Open Source License Agreement.
-//
-// Disclaimer:
-//
-// Lattice Semiconductor provides no warranty regarding the use or
-// functionality of this code. It is the user's responsibility to
-// verify the user's design for consistency and functionality through
-// the use of formal verification methods.
-//
-// --------------------------------------------------------------------
-//
-// Lattice Semiconductor Corporation
-// 5555 NE Moore Court
-// Hillsboro, OR 97214
-// U.S.A
-//
-// TEL: 1-800-Lattice (USA and Canada)
-// 503-286-8001 (other locations)
-//
-// web: http://www.latticesemi.com/
-// email: techsupport@latticesemi.com
-//
-// --------------------------------------------------------------------
-// FILE DETAILS
-// Project : LatticeMico32
-// File : lm32_adder.v
-// Title : Integer adder / subtractor with comparison flag generation
-// Dependencies : lm32_include.v
-// Version : 6.1.17
-// : Initial Release
-// Version : 7.0SP2, 3.0
-// : No Change
-// Version : 3.1
-// : No Change
-// =============================================================================
-
-`include "lm32_include.v"
-
-/////////////////////////////////////////////////////
-// Module interface
-/////////////////////////////////////////////////////
-
-module lm32_adder (
- // ----- Inputs -------
- adder_op_x,
- adder_op_x_n,
- operand_0_x,
- operand_1_x,
- // ----- Outputs -------
- adder_result_x,
- adder_carry_n_x,
- adder_overflow_x
- );
-
-/////////////////////////////////////////////////////
-// Inputs
-/////////////////////////////////////////////////////
-
-input adder_op_x; // Operating to perform, 0 for addition, 1 for subtraction
-input adder_op_x_n; // Inverted version of adder_op_x
-input [`LM32_WORD_RNG] operand_0_x; // Operand to add, or subtract from
-input [`LM32_WORD_RNG] operand_1_x; // Opearnd to add, or subtract by
-
-/////////////////////////////////////////////////////
-// Outputs
-/////////////////////////////////////////////////////
-
-output [`LM32_WORD_RNG] adder_result_x; // Result of addition or subtraction
-wire [`LM32_WORD_RNG] adder_result_x;
-output adder_carry_n_x; // Inverted carry
-wire adder_carry_n_x;
-output adder_overflow_x; // Indicates if overflow occured, only valid for subtractions
-reg adder_overflow_x;
-
-/////////////////////////////////////////////////////
-// Internal nets and registers
-/////////////////////////////////////////////////////
-
-wire a_sign; // Sign (i.e. positive or negative) of operand 0
-wire b_sign; // Sign of operand 1
-wire result_sign; // Sign of result
-
-/////////////////////////////////////////////////////
-// Instantiations
-/////////////////////////////////////////////////////
-
-lm32_addsub addsub (
- // ----- Inputs -----
- .DataA (operand_0_x),
- .DataB (operand_1_x),
- .Cin (adder_op_x),
- .Add_Sub (adder_op_x_n),
- // ----- Ouputs -----
- .Result (adder_result_x),
- .Cout (adder_carry_n_x)
- );
-
-/////////////////////////////////////////////////////
-// Combinational Logic
-/////////////////////////////////////////////////////
-
-// Extract signs of operands and result
-
-assign a_sign = operand_0_x[`LM32_WORD_WIDTH-1];
-assign b_sign = operand_1_x[`LM32_WORD_WIDTH-1];
-assign result_sign = adder_result_x[`LM32_WORD_WIDTH-1];
-
-// Determine whether an overflow occured when performing a subtraction
-
-always @(*)
-begin
- // +ve - -ve = -ve -> overflow
- // -ve - +ve = +ve -> overflow
- if ( (!a_sign & b_sign & result_sign)
- || (a_sign & !b_sign & !result_sign)
- )
- adder_overflow_x = `TRUE;
- else
- adder_overflow_x = `FALSE;
-end
-
-endmodule
-
View
95 verilog/lm32/lm32_addsub.v
@@ -1,95 +0,0 @@
-// ==================================================================
-// >>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
-// ------------------------------------------------------------------
-// Copyright (c) 2006-2011 by Lattice Semiconductor Corporation
-// ALL RIGHTS RESERVED
-// ------------------------------------------------------------------
-//
-// IMPORTANT: THIS FILE IS AUTO-GENERATED BY THE LATTICEMICO SYSTEM.
-//
-// Permission:
-//
-// Lattice Semiconductor grants permission to use this code
-// pursuant to the terms of the Lattice Semiconductor Corporation
-// Open Source License Agreement.
-//
-// Disclaimer:
-//
-// Lattice Semiconductor provides no warranty regarding the use or
-// functionality of this code. It is the user's responsibility to
-// verify the user's design for consistency and functionality through
-// the use of formal verification methods.
-//
-// --------------------------------------------------------------------
-//
-// Lattice Semiconductor Corporation
-// 5555 NE Moore Court
-// Hillsboro, OR 97214
-// U.S.A
-//
-// TEL: 1-800-Lattice (USA and Canada)
-// 503-286-8001 (other locations)
-//
-// web: http://www.latticesemi.com/
-// email: techsupport@latticesemi.com
-//
-// --------------------------------------------------------------------
-// FILE DETAILS
-// Project : LatticeMico32
-// File : lm32_addsub.v
-// Title : PMI adder/subtractor.
-// Version : 6.1.17
-// : Initial Release
-// Version : 7.0SP2, 3.0
-// : No Change
-// Version : 3.1
-// : No Change
-// =============================================================================
-
-`include "lm32_include.v"
-
-/////////////////////////////////////////////////////
-// Module interface
-/////////////////////////////////////////////////////
-
-module lm32_addsub (
- // ----- Inputs -------
- DataA,
- DataB,
- Cin,
- Add_Sub,
- // ----- Outputs -------
- Result,
- Cout
- );
-
-/////////////////////////////////////////////////////
-// Inputs
-/////////////////////////////////////////////////////
-
-input [31:0] DataA;
-input [31:0] DataB;
-input Cin;
-input Add_Sub;
-
-/////////////////////////////////////////////////////
-// Outputs
-/////////////////////////////////////////////////////
-
-output [31:0] Result;
-wire [31:0] Result;
-output Cout;
-wire Cout;
-
-/////////////////////////////////////////////////////
-// Instantiations
-/////////////////////////////////////////////////////
-
-// Modified for Milkymist: removed non-portable instantiated block
- wire [32:0] tmp_addResult = DataA + DataB + Cin;
- wire [32:0] tmp_subResult = DataA - DataB - !Cin;
-
- assign Result = (Add_Sub == 1) ? tmp_addResult[31:0] : tmp_subResult[31:0];
- assign Cout = (Add_Sub == 1) ? tmp_addResult[32] : !tmp_subResult[32];
-
-endmodule
View
167 verilog/lm32/lm32_config.v
@@ -2,39 +2,186 @@
`else
`define LM32_CONFIG_V
+//
+// EXCEPTION VECTORS BASE ADDRESS
+//
+
+// Base address for exception vectors
`define CFG_EBA_RESET 32'h00860000
+
+// Base address for the debug exception vectors. If the DC_RE flag is
+// set or the at_debug signal is asserted (see CFG_ALTERNATE_EBA) this
+// will also be used for normal exception vectors.
`define CFG_DEBA_RESET 32'h10000000
-`define CFG_PL_MULTIPLY_ENABLED
-`define CFG_PL_BARREL_SHIFT_ENABLED
+// Enable exception vector remapping by external signal
+//`define CFG_ALTERNATE_EBA
+
+
+//
+// ALU OPTIONS
+//
+
+// Enable sign-extension instructions
`define CFG_SIGN_EXTEND_ENABLED
+
+// Shifter
+// You may either enable the piplined or the multi-cycle barrel
+// shifter. The multi-cycle shifter will stall the pipeline until
+// the result is available after 32 cycles.
+// If both options are disabled, only "right shift by one bit" is
+// available.
+//`define CFG_MC_BARREL_SHIFT_ENABLED
+`define CFG_PL_BARREL_SHIFT_ENABLED
+
+// Multiplier
+// The multiplier is available either in a multi-cycle version or
+// in a pipelined one. The multi-cycle multiplier stalls the pipe
+// for 32 cycles. If both options are disabled, multiply operations
+// are not supported.
+//`define CFG_MC_MULTIPLY_ENABLED
+`define CFG_PL_MULTIPLY_ENABLED
+
+// Enable the multi-cycle divider. Stalls the pipe until the result
+// is ready after 32 cycles. If disabled, the divide operation is not
+// supported.
`define CFG_MC_DIVIDE_ENABLED
-`define CFG_EBR_POSEDGE_REGISTER_FILE
+
+//
+// INTERRUPTS
+//
+
+// Enable support for 32 hardware interrupts
+`define CFG_INTERRUPTS_ENABLED
+
+// Enable level-sensitive interrupts. The interrupt line status is
+// reflected in the IP register, which is then read-only.
+`define CFG_LEVEL_SENSITIVE_INTERRUPTS
+
+
+//
+// USER INSTRUCTION
+//
+
+// Enable support for the user opcode.
+//`define CFG_USER_ENABLED
+
+
+//
+// MEMORY MANAGEMENT UNIT
+//
+
+// Enable instruction and data translation lookaside buffers and
+// restricted user mode.
+//`define CFG_MMU_ENABLED
+
+
+//
+// CACHE
+//
+
+// Instruction cache
`define CFG_ICACHE_ENABLED
`define CFG_ICACHE_ASSOCIATIVITY 1
`define CFG_ICACHE_SETS 256
`define CFG_ICACHE_BYTES_PER_LINE 16
-`define CFG_ICACHE_BASE_ADDRESS 32'h0
+`define CFG_ICACHE_BASE_ADDRESS 32'h00000000
`define CFG_ICACHE_LIMIT 32'h7fffffff
+// Data cache
`define CFG_DCACHE_ENABLED
`define CFG_DCACHE_ASSOCIATIVITY 1
`define CFG_DCACHE_SETS 256
`define CFG_DCACHE_BYTES_PER_LINE 16
-`define CFG_DCACHE_BASE_ADDRESS 32'h0
+`define CFG_DCACHE_BASE_ADDRESS 32'h00000000
`define CFG_DCACHE_LIMIT 32'h7fffffff
-// Enable Debugging
+
+//
+// DEBUG OPTION
+//
+
+// Globally enable debugging
+//`define CFG_DEBUG_ENABLED
+
+// Enable the hardware JTAG debugging interface.
+// Note: to use this, there must be a special JTAG module for your
+// device. At the moment, there is only support for the
+// Spartan-6.
//`define CFG_JTAG_ENABLED
+
+// JTAG UART is a communication channel which uses JTAG to transmit
+// and receive bytes to and from the host computer.
//`define CFG_JTAG_UART_ENABLED
-//`define CFG_DEBUG_ENABLED
+
+// Enable reading and writing to the memory and writing CSRs using
+// the JTAG interface.
//`define CFG_HW_DEBUG_ENABLED
+
+// Number of hardware watchpoints, max. 4
+//`define CFG_WATCHPOINTS 32'h4
+
+// Enable hardware breakpoints
//`define CFG_ROM_DEBUG_ENABLED
+
+// Number of hardware breakpoints, max. 4
//`define CFG_BREAKPOINTS 32'h4
-//`define CFG_WATCHPOINTS 32'h4
+
+// Put the processor into debug mode by an external signal. That is,
+// raise a breakpoint exception. This is useful if you have a debug
+// monitor and a serial line and you want to trap into the monitor on a
+// BREAK symbol on the serial line.
//`define CFG_EXTERNAL_BREAK_ENABLED
-//`define CFG_GDBSTUB_ENABLED
+
+
+//
+// REGISTER FILE
+//
+
+// The following option explicitly infers block RAM for the register
+// file. There is extra logic to avoid parallel writes and reads.
+// Normally, if your synthesizer is smart enough, this should not be
+// necessary because it will automatically infer block RAM for you.
+//`define CFG_EBR_POSEDGE_REGISTER_FILE
+
+// Explicitly infers block RAM, too. But it uses two different clocks,
+// one being shifted by 180deg, for the read and write port. Therefore,
+// no additional logic to avoid the parallel write/reads.
+//`define CFG_EBR_NEGEDGE_REGISTER_FILE
+
+
+//
+// MISCELLANEOUS
+//
+
+// Exceptions on wishbone bus errors
+//`define CFG_BUS_ERRORS_ENABLED
+
+// Enable the cycle counter
+`define CFG_CYCLE_COUNTER_ENABLED
+
+// Embedded instruction ROM using on-chip block RAM
+//`define CFG_IROM_ENABLED
+//`define CFG_IROM_INIT_FILE "NONE"
+//`define CFG_IROM_BASE_ADDRESS 32'h10000000
+//`define CFG_IROM_LIMIT 32'h10000fff
+
+// Embedded data RAM using on-chip block RAM
+//`define CFG_DRAM_ENABLED
+//`define CFG_DRAM_INIT_FILE "NONE"
+//`define CFG_DRAM_BASE_ADDRESS 32'h20000000
+//`define CFG_DRAM_LIMIT 32'h20000fff
+
+// Trace unit
+//`define CFG_TRACE_ENABLED
+
+// Resolve unconditional branches already in the X stage (UNTESTED!)
+//`define CFG_FAST_UNCONDITIONAL_BRANCH
+
+// log2 function
+// If your simulator/synthesizer does not support the $clog2 system
+// function you can use a constant function instead.
function integer clog2;
input integer value;
@@ -47,4 +194,6 @@ endfunction
`define CLOG2 clog2
+//`define CLOG2 $clog2
+
`endif
View
2,767 verilog/lm32/lm32_cpu.v
0 additions, 2,767 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
525 verilog/lm32/lm32_dcache.v
@@ -1,525 +0,0 @@
-// ==================================================================
-// >>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
-// ------------------------------------------------------------------
-// Copyright (c) 2006-2011 by Lattice Semiconductor Corporation
-// ALL RIGHTS RESERVED
-// ------------------------------------------------------------------
-//
-// IMPORTANT: THIS FILE IS AUTO-GENERATED BY THE LATTICEMICO SYSTEM.
-//
-// Permission:
-//
-// Lattice Semiconductor grants permission to use this code
-// pursuant to the terms of the Lattice Semiconductor Corporation
-// Open Source License Agreement.
-//
-// Disclaimer:
-//
-// Lattice Semiconductor provides no warranty regarding the use or
-// functionality of this code. It is the user's responsibility to
-// verify the user's design for consistency and functionality through
-// the use of formal verification methods.
-//
-// --------------------------------------------------------------------
-//
-// Lattice Semiconductor Corporation
-// 5555 NE Moore Court
-// Hillsboro, OR 97214
-// U.S.A
-//
-// TEL: 1-800-Lattice (USA and Canada)
-// 503-286-8001 (other locations)
-//
-// web: http://www.latticesemi.com/
-// email: techsupport@latticesemi.com
-//
-// --------------------------------------------------------------------
-// FILE DETAILS
-// Project : LatticeMico32
-// File : lm32_dcache.v
-// Title : Data cache
-// Dependencies : lm32_include.v
-// Version : 6.1.17
-// : Initial Release
-// Version : 7.0SP2, 3.0
-// : No Change
-// Version : 3.1
-// : Support for user-selected resource usage when implementing
-// : cache memory. Additional parameters must be defined when
-// : invoking lm32_ram.v
-// =============================================================================
-
-`include "lm32_include.v"
-
-`ifdef CFG_DCACHE_ENABLED
-
-`define LM32_DC_ADDR_OFFSET_RNG addr_offset_msb:addr_offset_lsb
-`define LM32_DC_ADDR_SET_RNG addr_set_msb:addr_set_lsb
-`define LM32_DC_ADDR_TAG_RNG addr_tag_msb:addr_tag_lsb
-`define LM32_DC_ADDR_IDX_RNG addr_set_msb:addr_offset_lsb
-
-`define LM32_DC_TMEM_ADDR_WIDTH addr_set_width
-`define LM32_DC_TMEM_ADDR_RNG (`LM32_DC_TMEM_ADDR_WIDTH-1):0
-`define LM32_DC_DMEM_ADDR_WIDTH (addr_offset_width+addr_set_width)
-`define LM32_DC_DMEM_ADDR_RNG (`LM32_DC_DMEM_ADDR_WIDTH-1):0
-
-`define LM32_DC_TAGS_WIDTH (addr_tag_width+1)
-`define LM32_DC_TAGS_RNG (`LM32_DC_TAGS_WIDTH-1):0
-`define LM32_DC_TAGS_TAG_RNG (`LM32_DC_TAGS_WIDTH-1):1
-`define LM32_DC_TAGS_VALID_RNG 0
-
-`define LM32_DC_STATE_RNG 2:0
-`define LM32_DC_STATE_FLUSH 3'b001
-`define LM32_DC_STATE_CHECK 3'b010
-`define LM32_DC_STATE_REFILL 3'b100
-
-/////////////////////////////////////////////////////
-// Module interface
-/////////////////////////////////////////////////////
-
-module lm32_dcache (
- // ----- Inputs -----
- clk_i,
- rst_i,
- stall_a,
- stall_x,
- stall_m,
- address_x,
- address_m,
- load_q_m,
- store_q_m,
- store_data,
- store_byte_select,
- refill_ready,
- refill_data,
- dflush,
- // ----- Outputs -----
- stall_request,
- restart_request,
- refill_request,
- refill_address,
- refilling,
- load_data
- );
-
-/////////////////////////////////////////////////////
-// Parameters
-/////////////////////////////////////////////////////
-
-parameter associativity = 1; // Associativity of the cache (Number of ways)
-parameter sets = 512; // Number of sets
-parameter bytes_per_line = 16; // Number of bytes per cache line
-parameter base_address = 0; // Base address of cachable memory
-parameter limit = 0; // Limit (highest address) of cachable memory
-
-localparam addr_offset_width = `CLOG2(bytes_per_line)-2;
-localparam addr_set_width = `CLOG2(sets);
-localparam addr_offset_lsb = 2;
-localparam addr_offset_msb = (addr_offset_lsb+addr_offset_width-1);
-localparam addr_set_lsb = (addr_offset_msb+1);
-localparam addr_set_msb = (addr_set_lsb+addr_set_width-1);
-localparam addr_tag_lsb = (addr_set_msb+1);
-localparam addr_tag_msb = `CLOG2(`CFG_DCACHE_LIMIT-`CFG_DCACHE_BASE_ADDRESS);
-localparam addr_tag_width = (addr_tag_msb-addr_tag_lsb+1);
-
-/////////////////////////////////////////////////////
-// Inputs
-/////////////////////////////////////////////////////
-
-input clk_i; // Clock
-input rst_i; // Reset
-
-input stall_a; // Stall A stage
-input stall_x; // Stall X stage
-input stall_m; // Stall M stage
-
-input [`LM32_WORD_RNG] address_x; // X stage load/store address
-input [`LM32_WORD_RNG] address_m; // M stage load/store address
-input load_q_m; // Load instruction in M stage
-input store_q_m; // Store instruction in M stage
-input [`LM32_WORD_RNG] store_data; // Data to store
-input [`LM32_BYTE_SELECT_RNG] store_byte_select; // Which bytes in store data should be modified
-
-input refill_ready; // Indicates next word of refill data is ready
-input [`LM32_WORD_RNG] refill_data; // Refill data
-
-input dflush; // Indicates cache should be flushed
-
-/////////////////////////////////////////////////////
-// Outputs
-/////////////////////////////////////////////////////
-
-output stall_request; // Request pipeline be stalled because cache is busy
-wire stall_request;
-output restart_request; // Request to restart instruction that caused the cache miss
-reg restart_request;
-output refill_request; // Request a refill
-reg refill_request;
-output [`LM32_WORD_RNG] refill_address; // Address to refill from
-reg [`LM32_WORD_RNG] refill_address;
-output refilling; // Indicates if the cache is currently refilling
-reg refilling;
-output [`LM32_WORD_RNG] load_data; // Data read from cache
-wire [`LM32_WORD_RNG] load_data;
-
-/////////////////////////////////////////////////////
-// Internal nets and registers
-/////////////////////////////////////////////////////
-
-wire read_port_enable; // Cache memory read port clock enable
-wire write_port_enable; // Cache memory write port clock enable
-wire [0:associativity-1] way_tmem_we; // Tag memory write enable
-wire [0:associativity-1] way_dmem_we; // Data memory write enable
-wire [`LM32_WORD_RNG] way_data[0:associativity-1]; // Data read from data memory
-wire [`LM32_DC_TAGS_TAG_RNG] way_tag[0:associativity-1];// Tag read from tag memory
-wire [0:associativity-1] way_valid; // Indicates which ways are valid
-wire [0:associativity-1] way_match; // Indicates which ways matched
-wire miss; // Indicates no ways matched
-
-wire [`LM32_DC_TMEM_ADDR_RNG] tmem_read_address; // Tag memory read address
-wire [`LM32_DC_TMEM_ADDR_RNG] tmem_write_address; // Tag memory write address
-wire [`LM32_DC_DMEM_ADDR_RNG] dmem_read_address; // Data memory read address
-wire [`LM32_DC_DMEM_ADDR_RNG] dmem_write_address; // Data memory write address
-wire [`LM32_DC_TAGS_RNG] tmem_write_data; // Tag memory write data
-reg [`LM32_WORD_RNG] dmem_write_data; // Data memory write data
-
-reg [`LM32_DC_STATE_RNG] state; // Current state of FSM
-wire flushing; // Indicates if cache is currently flushing
-wire check; // Indicates if cache is currently checking for hits/misses
-wire refill; // Indicates if cache is currently refilling
-
-wire valid_store; // Indicates if there is a valid store instruction
-reg [associativity-1:0] refill_way_select; // Which way should be refilled
-reg [`LM32_DC_ADDR_OFFSET_RNG] refill_offset; // Which word in cache line should be refilled
-wire last_refill; // Indicates when on last cycle of cache refill
-reg [`LM32_DC_TMEM_ADDR_RNG] flush_set; // Which set is currently being flushed
-
-genvar i, j;
-
-/////////////////////////////////////////////////////
-// Functions
-/////////////////////////////////////////////////////
-
-/////////////////////////////////////////////////////
-// Instantiations
-/////////////////////////////////////////////////////
-
- generate
- for (i = 0; i < associativity; i = i + 1)
- begin : memories
- // Way data
- if (`LM32_DC_DMEM_ADDR_WIDTH < 11)
- begin : data_memories
- lm32_ram
- #(
- // ----- Parameters -------
- .data_width (32),
- .address_width (`LM32_DC_DMEM_ADDR_WIDTH)
-// Modified for Milkymist: removed non-portable RAM parameters
- ) way_0_data_ram
- (
- // ----- Inputs -------
- .read_clk (clk_i),
- .write_clk (clk_i),
- .reset (rst_i),
- .read_address (dmem_read_address),
- .enable_read (read_port_enable),
- .write_address (dmem_write_address),
- .enable_write (write_port_enable),
- .write_enable (way_dmem_we[i]),
- .write_data (dmem_write_data),
- // ----- Outputs -------
- .read_data (way_data[i])
- );
- end
- else
- begin
- for (j = 0; j < 4; j = j + 1)
- begin : byte_memories
- lm32_ram
- #(
- // ----- Parameters -------
- .data_width (8),
- .address_width (`LM32_DC_DMEM_ADDR_WIDTH)
-// Modified for Milkymist: removed non-portable RAM parameters
- ) way_0_data_ram
- (
- // ----- Inputs -------
- .read_clk (clk_i),
- .write_clk (clk_i),
- .reset (rst_i),
- .read_address (dmem_read_address),
- .enable_read (read_port_enable),
- .write_address (dmem_write_address),
- .enable_write (write_port_enable),
- .write_enable (way_dmem_we[i] & (store_byte_select[j] | refill)),
- .write_data (dmem_write_data[(j+1)*8-1:j*8]),
- // ----- Outputs -------
- .read_data (way_data[i][(j+1)*8-1:j*8])
- );
- end
- end
-
- // Way tags
- lm32_ram
- #(
- // ----- Parameters -------
- .data_width (`LM32_DC_TAGS_WIDTH),
- .address_width (`LM32_DC_TMEM_ADDR_WIDTH)
-// Modified for Milkymist: removed non-portable RAM parameters
- ) way_0_tag_ram
- (
- // ----- Inputs -------
- .read_clk (clk_i),
- .write_clk (clk_i),
- .reset (rst_i),
- .read_address (tmem_read_address),
- .enable_read (read_port_enable),
- .write_address (tmem_write_address),
- .enable_write (`TRUE),
- .write_enable (way_tmem_we[i]),
- .write_data (tmem_write_data),
- // ----- Outputs -------
- .read_data ({way_tag[i], way_valid[i]})
- );
- end
-
- endgenerate
-
-/////////////////////////////////////////////////////
-// Combinational logic
-/////////////////////////////////////////////////////
-
-// Compute which ways in the cache match the address being read
-generate
- for (i = 0; i < associativity; i = i + 1)
- begin : match
-assign way_match[i] = ({way_tag[i], way_valid[i]} == {address_m[`LM32_DC_ADDR_TAG_RNG], `TRUE});
- end
-endgenerate
-
-// Select data from way that matched the address being read
-generate
- if (associativity == 1)
- begin : data_1
-assign load_data = way_data[0];
- end
- else if (associativity == 2)
- begin : data_2
-assign load_data = way_match[0] ? way_data[0] : way_data[1];
- end
-endgenerate
-
-generate
- if (`LM32_DC_DMEM_ADDR_WIDTH < 11)
- begin
-// Select data to write to data memories
-always @(*)
-begin
- if (refill == `TRUE)
- dmem_write_data = refill_data;
- else
- begin
- dmem_write_data[`LM32_BYTE_0_RNG] = store_byte_select[0] ? store_data[`LM32_BYTE_0_RNG] : load_data[`LM32_BYTE_0_RNG];
- dmem_write_data[`LM32_BYTE_1_RNG] = store_byte_select[1] ? store_data[`LM32_BYTE_1_RNG] : load_data[`LM32_BYTE_1_RNG];
- dmem_write_data[`LM32_BYTE_2_RNG] = store_byte_select[2] ? store_data[`LM32_BYTE_2_RNG] : load_data[`LM32_BYTE_2_RNG];
- dmem_write_data[`LM32_BYTE_3_RNG] = store_byte_select[3] ? store_data[`LM32_BYTE_3_RNG] : load_data[`LM32_BYTE_3_RNG];
- end
-end
- end
- else
- begin
-// Select data to write to data memories - FIXME: Should use different write ports on dual port RAMs, but they don't work
-always @(*)
-begin
- if (refill == `TRUE)
- dmem_write_data = refill_data;
- else
- dmem_write_data = store_data;
-end
- end
-endgenerate
-
-// Compute address to use to index into the data memories
-generate
- if (bytes_per_line > 4)
-assign dmem_write_address = (refill == `TRUE)
- ? {refill_address[`LM32_DC_ADDR_SET_RNG], refill_offset}
- : address_m[`LM32_DC_ADDR_IDX_RNG];
- else
-assign dmem_write_address = (refill == `TRUE)
- ? refill_address[`LM32_DC_ADDR_SET_RNG]
- : address_m[`LM32_DC_ADDR_IDX_RNG];
-endgenerate
-assign dmem_read_address = address_x[`LM32_DC_ADDR_IDX_RNG];
-// Compute address to use to index into the tag memories
-assign tmem_write_address = (flushing == `TRUE)
- ? flush_set
- : refill_address[`LM32_DC_ADDR_SET_RNG];
-assign tmem_read_address = address_x[`LM32_DC_ADDR_SET_RNG];
-
-// Compute signal to indicate when we are on the last refill accesses
-generate
- if (bytes_per_line > 4)
-assign last_refill = refill_offset == {addr_offset_width{1'b1}};
- else
-assign last_refill = `TRUE;
-endgenerate
-
-// Compute data and tag memory access enable
-assign read_port_enable = (stall_x == `FALSE);
-assign write_port_enable = (refill_ready == `TRUE) || !stall_m;
-
-// Determine when we have a valid store
-assign valid_store = (store_q_m == `TRUE) && (check == `TRUE);
-
-// Compute data and tag memory write enables
-generate
- if (associativity == 1)
- begin : we_1
-assign way_dmem_we[0] = (refill_ready == `TRUE) || ((valid_store == `TRUE) && (way_match[0] == `TRUE));
-assign way_tmem_we[0] = (refill_ready == `TRUE) || (flushing == `TRUE);
- end
- else
- begin : we_2
-assign way_dmem_we[0] = ((refill_ready == `TRUE) && (refill_way_select[0] == `TRUE)) || ((valid_store == `TRUE) && (way_match[0] == `TRUE));
-assign way_dmem_we[1] = ((refill_ready == `TRUE) && (refill_way_select[1] == `TRUE)) || ((valid_store == `TRUE) && (way_match[1] == `TRUE));
-assign way_tmem_we[0] = ((refill_ready == `TRUE) && (refill_way_select[0] == `TRUE)) || (flushing == `TRUE);
-assign way_tmem_we[1] = ((refill_ready == `TRUE) && (refill_way_select[1] == `TRUE)) || (flushing == `TRUE);
- end
-endgenerate
-
-// On the last refill cycle set the valid bit, for all other writes it should be cleared
-assign tmem_write_data[`LM32_DC_TAGS_VALID_RNG] = ((last_refill == `TRUE) || (valid_store == `TRUE)) && (flushing == `FALSE);
-assign tmem_write_data[`LM32_DC_TAGS_TAG_RNG] = refill_address[`LM32_DC_ADDR_TAG_RNG];
-
-// Signals that indicate which state we are in
-assign flushing = state[0];
-assign check = state[1];
-assign refill = state[2];
-
-assign miss = (~(|way_match)) && (load_q_m == `TRUE) && (stall_m == `FALSE);
-assign stall_request = (check == `FALSE);
-
-/////////////////////////////////////////////////////
-// Sequential logic
-/////////////////////////////////////////////////////
-
-// Record way selected for replacement on a cache miss
-generate
- if (associativity >= 2)
- begin : way_select
-always @(posedge clk_i `CFG_RESET_SENSITIVITY)
-begin
- if (rst_i == `TRUE)
- refill_way_select <= {{associativity-1{1'b0}}, 1'b1};
- else
- begin
- if (refill_request == `TRUE)
- refill_way_select <= {refill_way_select[0], refill_way_select[1]};
- end
-end
- end
-endgenerate
-
-// Record whether we are currently refilling
-always @(posedge clk_i `CFG_RESET_SENSITIVITY)
-begin
- if (rst_i == `TRUE)
- refilling <= `FALSE;
- else
- refilling <= refill;
-end
-
-// Instruction cache control FSM
-always @(posedge clk_i `CFG_RESET_SENSITIVITY)
-begin
- if (rst_i == `TRUE)
- begin
- state <= `LM32_DC_STATE_FLUSH;
- flush_set <= {`LM32_DC_TMEM_ADDR_WIDTH{1'b1}};
- refill_request <= `FALSE;
- refill_address <= {`LM32_WORD_WIDTH{1'bx}};
- restart_request <= `FALSE;
- end
- else
- begin
- case (state)
-
- // Flush the cache
- `LM32_DC_STATE_FLUSH:
- begin
- if (flush_set == {`LM32_DC_TMEM_ADDR_WIDTH{1'b0}})
- state <= `LM32_DC_STATE_CHECK;
- flush_set <= flush_set - 1'b1;
- end
-
- // Check for cache misses
- `LM32_DC_STATE_CHECK:
- begin
- if (stall_a == `FALSE)
- restart_request <= `FALSE;
- if (miss == `TRUE)
- begin
- refill_request <= `TRUE;
- refill_address <= address_m;
- state <= `LM32_DC_STATE_REFILL;
- end
- else if (dflush == `TRUE)
- state <= `LM32_DC_STATE_FLUSH;
- end
-
- // Refill a cache line
- `LM32_DC_STATE_REFILL:
- begin
- refill_request <= `FALSE;
- if (refill_ready == `TRUE)
- begin
- if (last_refill == `TRUE)
- begin
- restart_request <= `TRUE;
- state <= `LM32_DC_STATE_CHECK;
- end
- end
- end
-
- endcase
- end
-end
-
-generate
- if (bytes_per_line > 4)
- begin
-// Refill offset
-always @(posedge clk_i `CFG_RESET_SENSITIVITY)
-begin
- if (rst_i == `TRUE)
- refill_offset <= {addr_offset_width{1'b0}};
- else
- begin
- case (state)
-
- // Check for cache misses
- `LM32_DC_STATE_CHECK:
- begin
- if (miss == `TRUE)
- refill_offset <= {addr_offset_width{1'b0}};
- end
-
- // Refill a cache line
- `LM32_DC_STATE_REFILL:
- begin
- if (refill_ready == `TRUE)
- refill_offset <= refill_offset + 1'b1;
- end
-
- endcase
- end
-end
- end
-endgenerate
-
-endmodule
-
-`endif
-
View
367 verilog/lm32/lm32_debug.v
@@ -1,367 +0,0 @@
-// ==================================================================
-// >>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
-// ------------------------------------------------------------------
-// Copyright (c) 2006-2011 by Lattice Semiconductor Corporation
-// ALL RIGHTS RESERVED
-// ------------------------------------------------------------------
-//
-// IMPORTANT: THIS FILE IS AUTO-GENERATED BY THE LATTICEMICO SYSTEM.
-//
-// Permission:
-//
-// Lattice Semiconductor grants permission to use this code
-// pursuant to the terms of the Lattice Semiconductor Corporation
-// Open Source License Agreement.
-//
-// Disclaimer:
-//
-// Lattice Semiconductor provides no warranty regarding the use or
-// functionality of this code. It is the user's responsibility to
-// verify the user's design for consistency and functionality through
-// the use of formal verification methods.
-//
-// --------------------------------------------------------------------
-//
-// Lattice Semiconductor Corporation
-// 5555 NE Moore Court
-// Hillsboro, OR 97214
-// U.S.A
-//
-// TEL: 1-800-Lattice (USA and Canada)
-// 503-286-8001 (other locations)
-//
-// web: http://www.latticesemi.com/
-// email: techsupport@latticesemi.com
-//
-// --------------------------------------------------------------------
-// FILE DETAILS
-// Project : LatticeMico32
-// File : lm32_debug.v
-// Title : Hardware debug registers and associated logic.
-// Dependencies : lm32_include.v
-// Version : 6.1.17
-// : Initial Release
-// Version : 7.0SP2, 3.0
-// : No Change
-// Version : 3.1
-// : No Change
-// Version : 3.2
-// : Fixed simulation bug which flares up when number of
-// : watchpoints is zero.
-// =============================================================================
-
-`include "lm32_include.v"
-
-`ifdef CFG_DEBUG_ENABLED
-
-// States for single-step FSM
-`define LM32_DEBUG_SS_STATE_RNG 2:0
-`define LM32_DEBUG_SS_STATE_IDLE 3'b000
-`define LM32_DEBUG_SS_STATE_WAIT_FOR_RET 3'b001
-`define LM32_DEBUG_SS_STATE_EXECUTE_ONE_INSN 3'b010
-`define LM32_DEBUG_SS_STATE_RAISE_BREAKPOINT 3'b011
-`define LM32_DEBUG_SS_STATE_RESTART 3'b100
-
-/////////////////////////////////////////////////////
-// Module interface
-/////////////////////////////////////////////////////
-
-module lm32_debug (
- // ----- Inputs -------
- clk_i,
- rst_i,
- pc_x,
- load_x,
- store_x,
- load_store_address_x,
- csr_write_enable_x,
- csr_write_data,
- csr_x,
-`ifdef CFG_HW_DEBUG_ENABLED
- jtag_csr_write_enable,
- jtag_csr_write_data,
- jtag_csr,
-`endif
-`ifdef LM32_SINGLE_STEP_ENABLED
- eret_q_x,
- bret_q_x,
- stall_x,
- exception_x,
- q_x,
-`ifdef CFG_DCACHE_ENABLED
- dcache_refill_request,
-`endif
-`endif
- // ----- Outputs -------
-`ifdef LM32_SINGLE_STEP_ENABLED
- dc_ss,
-`endif
- dc_re,
- bp_match,
- wp_match
- );
-
-/////////////////////////////////////////////////////
-// Parameters
-/////////////////////////////////////////////////////
-
-parameter breakpoints = 0; // Number of breakpoint CSRs
-parameter watchpoints = 0; // Number of watchpoint CSRs
-
-/////////////////////////////////////////////////////
-// Inputs
-/////////////////////////////////////////////////////
-
-input clk_i; // Clock
-input rst_i; // Reset
-
-input [`LM32_PC_RNG] pc_x; // X stage PC
-input load_x; // Load instruction in X stage
-input store_x; // Store instruction in X stage
-input [`LM32_WORD_RNG] load_store_address_x; // Load or store effective address
-input csr_write_enable_x; // wcsr instruction in X stage
-input [`LM32_WORD_RNG] csr_write_data; // Data to write to CSR
-input [`LM32_CSR_RNG] csr_x; // Which CSR to write
-`ifdef CFG_HW_DEBUG_ENABLED
-input jtag_csr_write_enable; // JTAG interface CSR write enable
-input [`LM32_WORD_RNG] jtag_csr_write_data; // Data to write to CSR
-input [`LM32_CSR_RNG] jtag_csr; // Which CSR to write
-`endif
-`ifdef LM32_SINGLE_STEP_ENABLED
-input eret_q_x; // eret instruction in X stage
-input bret_q_x; // bret instruction in X stage
-input stall_x; // Instruction in X stage is stalled
-input exception_x; // An exception has occured in X stage
-input q_x; // Indicates the instruction in the X stage is qualified
-`ifdef CFG_DCACHE_ENABLED
-input dcache_refill_request; // Indicates data cache wants to be refilled
-`endif
-`endif
-
-/////////////////////////////////////////////////////
-// Outputs
-/////////////////////////////////////////////////////
-
-`ifdef LM32_SINGLE_STEP_ENABLED
-output dc_ss; // Single-step enable
-reg dc_ss;
-`endif
-output dc_re; // Remap exceptions
-reg dc_re;
-output bp_match; // Indicates a breakpoint has matched
-wire bp_match;
-output wp_match; // Indicates a watchpoint has matched
-wire wp_match;
-
-/////////////////////////////////////////////////////
-// Internal nets and registers
-/////////////////////////////////////////////////////
-
-genvar i; // Loop index for generate statements
-
-// Debug CSRs
-
-reg [`LM32_PC_RNG] bp_a[0:breakpoints-1]; // Instruction breakpoint address
-reg bp_e[0:breakpoints-1]; // Instruction breakpoint enable
-wire [0:breakpoints-1]bp_match_n; // Indicates if a h/w instruction breakpoint matched
-
-reg [`LM32_WPC_C_RNG] wpc_c[0:watchpoints-1]; // Watchpoint enable
-reg [`LM32_WORD_RNG] wp[0:watchpoints-1]; // Watchpoint address
-wire [0:watchpoints-1]wp_match_n; // Indicates if a h/w data watchpoint matched
-
-wire debug_csr_write_enable; // Debug CSR write enable (from either a wcsr instruction of external debugger)
-wire [`LM32_WORD_RNG] debug_csr_write_data; // Data to write to debug CSR
-wire [`LM32_CSR_RNG] debug_csr; // Debug CSR to write to
-
-`ifdef LM32_SINGLE_STEP_ENABLED
-// FIXME: Declaring this as a reg causes ModelSim 6.1.15b to crash, so use integer for now
-//reg [`LM32_DEBUG_SS_STATE_RNG] state; // State of single-step FSM
-integer state; // State of single-step FSM
-`endif
-
-/////////////////////////////////////////////////////
-// Functions
-/////////////////////////////////////////////////////
-
-/////////////////////////////////////////////////////
-// Combinational Logic
-/////////////////////////////////////////////////////
-
-// Check for breakpoints
-generate
- for (i = 0; i < breakpoints; i = i + 1)
- begin : bp_comb
-assign bp_match_n[i] = ((bp_a[i] == pc_x) && (bp_e[i] == `TRUE));
- end
-endgenerate
-generate
-`ifdef LM32_SINGLE_STEP_ENABLED
- if (breakpoints > 0)
-assign bp_match = (|bp_match_n) || (state == `LM32_DEBUG_SS_STATE_RAISE_BREAKPOINT);
- else
-assign bp_match = state == `LM32_DEBUG_SS_STATE_RAISE_BREAKPOINT;
-`else
- if (breakpoints > 0)
-assign bp_match = |bp_match_n;
- else
-assign bp_match = `FALSE;
-`endif
-endgenerate
-
-// Check for watchpoints
-generate
- for (i = 0; i < watchpoints; i = i + 1)
- begin : wp_comb
-assign wp_match_n[i] = (wp[i] == load_store_address_x) && ((load_x & wpc_c[i][0]) | (store_x & wpc_c[i][1]));
- end
-endgenerate
-generate
- if (watchpoints > 0)
-assign wp_match = |wp_match_n;
- else
-assign wp_match = `FALSE;
-endgenerate
-
-`ifdef CFG_HW_DEBUG_ENABLED
-// Multiplex between wcsr instruction writes and debugger writes to the debug CSRs
-assign debug_csr_write_enable = (csr_write_enable_x == `TRUE) || (jtag_csr_write_enable == `TRUE);
-assign debug_csr_write_data = jtag_csr_write_enable == `TRUE ? jtag_csr_write_data : csr_write_data;
-assign debug_csr = jtag_csr_write_enable == `TRUE ? jtag_csr : csr_x;
-`else
-assign debug_csr_write_enable = csr_write_enable_x;
-assign debug_csr_write_data = csr_write_data;
-assign debug_csr = csr_x;
-`endif
-
-/////////////////////////////////////////////////////
-// Sequential Logic
-/////////////////////////////////////////////////////
-
-// Breakpoint address and enable CSRs
-generate
- for (i = 0; i < breakpoints; i = i + 1)
- begin : bp_seq
-always @(posedge clk_i `CFG_RESET_SENSITIVITY)
-begin
- if (rst_i == `TRUE)
- begin
- bp_a[i] <= {`LM32_PC_WIDTH{1'bx}};
- bp_e[i] <= `FALSE;
- end
- else
- begin
- if ((debug_csr_write_enable == `TRUE) && (debug_csr == `LM32_CSR_BP0 + i))
- begin
- bp_a[i] <= debug_csr_write_data[`LM32_PC_RNG];
- bp_e[i] <= debug_csr_write_data[0];
- end
- end
-end
- end
-endgenerate
-
-// Watchpoint address and control flags CSRs
-generate
- for (i = 0; i < watchpoints; i = i + 1)
- begin : wp_seq
-always @(posedge clk_i `CFG_RESET_SENSITIVITY)
-begin
- if (rst_i == `TRUE)
- begin
- wp[i] <= {`LM32_WORD_WIDTH{1'bx}};
- wpc_c[i] <= `LM32_WPC_C_DISABLED;
- end
- else
- begin
- if (debug_csr_write_enable == `TRUE)
- begin
- if (debug_csr == `LM32_CSR_DC)
- wpc_c[i] <= debug_csr_write_data[3+i*2:2+i*2];
- if (debug_csr == `LM32_CSR_WP0 + i)
- wp[i] <= debug_csr_write_data;
- end
- end
-end
- end
-endgenerate
-
-// Remap exceptions control bit
-always @(posedge clk_i `CFG_RESET_SENSITIVITY)
-begin
- if (rst_i == `TRUE)
- dc_re <= `FALSE;
- else
- begin
- if ((debug_csr_write_enable == `TRUE) && (debug_csr == `LM32_CSR_DC))
- dc_re <= debug_csr_write_data[1];
- end
-end
-
-`ifdef LM32_SINGLE_STEP_ENABLED
-// Single-step control flag
-always @(posedge clk_i `CFG_RESET_SENSITIVITY)
-begin
- if (rst_i == `TRUE)
- begin
- state <= `LM32_DEBUG_SS_STATE_IDLE;
- dc_ss <= `FALSE;
- end
- else
- begin
- if ((debug_csr_write_enable == `TRUE) && (debug_csr == `LM32_CSR_DC))
- begin
- dc_ss <= debug_csr_write_data[0];
- if (debug_csr_write_data[0] == `FALSE)
- state <= `LM32_DEBUG_SS_STATE_IDLE;
- else
- state <= `LM32_DEBUG_SS_STATE_WAIT_FOR_RET;
- end
- case (state)
- `LM32_DEBUG_SS_STATE_WAIT_FOR_RET:
- begin
- // Wait for eret or bret instruction to be executed
- if ( ( (eret_q_x == `TRUE)
- || (bret_q_x == `TRUE)
- )
- && (stall_x == `FALSE)
- )
- state <= `LM32_DEBUG_SS_STATE_EXECUTE_ONE_INSN;
- end
- `LM32_DEBUG_SS_STATE_EXECUTE_ONE_INSN:
- begin
- // Wait for an instruction to be executed
- if ((q_x == `TRUE) && (stall_x == `FALSE))
- state <= `LM32_DEBUG_SS_STATE_RAISE_BREAKPOINT;
- end
- `LM32_DEBUG_SS_STATE_RAISE_BREAKPOINT:
- begin
- // Wait for exception to be raised
-`ifdef CFG_DCACHE_ENABLED
- if (dcache_refill_request == `TRUE)
- state <= `LM32_DEBUG_SS_STATE_EXECUTE_ONE_INSN;
- else
-`endif
- if ((exception_x == `TRUE) && (q_x == `TRUE) && (stall_x == `FALSE))
- begin
- dc_ss <= `FALSE;
- state <= `LM32_DEBUG_SS_STATE_RESTART;
- end
- end
- `LM32_DEBUG_SS_STATE_RESTART:
- begin
- // Watch to see if stepped instruction is restarted due to a cache miss
-`ifdef CFG_DCACHE_ENABLED
- if (dcache_refill_request == `TRUE)
- state <= `LM32_DEBUG_SS_STATE_EXECUTE_ONE_INSN;
- else
-`endif
- state <= `LM32_DEBUG_SS_STATE_IDLE;
- end
- endcase
- end
-end
-`endif
-
-endmodule
-
-`endif
View
602 verilog/lm32/lm32_decoder.v
@@ -1,602 +0,0 @@
-// ==================================================================
-// >>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
-// ------------------------------------------------------------------
-// Copyright (c) 2006-2011 by Lattice Semiconductor Corporation
-// ALL RIGHTS RESERVED
-// ------------------------------------------------------------------
-//
-// IMPORTANT: THIS FILE IS AUTO-GENERATED BY THE LATTICEMICO SYSTEM.
-//
-// Permission:
-//
-// Lattice Semiconductor grants permission to use this code
-// pursuant to the terms of the Lattice Semiconductor Corporation
-// Open Source License Agreement.
-//
-// Disclaimer:
-//
-// Lattice Semiconductor provides no warranty regarding the use or
-// functionality of this code. It is the user's responsibility to
-// verify the user's design for consistency and functionality through
-// the use of formal verification methods.
-//
-// --------------------------------------------------------------------
-//
-// Lattice Semiconductor Corporation
-// 5555 NE Moore Court
-// Hillsboro, OR 97214
-// U.S.A
-//
-// TEL: 1-800-Lattice (USA and Canada)
-// 503-286-8001 (other locations)
-//
-// web: http://www.latticesemi.com/
-// email: techsupport@latticesemi.com
-//
-// --------------------------------------------------------------------
-// FILE DETAILS
-// Project : LatticeMico32
-// File : lm32_decoder.v
-// Title : Instruction decoder
-// Dependencies : lm32_include.v
-// Version : 6.1.17
-// : Initial Release
-// Version : 7.0SP2, 3.0
-// : No Change
-// Version : 3.1
-// : Support for static branch prediction. Information about
-// : branch type is generated and passed on to the predictor.
-// Version : 3.2
-// : No change
-// Version : 3.3
-// : Renamed port names that conflict with keywords reserved
-// : in System-Verilog.
-// =============================================================================
-
-`include "lm32_include.v"
-
-// Index of opcode field in an instruction
-`define LM32_OPCODE_RNG 31:26
-`define LM32_OP_RNG 30:26
-
-// Opcodes - Some are only listed as 5 bits as their MSB is a don't care
-`define LM32_OPCODE_ADD 5'b01101
-`define LM32_OPCODE_AND 5'b01000
-`define LM32_OPCODE_ANDHI 6'b011000
-`define LM32_OPCODE_B 6'b110000
-`define LM32_OPCODE_BI 6'b111000
-`define LM32_OPCODE_BE 6'b010001
-`define LM32_OPCODE_BG 6'b010010
-`define LM32_OPCODE_BGE 6'b010011
-`define LM32_OPCODE_BGEU 6'b010100
-`define LM32_OPCODE_BGU 6'b010101
-`define LM32_OPCODE_BNE 6'b010111
-`define LM32_OPCODE_CALL 6'b110110
-`define LM32_OPCODE_CALLI 6'b111110
-`define LM32_OPCODE_CMPE 5'b11001
-`define LM32_OPCODE_CMPG 5'b11010
-`define LM32_OPCODE_CMPGE 5'b11011
-`define LM32_OPCODE_CMPGEU 5'b11100
-`define LM32_OPCODE_CMPGU 5'b11101
-`define LM32_OPCODE_CMPNE 5'b11111
-`define LM32_OPCODE_DIVU 6'b100011
-`define LM32_OPCODE_LB 6'b000100
-`define LM32_OPCODE_LBU 6'b010000
-`define LM32_OPCODE_LH 6'b000111
-`define LM32_OPCODE_LHU 6'b001011
-`define LM32_OPCODE_LW 6'b001010
-`define LM32_OPCODE_MODU 6'b110001
-`define LM32_OPCODE_MUL 5'b00010
-`define LM32_OPCODE_NOR 5'b00001
-`define LM32_OPCODE_OR 5'b01110
-`define LM32_OPCODE_ORHI 6'b011110
-`define LM32_OPCODE_RAISE 6'b101011
-`define LM32_OPCODE_RCSR 6'b100100
-`define LM32_OPCODE_SB 6'b001100
-`define LM32_OPCODE_SEXTB 6'b101100
-`define LM32_OPCODE_SEXTH 6'b110111
-`define LM32_OPCODE_SH 6'b000011
-`define LM32_OPCODE_SL 5'b01111
-`define LM32_OPCODE_SR 5'b00101
-`define LM32_OPCODE_SRU 5'b00000
-`define LM32_OPCODE_SUB 6'b110010
-`define LM32_OPCODE_SW 6'b010110
-`define LM32_OPCODE_USER 6'b110011
-`define LM32_OPCODE_WCSR 6'b110100
-`define LM32_OPCODE_XNOR 5'b01001
-`define LM32_OPCODE_XOR 5'b00110
-
-/////////////////////////////////////////////////////
-// Module interface
-/////////////////////////////////////////////////////
-
-module lm32_decoder (
- // ----- Inputs -------
- instruction,
- // ----- Outputs -------
- d_result_sel_0,
- d_result_sel_1,
- x_result_sel_csr,
-`ifdef LM32_MC_ARITHMETIC_ENABLED
- x_result_sel_mc_arith,
-`endif
-`ifdef LM32_NO_BARREL_SHIFT
- x_result_sel_shift,
-`endif
-`ifdef CFG_SIGN_EXTEND_ENABLED
- x_result_sel_sext,
-`endif
- x_result_sel_logic,
-`ifdef CFG_USER_ENABLED
- x_result_sel_user,
-`endif
- x_result_sel_add,
- m_result_sel_compare,
-`ifdef CFG_PL_BARREL_SHIFT_ENABLED
- m_result_sel_shift,
-`endif
- w_result_sel_load,
-`ifdef CFG_PL_MULTIPLY_ENABLED
- w_result_sel_mul,
-`endif
- x_bypass_enable,
- m_bypass_enable,
- read_enable_0,
- read_idx_0,
- read_enable_1,
- read_idx_1,
- write_enable,
- write_idx,
- immediate,
- branch_offset,
- load,
- store,
- size,
- sign_extend,
- adder_op,
- logic_op,
-`ifdef CFG_PL_BARREL_SHIFT_ENABLED
- direction,
-`endif
-`ifdef CFG_MC_BARREL_SHIFT_ENABLED
- shift_left,
- shift_right,
-`endif
-`ifdef CFG_MC_MULTIPLY_ENABLED
- multiply,
-`endif
-`ifdef CFG_MC_DIVIDE_ENABLED
- divide,
- modulus,
-`endif
- branch,
- branch_reg,
- condition,
- bi_conditional,
- bi_unconditional,
-`ifdef CFG_DEBUG_ENABLED
- break_opcode,
-`endif
- scall,
- eret,
-`ifdef CFG_DEBUG_ENABLED
- bret,
-`endif
-`ifdef CFG_USER_ENABLED
- user_opcode,
-`endif
- csr_write_enable
- );
-
-/////////////////////////////////////////////////////
-// Inputs
-/////////////////////////////////////////////////////
-
-input [`LM32_INSTRUCTION_RNG] instruction; // Instruction to decode
-
-/////////////////////////////////////////////////////
-// Outputs
-/////////////////////////////////////////////////////
-
-output [`LM32_D_RESULT_SEL_0_RNG] d_result_sel_0;
-reg [`LM32_D_RESULT_SEL_0_RNG] d_result_sel_0;
-output [`LM32_D_RESULT_SEL_1_RNG] d_result_sel_1;
-reg [`LM32_D_RESULT_SEL_1_RNG] d_result_sel_1;
-output x_result_sel_csr;
-reg x_result_sel_csr;
-`ifdef LM32_MC_ARITHMETIC_ENABLED
-output x_result_sel_mc_arith;
-reg x_result_sel_mc_arith;
-`endif
-`ifdef LM32_NO_BARREL_SHIFT
-output x_result_sel_shift;
-reg x_result_sel_shift;
-`endif
-`ifdef CFG_SIGN_EXTEND_ENABLED
-output x_result_sel_sext;
-reg x_result_sel_sext;
-`endif
-output x_result_sel_logic;
-reg x_result_sel_logic;
-`ifdef CFG_USER_ENABLED
-output x_result_sel_user;
-reg x_result_sel_user;
-`endif
-output x_result_sel_add;
-reg x_result_sel_add;
-output m_result_sel_compare;
-reg m_result_sel_compare;
-`ifdef CFG_PL_BARREL_SHIFT_ENABLED
-output m_result_sel_shift;
-reg m_result_sel_shift;
-`endif
-output w_result_sel_load;
-reg w_result_sel_load;
-`ifdef CFG_PL_MULTIPLY_ENABLED
-output w_result_sel_mul;
-reg w_result_sel_mul;
-`endif
-output x_bypass_enable;
-wire x_bypass_enable;
-output m_bypass_enable;
-wire m_bypass_enable;
-output read_enable_0;
-wire read_enable_0;
-output [`LM32_REG_IDX_RNG] read_idx_0;
-wire [`LM32_REG_IDX_RNG] read_idx_0;
-output read_enable_1;
-wire read_enable_1;
-output [`LM32_REG_IDX_RNG] read_idx_1;
-wire [`LM32_REG_IDX_RNG] read_idx_1;
-output write_enable;
-wire write_enable;
-output [`LM32_REG_IDX_RNG] write_idx;
-wire [`LM32_REG_IDX_RNG] write_idx;
-output [`LM32_WORD_RNG] immediate;
-wire [`LM32_WORD_RNG] immediate;
-output [`LM32_PC_RNG] branch_offset;
-wire [`LM32_PC_RNG] branch_offset;
-output load;
-wire load;
-output store;
-wire store;
-output [`LM32_SIZE_RNG] size;
-wire [`LM32_SIZE_RNG] size;
-output sign_extend;
-wire sign_extend;
-output adder_op;
-wire adder_op;
-output [`LM32_LOGIC_OP_RNG] logic_op;
-wire [`LM32_LOGIC_OP_RNG] logic_op;
-`ifdef CFG_PL_BARREL_SHIFT_ENABLED
-output direction;
-wire direction;
-`endif
-`ifdef CFG_MC_BARREL_SHIFT_ENABLED
-output shift_left;
-wire shift_left;
-output shift_right;
-wire shift_right;
-`endif
-`ifdef CFG_MC_MULTIPLY_ENABLED
-output multiply;
-wire multiply;
-`endif
-`ifdef CFG_MC_DIVIDE_ENABLED
-output divide;
-wire divide;
-output modulus;
-wire modulus;
-`endif
-output branch;
-wire branch;
-output branch_reg;
-wire branch_reg;
-output [`LM32_CONDITION_RNG] condition;
-wire [`LM32_CONDITION_RNG] condition;
-output bi_conditional;
-wire bi_conditional;
-output bi_unconditional;
-wire bi_unconditional;
-`ifdef CFG_DEBUG_ENABLED
-output break_opcode;
-wire break_opcode;
-`endif
-output scall;
-wire scall;
-output eret;
-wire eret;
-`ifdef CFG_DEBUG_ENABLED
-output bret;
-wire bret;
-`endif
-`ifdef CFG_USER_ENABLED
-output [`LM32_USER_OPCODE_RNG] user_opcode;
-wire [`LM32_USER_OPCODE_RNG] user_opcode;
-`endif
-output csr_write_enable;
-wire csr_write_enable;
-
-/////////////////////////////////////////////////////
-// Internal nets and registers
-/////////////////////////////////////////////////////
-
-wire [`LM32_WORD_RNG] extended_immediate; // Zero or sign extended immediate
-wire [`LM32_WORD_RNG] high_immediate; // Immediate as high 16 bits
-wire [`LM32_WORD_RNG] call_immediate; // Call immediate
-wire [`LM32_WORD_RNG] branch_immediate; // Conditional branch immediate
-wire sign_extend_immediate; // Whether the immediate should be sign extended (`TRUE) or zero extended (`FALSE)
-wire select_high_immediate; // Whether to select the high immediate
-wire select_call_immediate; // Whether to select the call immediate
-
-/////////////////////////////////////////////////////
-// Functions
-/////////////////////////////////////////////////////
-
-/////////////////////////////////////////////////////
-// Combinational logic
-/////////////////////////////////////////////////////
-
-// Determine opcode
-assign op_add = instruction[`LM32_OP_RNG] == `LM32_OPCODE_ADD;
-assign op_and = instruction[`LM32_OP_RNG] == `LM32_OPCODE_AND;
-assign op_andhi = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_ANDHI;
-assign op_b = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_B;
-assign op_bi = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_BI;
-assign op_be = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_BE;
-assign op_bg = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_BG;
-assign op_bge = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_BGE;
-assign op_bgeu = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_BGEU;
-assign op_bgu = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_BGU;
-assign op_bne = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_BNE;
-assign op_call = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_CALL;
-assign op_calli = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_CALLI;
-assign op_cmpe = instruction[`LM32_OP_RNG] == `LM32_OPCODE_CMPE;
-assign op_cmpg = instruction[`LM32_OP_RNG] == `LM32_OPCODE_CMPG;
-assign op_cmpge = instruction[`LM32_OP_RNG] == `LM32_OPCODE_CMPGE;
-assign op_cmpgeu = instruction[`LM32_OP_RNG] == `LM32_OPCODE_CMPGEU;
-assign op_cmpgu = instruction[`LM32_OP_RNG] == `LM32_OPCODE_CMPGU;
-assign op_cmpne = instruction[`LM32_OP_RNG] == `LM32_OPCODE_CMPNE;
-`ifdef CFG_MC_DIVIDE_ENABLED
-assign op_divu = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_DIVU;
-`endif
-assign op_lb = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_LB;
-assign op_lbu = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_LBU;
-assign op_lh = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_LH;
-assign op_lhu = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_LHU;
-assign op_lw = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_LW;
-`ifdef CFG_MC_DIVIDE_ENABLED
-assign op_modu = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_MODU;
-`endif
-`ifdef LM32_MULTIPLY_ENABLED
-assign op_mul = instruction[`LM32_OP_RNG] == `LM32_OPCODE_MUL;
-`endif
-assign op_nor = instruction[`LM32_OP_RNG] == `LM32_OPCODE_NOR;
-assign op_or = instruction[`LM32_OP_RNG] == `LM32_OPCODE_OR;
-assign op_orhi = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_ORHI;
-assign op_raise = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_RAISE;
-assign op_rcsr = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_RCSR;
-assign op_sb = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_SB;
-`ifdef CFG_SIGN_EXTEND_ENABLED
-assign op_sextb = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_SEXTB;
-assign op_sexth = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_SEXTH;
-`endif
-assign op_sh = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_SH;
-`ifdef LM32_BARREL_SHIFT_ENABLED
-assign op_sl = instruction[`LM32_OP_RNG] == `LM32_OPCODE_SL;
-`endif
-assign op_sr = instruction[`LM32_OP_RNG] == `LM32_OPCODE_SR;
-assign op_sru = instruction[`LM32_OP_RNG] == `LM32_OPCODE_SRU;
-assign op_sub = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_SUB;
-assign op_sw = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_SW;
-assign op_user = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_USER;
-assign op_wcsr = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_WCSR;
-assign op_xnor = instruction[`LM32_OP_RNG] == `LM32_OPCODE_XNOR;
-assign op_xor = instruction[`LM32_OP_RNG] == `LM32_OPCODE_XOR;
-
-// Group opcodes by function
-assign arith = op_add | op_sub;
-assign logical = op_and | op_andhi | op_nor | op_or | op_orhi | op_xor | op_xnor;
-assign cmp = op_cmpe | op_cmpg | op_cmpge | op_cmpgeu | op_cmpgu | op_cmpne;
-assign bi_conditional = op_be | op_bg | op_bge | op_bgeu | op_bgu | op_bne;
-assign bi_unconditional = op_bi;
-assign bra = op_b | bi_unconditional | bi_conditional;
-assign call = op_call | op_calli;
-`ifdef LM32_BARREL_SHIFT_ENABLED
-assign shift = op_sl | op_sr | op_sru;
-`endif
-`ifdef LM32_NO_BARREL_SHIFT
-assign shift = op_sr | op_sru;
-`endif
-`ifdef CFG_MC_BARREL_SHIFT_ENABLED
-assign shift_left = op_sl;
-assign shift_right = op_sr | op_sru;
-`endif
-`ifdef CFG_SIGN_EXTEND_ENABLED
-assign sext = op_sextb | op_sexth;
-`endif
-`ifdef LM32_MULTIPLY_ENABLED
-assign multiply = op_mul;
-`endif
-`ifdef CFG_MC_DIVIDE_ENABLED
-assign divide = op_divu;
-assign modulus = op_modu;
-`endif
-assign load = op_lb | op_lbu | op_lh | op_lhu | op_lw;
-assign store = op_sb | op_sh | op_sw;
-
-// Select pipeline multiplexor controls
-always @(*)
-begin
- // D stage
- if (call)
- d_result_sel_0 = `LM32_D_RESULT_SEL_0_NEXT_PC;
- else
- d_result_sel_0 = `LM32_D_RESULT_SEL_0_REG_0;
- if (call)
- d_result_sel_1 = `LM32_D_RESULT_SEL_1_ZERO;
- else if ((instruction[31] == 1'b0) && !bra)
- d_result_sel_1 = `LM32_D_RESULT_SEL_1_IMMEDIATE;
- else
- d_result_sel_1 = `LM32_D_RESULT_SEL_1_REG_1;
- // X stage
- x_result_sel_csr = `FALSE;
-`ifdef LM32_MC_ARITHMETIC_ENABLED
- x_result_sel_mc_arith = `FALSE;
-`endif
-`ifdef LM32_NO_BARREL_SHIFT
- x_result_sel_shift = `FALSE;
-`endif
-`ifdef CFG_SIGN_EXTEND_ENABLED
- x_result_sel_sext = `FALSE;
-`endif
- x_result_sel_logic = `FALSE;
-`ifdef CFG_USER_ENABLED
- x_result_sel_user = `FALSE;
-`endif
- x_result_sel_add = `FALSE;
- if (op_rcsr)
- x_result_sel_csr = `TRUE;
-`ifdef LM32_MC_ARITHMETIC_ENABLED
-`ifdef CFG_MC_BARREL_SHIFT_ENABLED
- else if (shift_left | shift_right)
- x_result_sel_mc_arith = `TRUE;
-`endif
-`ifdef CFG_MC_DIVIDE_ENABLED
- else if (divide | modulus)
- x_result_sel_mc_arith = `TRUE;
-`endif
-`ifdef CFG_MC_MULTIPLY_ENABLED
- else if (multiply)
- x_result_sel_mc_arith = `TRUE;
-`endif
-`endif
-`ifdef LM32_NO_BARREL_SHIFT
- else if (shift)
- x_result_sel_shift = `TRUE;
-`endif
-`ifdef CFG_SIGN_EXTEND_ENABLED
- else if (sext)
- x_result_sel_sext = `TRUE;
-`endif
- else if (logical)
- x_result_sel_logic = `TRUE;
-`ifdef CFG_USER_ENABLED
- else if (op_user)
- x_result_sel_user = `TRUE;
-`endif
- else
- x_result_sel_add = `TRUE;
-
- // M stage
-
- m_result_sel_compare = cmp;
-`ifdef CFG_PL_BARREL_SHIFT_ENABLED
- m_result_sel_shift = shift;
-`endif
-
- // W stage
- w_result_sel_load = load;
-`ifdef CFG_PL_MULTIPLY_ENABLED
- w_result_sel_mul = op_mul;
-`endif
-end
-
-// Set if result is valid at end of X stage
-assign x_bypass_enable = arith
- | logical
-`ifdef CFG_MC_BARREL_SHIFT_ENABLED
- | shift_left
- | shift_right
-`endif
-`ifdef CFG_MC_MULTIPLY_ENABLED
- | multiply
-`endif
-`ifdef CFG_MC_DIVIDE_ENABLED
- | divide
- | modulus
-`endif
-`ifdef LM32_NO_BARREL_SHIFT
- | shift
-`endif
-`ifdef CFG_SIGN_EXTEND_ENABLED
- | sext
-`endif
-`ifdef CFG_USER_ENABLED
- | op_user
-`endif
- | op_rcsr
- ;
-// Set if result is valid at end of M stage
-assign m_bypass_enable = x_bypass_enable
-`ifdef CFG_PL_BARREL_SHIFT_ENABLED
- | shift
-`endif
- | cmp
- ;
-// Register file read port 0
-assign read_enable_0 = ~(op_bi | op_calli);
-assign read_idx_0 = instruction[25:21];
-// Register file read port 1
-assign read_enable_1 = ~(op_bi | op_calli | load);
-assign read_idx_1 = instruction[20:16];
-// Register file write port
-assign write_enable = ~(bra | op_raise | store | op_wcsr);
-assign write_idx = call
- ? 5'd29
- : instruction[31] == 1'b0
- ? instruction[20:16]
- : instruction[15:11];
-
-// Size of load/stores
-assign size = instruction[27:26];
-// Whether to sign or zero extend
-assign sign_extend = instruction[28];
-// Set adder_op to 1 to perform a subtraction
-assign adder_op = op_sub | op_cmpe | op_cmpg | op_cmpge | op_cmpgeu | op_cmpgu | op_cmpne | bra;
-// Logic operation (and, or, etc)
-assign logic_op = instruction[29:26];
-`ifdef CFG_PL_BARREL_SHIFT_ENABLED
-// Shift direction
-assign direction = instruction[29];
-`endif
-// Control flow microcodes
-assign branch = bra | call;
-assign branch_reg = op_call | op_b;
-assign condition = instruction[28:26];
-`ifdef CFG_DEBUG_ENABLED
-assign break_opcode = op_raise & ~instruction[2];
-`endif
-assign scall = op_raise & instruction[2];
-assign eret = op_b & (instruction[25:21] == 5'd30);
-`ifdef CFG_DEBUG_ENABLED
-assign bret = op_b & (instruction[25:21] == 5'd31);
-`endif
-`ifdef CFG_USER_ENABLED
-// Extract user opcode
-assign user_opcode = instruction[10:0];
-`endif
-// CSR read/write
-assign csr_write_enable = op_wcsr;
-
-// Extract immediate from instruction
-
-assign sign_extend_immediate = ~(op_and | op_cmpgeu | op_cmpgu | op_nor | op_or | op_xnor | op_xor);
-assign select_high_immediate = op_andhi | op_orhi;
-assign select_call_immediate = instruction[31];
-
-assign high_immediate = {instruction[15:0], 16'h0000};
-assign extended_immediate = {{16{sign_extend_immediate & instruction[15]}}, instruction[15:0]};
-assign call_immediate = {{6{instruction[25]}}, instruction[25:0]};
-assign branch_immediate = {{16{instruction[15]}}, instruction[15:0]};
-
-assign immediate = select_high_immediate == `TRUE
- ? high_immediate
- : extended_immediate;
-
-assign branch_offset = select_call_immediate == `TRUE
- ? call_immediate
- : branch_immediate;
-
-endmodule
-
View
66 verilog/lm32/lm32_dp_ram.v
@@ -1,66 +0,0 @@
-/////////////////////////////////////////////////////
-// Module interface
-/////////////////////////////////////////////////////
-
-module lm32_dp_ram(
- // ----- Inputs -----
- clk_i,
- rst_i,
- we_i,
- waddr_i,
- wdata_i,
- raddr_i,
- // ----- Outputs -----
- rdata_o
-);
-
-/////////////////////////////////////////////////////
-// Parameters
-/////////////////////////////////////////////////////
-
-parameter data_width = 1; // Width of the data ports
-parameter addr_width = 1; // Width of the address ports
-
-/////////////////////////////////////////////////////
-// Inputs
-/////////////////////////////////////////////////////
-
-input clk_i;
-input rst_i;
-input we_i;
-input [addr_width-1:0] waddr_i;
-input [data_width-1:0] wdata_i;
-input [addr_width-1:0] raddr_i;
-
-/////////////////////////////////////////////////////
-// Outputs
-/////////////////////////////////////////////////////
-
-output [data_width-1:0] rdata_o;
-
-/////////////////////////////////////////////////////
-// Internal nets and registers
-/////////////////////////////////////////////////////
-
-reg [data_width-1:0] mem[(1<<addr_width)-1:0];
-reg [addr_width-1:0] raddr_r;
-
-/////////////////////////////////////////////////////
-// Combinational logic
-/////////////////////////////////////////////////////
-
-assign rdata_o = mem[raddr_r];
-
-/////////////////////////////////////////////////////
-// Sequential logic
-/////////////////////////////////////////////////////
-
-always @(posedge clk_i)
-begin
- if (we_i)
- mem[waddr_i] <= wdata_i;
- raddr_r <= raddr_i;
-end
-
-endmodule
-
View
479 verilog/lm32/lm32_icache.v
@@ -1,479 +0,0 @@
-// ==================================================================
-// >>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
-// ------------------------------------------------------------------
-// Copyright (c) 2006-2011 by Lattice Semiconductor Corporation
-// ALL RIGHTS RESERVED
-// ------------------------------------------------------------------
-//
-// IMPORTANT: THIS FILE IS AUTO-GENERATED BY THE LATTICEMICO SYSTEM.
-//
-// Permission:
-//
-// Lattice Semiconductor grants permission to use this code
-// pursuant to the terms of the Lattice Semiconductor Corporation
-// Open Source License Agreement.
-//
-// Disclaimer:
-//
-// Lattice Semiconductor provides no warranty regarding the use or
-// functionality of this code. It is the user's responsibility to
-// verify the user's design for consistency and functionality through
-// the use of formal verification methods.
-//
-// --------------------------------------------------------------------
-//
-// Lattice Semiconductor Corporation
-// 5555 NE Moore Court
-// Hillsboro, OR 97214
-// U.S.A
-//
-// TEL: 1-800-Lattice (USA and Canada)
-// 503-286-8001 (other locations)
-//
-// web: http://www.latticesemi.com/
-// email: techsupport@latticesemi.com
-//
-// --------------------------------------------------------------------
-// FILE DETAILS
-// Project : LatticeMico32
-// File : lm32_icache.v
-// Title : Instruction cache
-// Dependencies : lm32_include.v
-//
-// Version 3.5
-// 1. Bug Fix: Instruction cache flushes issued from Instruction Inline Memory
-// cause segmentation fault due to incorrect fetches.
-//
-// Version 3.1
-// 1. Feature: Support for user-selected resource usage when implementing
-// cache memory. Additional parameters must be defined when invoking module
-// lm32_ram. Instruction cache miss mechanism is dependent on branch
-// prediction being performed in D stage of pipeline.
-//
-// Version 7.0SP2, 3.0
-// No change
-// =============================================================================
-
-`include "lm32_include.v"
-
-`ifdef CFG_ICACHE_ENABLED
-
-`define LM32_IC_ADDR_OFFSET_RNG addr_offset_msb:addr_offset_lsb
-`define LM32_IC_ADDR_SET_RNG addr_set_msb:addr_set_lsb
-`define LM32_IC_ADDR_TAG_RNG addr_tag_msb:addr_tag_lsb
-`define LM32_IC_ADDR_IDX_RNG addr_set_msb:addr_offset_lsb
-
-`define LM32_IC_TMEM_ADDR_WIDTH addr_set_width
-`define LM32_IC_TMEM_ADDR_RNG (`LM32_IC_TMEM_ADDR_WIDTH-1):0
-`define LM32_IC_DMEM_ADDR_WIDTH (addr_offset_width+addr_set_width)
-`define LM32_IC_DMEM_ADDR_RNG (`LM32_IC_DMEM_ADDR_WIDTH-1):0
-
-`define LM32_IC_TAGS_WIDTH (addr_tag_width+1)
-`define LM32_IC_TAGS_RNG (`LM32_IC_TAGS_WIDTH-1):0
-`define LM32_IC_TAGS_TAG_RNG (`LM32_IC_TAGS_WIDTH-1):1
-`define LM32_IC_TAGS_VALID_RNG 0
-
-`define LM32_IC_STATE_RNG 3:0
-`define LM32_IC_STATE_FLUSH_INIT 4'b0001
-`define LM32_IC_STATE_FLUSH 4'b0010
-`define LM32_IC_STATE_CHECK 4'b0100
-`define LM32_IC_STATE_REFILL 4'b1000
-
-/////////////////////////////////////////////////////
-// Module interface
-/////////////////////////////////////////////////////
-
-module lm32_icache (
- // ----- Inputs -----
- clk_i,
- rst_i,
- stall_a,
- stall_f,
- address_a,
- address_f,
- read_enable_f,
- refill_ready,
- refill_data,
- iflush,
-`ifdef CFG_IROM_ENABLED
- select_f,
-`endif
- valid_d,
- branch_predict_taken_d,
- // ----- Outputs -----
- stall_request,
- restart_request,
- refill_request,
- refill_address,
- refilling,
- inst
- );
-
-/////////////////////////////////////////////////////
-// Parameters
-/////////////////////////////////////////////////////
-
-parameter associativity = 1; // Associativity of the cache (Number of ways)
-parameter sets = 512; // Number of sets
-parameter bytes_per_line = 16; // Number of bytes per cache line
-parameter base_address = 0; // Base address of cachable memory
-parameter limit = 0; // Limit (highest address) of cachable memory
-
-localparam addr_offset_width = `CLOG2(bytes_per_line)-2;
-localparam addr_set_width = `CLOG2(sets);
-localparam addr_offset_lsb = 2;
-localparam addr_offset_msb = (addr_offset_lsb+addr_offset_width-1);
-localparam addr_set_lsb = (addr_offset_msb+1);
-localparam addr_set_msb = (addr_set_lsb+addr_set_width-1);
-localparam addr_tag_lsb = (addr_set_msb+1);
-localparam addr_tag_msb = `CLOG2(`CFG_ICACHE_LIMIT-`CFG_ICACHE_BASE_ADDRESS);
-localparam addr_tag_width = (addr_tag_msb-addr_tag_lsb+1);
-
-/////////////////////////////////////////////////////
-// Inputs
-/////////////////////////////////////////////////////
-
-input clk_i; // Clock
-input rst_i; // Reset
-
-input stall_a; // Stall instruction in A stage
-input stall_f; // Stall instruction in F stage
-
-input valid_d; // Valid instruction in D stage
-input branch_predict_taken_d; // Instruction in D stage is a branch and is predicted taken
-
-input [`LM32_PC_RNG] address_a; // Address of instruction in A stage
-input [`LM32_PC_RNG] address_f; // Address of instruction in F stage
-input read_enable_f; // Indicates if cache access is valid
-
-input refill_ready; // Next word of refill data is ready
-input [`LM32_INSTRUCTION_RNG] refill_data; // Data to refill the cache with
-
-input iflush; // Flush the cache
-`ifdef CFG_IROM_ENABLED
-input select_f; // Instruction in F stage is mapped through instruction cache
-`endif
-
-/////////////////////////////////////////////////////
-// Outputs
-/////////////////////////////////////////////////////
-
-output stall_request; // Request to stall the pipeline
-wire stall_request;
-output restart_request; // Request to restart instruction that caused the cache miss
-reg restart_request;
-output refill_request; // Request to refill a cache line
-wire refill_request;
-output [`LM32_PC_RNG] refill_address; // Base address of cache refill
-reg [`LM32_PC_RNG] refill_address;
-output refilling; // Indicates the instruction cache is currently refilling
-reg refilling;
-output [`LM32_INSTRUCTION_RNG] inst; // Instruction read from cache
-wire [`LM32_INSTRUCTION_RNG] inst;
-
-/////////////////////////////////////////////////////
-// Internal nets and registers
-/////////////////////////////////////////////////////
-
-wire enable;
-wire [0:associativity-1] way_mem_we;
-wire [`LM32_INSTRUCTION_RNG] way_data[0:associativity-1];
-wire [`LM32_IC_TAGS_TAG_RNG] way_tag[0:associativity-1];
-wire [0:associativity-1] way_valid;
-wire [0:associativity-1] way_match;
-wire miss;
-
-wire [`LM32_IC_TMEM_ADDR_RNG] tmem_read_address;
-wire [`LM32_IC_TMEM_ADDR_RNG] tmem_write_address;
-wire [`LM32_IC_DMEM_ADDR_RNG] dmem_read_address;
-wire [`LM32_IC_DMEM_ADDR_RNG] dmem_write_address;
-wire [`LM32_IC_TAGS_RNG] tmem_write_data;
-
-reg [`LM32_IC_STATE_RNG] state;
-wire flushing;
-wire check;
-wire refill;
-
-reg [associativity-1:0] refill_way_select;
-reg [`LM32_IC_ADDR_OFFSET_RNG] refill_offset;
-wire last_refill;
-reg [`LM32_IC_TMEM_ADDR_RNG] flush_set;
-
-genvar i;
-
-/////////////////////////////////////////////////////
-// Functions
-/////////////////////////////////////////////////////
-
-/////////////////////////////////////////////////////
-// Instantiations
-/////////////////////////////////////////////////////
-
- generate
- for (i = 0; i < associativity; i = i + 1)
- begin : memories
-
- lm32_ram
- #(
- // ----- Parameters -------
- .data_width (32),
- .address_width (`LM32_IC_DMEM_ADDR_WIDTH)
-// Modified for Milkymist: removed non-portable RAM parameters
-)
- way_0_data_ram
- (
- // ----- Inputs -------
- .read_clk (clk_i),
- .write_clk (clk_i),
- .reset (rst_i),
- .read_address (dmem_read_address),
- .enable_read (enable),
- .write_address (dmem_write_address),
- .enable_write (`TRUE),
- .write_enable (way_mem_we[i]),
- .write_data (refill_data),
- // ----- Outputs -------
- .read_data (way_data[i])
- );
-
- lm32_ram
- #(
- // ----- Parameters -------
- .data_width (`LM32_IC_TAGS_WIDTH),
- .address_width (`LM32_IC_TMEM_ADDR_WIDTH)
-// Modified for Milkymist: removed non-portable RAM parameters
- )
- way_0_tag_ram
- (
- // ----- Inputs -------
- .read_clk (clk_i),
- .write_clk (clk_i),
- .reset (rst_i),
- .read_address (tmem_read_address),
- .enable_read (enable),
- .write_address (tmem_write_address),
- .enable_write (`TRUE),
- .write_enable (way_mem_we[i] | flushing),
- .write_data (tmem_write_data),
- // ----- Outputs -------
- .read_data ({way_tag[i], way_valid[i]})
- );
-
- end
-endgenerate
-
-/////////////////////////////////////////////////////
-// Combinational logic
-/////////////////////////////////////////////////////
-
-// Compute which ways in the cache match the address address being read
-generate
- for (i = 0; i < associativity; i = i + 1)
- begin : match
-assign way_match[i] = ({way_tag[i], way_valid[i]} == {address_f[`LM32_IC_ADDR_TAG_RNG], `TRUE});
- end
-endgenerate
-
-// Select data from way that matched the address being read
-generate
- if (associativity == 1)
- begin : inst_1
-assign inst = way_match[0] ? way_data[0] : 32'b0;
- end
- else if (associativity == 2)
- begin : inst_2
-assign inst = way_match[0] ? way_data[0] : (way_match[1] ? way_data[1] : 32'b0);
- end
-endgenerate
-
-// Compute address to use to index into the data memories
-generate
- if (bytes_per_line > 4)
-assign dmem_write_address = {refill_address[`LM32_IC_ADDR_SET_RNG], refill_offset};
- else
-assign dmem_write_address = refill_address[`LM32_IC_ADDR_SET_RNG];
-endgenerate
-
-assign dmem_read_address = address_a[`LM32_IC_ADDR_IDX_RNG];
-
-// Compute address to use to index into the tag memories
-assign tmem_read_address = address_a[`LM32_IC_ADDR_SET_RNG];
-assign tmem_write_address = flushing
- ? flush_set
- : refill_address[`LM32_IC_ADDR_SET_RNG];
-
-// Compute signal to indicate when we are on the last refill accesses
-generate