Skip to content

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
  • 11 commits
  • 20 files changed
  • 0 commit comments
  • 1 contributor
Commits on Nov 14, 2012
@mwalle mwalle lm32: replace clogb2 by builtin $clog2
This function is fixed in ISE since version 14.1 (see AR #44586). If the
builtin function is used, the design can be simulated with Icarus Verilog.

Signed-off-by: Michael Walle <michael@walle.cc>
83c735b
@mwalle mwalle lm32: rename mem array in lm32_dp_ram
Be compatible with original proprietary DP RAM instantiation. This is
needed for simulation, where r0 is initialized to zero in lm32_cpu.v.

Signed-off-by: Michael Walle <michael@walle.cc>
531a968
@mwalle mwalle lm32: remove unneeded parameter in lm32_dp_ram
addr_depth can be computed by addr_width.

Signed-off-by: Michael Walle <michael@walle.cc>
1fad281
@mwalle mwalle lm32: fix documentation style
Signed-off-by: Michael Walle <michael@walle.cc>
c4360b6
@mwalle mwalle lm32: add lm32 test bench
Signed-off-by: Michael Walle <michael@walle.cc>
890d62c
@mwalle mwalle lm32: clear memories in testbench
Signed-off-by: Michael Walle <michael@walle.cc>
fe1373a
@mwalle mwalle lm32: add pipeline tracing to testbench
Signed-off-by: Michael Walle <michael@walle.cc>
f7e767e
@mwalle mwalle lm32: add simple pipe test program
Signed-off-by: Michael Walle <michael@walle.cc>
edf14a2
@mwalle mwalle lm32: split lm32_include.v
Split lm32_include.v into common defines and actual processor
configuration. Put the first module into the rtl/ directory.

Signed-off-by: Michael Walle <michael@walle.cc>
57a283c
@mwalle mwalle lm32: replace $clog2 with macro
Unfortunately, XST does not support $clog2 with the localparam keyword
(the parameter keyword works just fine). Define a macro which replaces the
call with a constant function.

This commit can be reverted if the bug in XST is fixed.

Signed-off-by: Michael Walle <michael@walle.cc>
abbad88
@mwalle mwalle lm32: fix test bench
If simulation run with caches disabled, the test bench will throw errors.
Fix this.

Signed-off-by: Michael Walle <michael@walle.cc>
254f48b
View
55 boards/milkymist-one/rtl/lm32_config.v
@@ -0,0 +1,55 @@
+`ifdef LM32_CONFIG_V
+`else
+`define LM32_CONFIG_V
+
+`ifdef RESCUE
+`define CFG_EBA_RESET 32'h00220000
+`define CFG_DEBA_RESET 32'h10000000
+`else
+`define CFG_EBA_RESET 32'h00860000
+`define CFG_DEBA_RESET 32'h10000000
+`endif
+
+`define CFG_PL_MULTIPLY_ENABLED
+`define CFG_PL_BARREL_SHIFT_ENABLED
+`define CFG_SIGN_EXTEND_ENABLED
+`define CFG_MC_DIVIDE_ENABLED
+`define CFG_EBR_POSEDGE_REGISTER_FILE
+
+`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_LIMIT 32'h7fffffff
+
+`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_LIMIT 32'h7fffffff
+
+// Enable Debugging
+//`define CFG_JTAG_ENABLED
+//`define CFG_JTAG_UART_ENABLED
+`define CFG_DEBUG_ENABLED
+//`define CFG_HW_DEBUG_ENABLED
+`define CFG_ROM_DEBUG_ENABLED
+`define CFG_BREAKPOINTS 32'h4
+`define CFG_WATCHPOINTS 32'h4
+`define CFG_EXTERNAL_BREAK_ENABLED
+`define CFG_GDBSTUB_ENABLED
+
+function integer clog2;
+ input integer value;
+ begin
+ value = value - 1;
+ for (clog2 = 0; value > 0; clog2 = clog2 + 1)
+ value = value >> 1;
+ end
+endfunction
+
+`define CLOG2 clog2
+
+`endif
View
1 boards/milkymist-one/sources.mak
@@ -3,6 +3,7 @@ BOARD_SRC=$(wildcard $(BOARD_DIR)/*.v) $(BOARD_DIR)/../../gen_capabilities.v
ASFIFO_SRC=$(wildcard $(CORES_DIR)/asfifo/rtl/*.v)
CONBUS_SRC=$(wildcard $(CORES_DIR)/conbus/rtl/*.v)
LM32_SRC= \
+ $(CORES_DIR)/lm32/rtl/lm32_include.v \
$(CORES_DIR)/lm32/rtl/lm32_cpu.v \
$(CORES_DIR)/lm32/rtl/lm32_instruction_unit.v \
$(CORES_DIR)/lm32/rtl/lm32_decoder.v \
View
4 cores/lm32/rtl/lm32_cpu.v
@@ -780,8 +780,6 @@ reg ext_break_r;
// Functions
/////////////////////////////////////////////////////
-`include "lm32_functions.v"
-
/////////////////////////////////////////////////////
// Instantiations
/////////////////////////////////////////////////////
@@ -1326,7 +1324,6 @@ lm32_debug #(
lm32_dp_ram
#(
// ----- Parameters -----
- .addr_depth(1<<5),
.addr_width(5),
.data_width(32)
)
@@ -1345,7 +1342,6 @@ lm32_debug #(
lm32_dp_ram
#(
- .addr_depth(1<<5),
.addr_width(5),
.data_width(32)
)
View
8 cores/lm32/rtl/lm32_dcache.v
@@ -112,14 +112,14 @@ parameter bytes_per_line = 16; // Number of bytes per c
parameter base_address = 0; // Base address of cachable memory
parameter limit = 0; // Limit (highest address) of cachable memory
-localparam addr_offset_width = clogb2(bytes_per_line)-1-2;
-localparam addr_set_width = clogb2(sets)-1;
+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 = clogb2(`CFG_DCACHE_LIMIT-`CFG_DCACHE_BASE_ADDRESS)-1;
+localparam addr_tag_msb = `CLOG2(`CFG_DCACHE_LIMIT-`CFG_DCACHE_BASE_ADDRESS);
localparam addr_tag_width = (addr_tag_msb-addr_tag_lsb+1);
/////////////////////////////////////////////////////
@@ -200,8 +200,6 @@ genvar i, j;
// Functions
/////////////////////////////////////////////////////
-`include "lm32_functions.v"
-
/////////////////////////////////////////////////////
// Instantiations
/////////////////////////////////////////////////////
View
2 cores/lm32/rtl/lm32_debug.v
@@ -183,8 +183,6 @@ integer state; // State of single-step FSM
// Functions
/////////////////////////////////////////////////////
-`include "lm32_functions.v"
-
/////////////////////////////////////////////////////
// Combinational Logic
/////////////////////////////////////////////////////
View
2 cores/lm32/rtl/lm32_decoder.v
@@ -333,8 +333,6 @@ wire select_call_immediate; // Whether to select the call im
// Functions
/////////////////////////////////////////////////////
-`include "lm32_functions.v"
-
/////////////////////////////////////////////////////
// Combinational logic
/////////////////////////////////////////////////////
View
47 cores/lm32/rtl/lm32_dp_ram.v
@@ -1,15 +1,29 @@
+/////////////////////////////////////////////////////
+// Module interface
+/////////////////////////////////////////////////////
+
module lm32_dp_ram(
+ // ----- Inputs -----
clk_i,
rst_i,
we_i,
waddr_i,
wdata_i,
raddr_i,
- rdata_o);
+ // ----- Outputs -----
+ rdata_o
+);
+
+/////////////////////////////////////////////////////
+// Parameters
+/////////////////////////////////////////////////////
-parameter addr_width = 32;
-parameter addr_depth = 1024;
-parameter data_width = 8;
+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;
@@ -17,17 +31,34 @@ 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;
-reg [data_width-1:0] ram[addr_depth-1:0];
+/////////////////////////////////////////////////////
+// Internal nets and registers
+/////////////////////////////////////////////////////
+reg [data_width-1:0] mem[(1<<addr_width)-1:0];
reg [addr_width-1:0] raddr_r;
-assign rdata_o = ram[raddr_r];
-always @ (posedge clk_i)
+/////////////////////////////////////////////////////
+// Combinational logic
+/////////////////////////////////////////////////////
+
+assign rdata_o = mem[raddr_r];
+
+/////////////////////////////////////////////////////
+// Sequential logic
+/////////////////////////////////////////////////////
+
+always @(posedge clk_i)
begin
if (we_i)
- ram[waddr_i] <= wdata_i;
+ mem[waddr_i] <= wdata_i;
raddr_r <= raddr_i;
end
View
70 cores/lm32/rtl/lm32_functions.v
@@ -1,70 +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_functions.v
-// Title : Common functions
-// Version : 6.1.17
-// : Initial Release
-// Version : 7.0SP2, 3.0
-// : No Change
-// Version : 3.5
-// : Added function to generate log-of-two that rounds-up to
-// : power-of-two
-// =============================================================================
-
-function integer clogb2;
-input [31:0] value;
-begin
- for (clogb2 = 0; value > 0; clogb2 = clogb2 + 1)
- value = value >> 1;
-end
-endfunction
-
-function integer clogb2_v1;
-input [31:0] value;
-reg [31:0] i;
-reg [31:0] temp;
-begin
- temp = 0;
- i = 0;
- for (i = 0; temp < value; i = i + 1)
- temp = 1<<i;
- clogb2_v1 = i-1;
-end
-endfunction
-
View
8 cores/lm32/rtl/lm32_icache.v
@@ -119,14 +119,14 @@ parameter bytes_per_line = 16; // Number of bytes per c
parameter base_address = 0; // Base address of cachable memory
parameter limit = 0; // Limit (highest address) of cachable memory
-localparam addr_offset_width = clogb2(bytes_per_line)-1-2;
-localparam addr_set_width = clogb2(sets)-1;
+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 = clogb2(`CFG_ICACHE_LIMIT-`CFG_ICACHE_BASE_ADDRESS)-1;
+localparam addr_tag_msb = `CLOG2(`CFG_ICACHE_LIMIT-`CFG_ICACHE_BASE_ADDRESS);
localparam addr_tag_width = (addr_tag_msb-addr_tag_lsb+1);
/////////////////////////////////////////////////////
@@ -205,8 +205,6 @@ genvar i;
// Functions
/////////////////////////////////////////////////////
-`include "lm32_functions.v"
-
/////////////////////////////////////////////////////
// Instantiations
/////////////////////////////////////////////////////
View
49 boards/milkymist-one/rtl/lm32_include.v → cores/lm32/rtl/lm32_include.v
@@ -2,7 +2,7 @@
// >>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
// ------------------------------------------------------------------
// Copyright (c) 2006-2011 by Lattice Semiconductor Corporation
-// ALL RIGHTS RESERVED
+// ALL RIGHTS RESERVED
// ------------------------------------------------------------------
//
// IMPORTANT: THIS FILE IS AUTO-GENERATED BY THE LATTICEMICO SYSTEM.
@@ -11,7 +11,7 @@
//
// Lattice Semiconductor grants permission to use this code
// pursuant to the terms of the Lattice Semiconductor Corporation
-// Open Source License Agreement.
+// Open Source License Agreement.
//
// Disclaimer:
//
@@ -58,44 +58,7 @@
// Common configuration options
//
-`ifdef RESCUE
-`define CFG_EBA_RESET 32'h00220000
-`define CFG_DEBA_RESET 32'h10000000
-`else
-`define CFG_EBA_RESET 32'h00860000
-`define CFG_DEBA_RESET 32'h10000000
-`endif
-
-`define CFG_PL_MULTIPLY_ENABLED
-`define CFG_PL_BARREL_SHIFT_ENABLED
-`define CFG_SIGN_EXTEND_ENABLED
-`define CFG_MC_DIVIDE_ENABLED
-`define CFG_EBR_POSEDGE_REGISTER_FILE
-
-`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_LIMIT 32'h7fffffff
-
-`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_LIMIT 32'h7fffffff
-
-// Enable Debugging
-//`define CFG_JTAG_ENABLED
-//`define CFG_JTAG_UART_ENABLED
-`define CFG_DEBUG_ENABLED
-//`define CFG_HW_DEBUG_ENABLED
-`define CFG_ROM_DEBUG_ENABLED
-`define CFG_BREAKPOINTS 32'h4
-`define CFG_WATCHPOINTS 32'h4
-`define CFG_EXTERNAL_BREAK_ENABLED
-`define CFG_GDBSTUB_ENABLED
+`include "lm32_config.v"
//
// End of common configuration options
@@ -131,7 +94,7 @@
`define LM32_EA_REG `LM32_REG_IDX_WIDTH'd30
`define LM32_BA_REG `LM32_REG_IDX_WIDTH'd31
-// Range of Program Counter. Two LSBs are always 0.
+// Range of Program Counter. Two LSBs are always 0.
`define LM32_PC_WIDTH (`LM32_WORD_WIDTH-2)
`define LM32_PC_RNG (`LM32_PC_WIDTH+2-1):2
@@ -280,7 +243,7 @@
`define LM32_CSR_WP1 `LM32_CSR_WIDTH'h19
`define LM32_CSR_WP2 `LM32_CSR_WIDTH'h1a
`define LM32_CSR_WP3 `LM32_CSR_WIDTH'h1b
-`endif
+`endif
// Values for WPC CSR
`define LM32_WPC_C_RNG 1:0
@@ -359,7 +322,7 @@
// Use a synchronous reset
`define CFG_RESET_SENSITIVITY
-// Wishbone defines
+// Wishbone defines
// Refer to Wishbone System-on-Chip Interconnection Architecture
// These should probably be moved to a Wishbone common file
View
20 cores/lm32/rtl/lm32_instruction_unit.v
@@ -179,7 +179,7 @@ parameter base_address = 0; // Base address of cacha
parameter limit = 0; // Limit (highest address) of cachable memory
// For bytes_per_line == 4, we set 1 so part-select range isn't reversed, even though not really used
-localparam addr_offset_width = bytes_per_line == 4 ? 1 : clogb2(bytes_per_line)-1-2;
+localparam addr_offset_width = bytes_per_line == 4 ? 1 : `CLOG2(bytes_per_line)-2;
localparam addr_offset_lsb = 2;
localparam addr_offset_msb = (addr_offset_lsb+addr_offset_width-1);
@@ -377,8 +377,6 @@ reg alternate_eba_taken;
// Functions
/////////////////////////////////////////////////////
-`include "lm32_functions.v"
-
/////////////////////////////////////////////////////
// Instantiations
/////////////////////////////////////////////////////
@@ -390,18 +388,18 @@ reg alternate_eba_taken;
// ----- Parameters -------
.pmi_family (`LATTICE_FAMILY),
- //.pmi_addr_depth_a (1 << (clogb2(`CFG_IROM_LIMIT/4-`CFG_IROM_BASE_ADDRESS/4+1)-1)),
- //.pmi_addr_width_a ((clogb2(`CFG_IROM_LIMIT/4-`CFG_IROM_BASE_ADDRESS/4+1)-1)),
+ //.pmi_addr_depth_a (1 << `CLOG2(`CFG_IROM_LIMIT/4-`CFG_IROM_BASE_ADDRESS/4+1)),
+ //.pmi_addr_width_a (`CLOG2(`CFG_IROM_LIMIT/4-`CFG_IROM_BASE_ADDRESS/4+1)),
//.pmi_data_width_a (`LM32_WORD_WIDTH),
- //.pmi_addr_depth_b (1 << (clogb2(`CFG_IROM_LIMIT/4-`CFG_IROM_BASE_ADDRESS/4+1)-1)),
- //.pmi_addr_width_b ((clogb2(`CFG_IROM_LIMIT/4-`CFG_IROM_BASE_ADDRESS/4+1)-1)),
+ //.pmi_addr_depth_b (1 << `CLOG2(`CFG_IROM_LIMIT/4-`CFG_IROM_BASE_ADDRESS/4+1)),
+ //.pmi_addr_width_b (`CLOG2(`CFG_IROM_LIMIT/4-`CFG_IROM_BASE_ADDRESS/4+1)),
//.pmi_data_width_b (`LM32_WORD_WIDTH),
.pmi_addr_depth_a (`CFG_IROM_LIMIT/4-`CFG_IROM_BASE_ADDRESS/4+1),
- .pmi_addr_width_a (clogb2_v1(`CFG_IROM_LIMIT/4-`CFG_IROM_BASE_ADDRESS/4+1)),
+ .pmi_addr_width_a (`CLOG2(`CFG_IROM_LIMIT/4-`CFG_IROM_BASE_ADDRESS/4+1)),
.pmi_data_width_a (`LM32_WORD_WIDTH),
.pmi_addr_depth_b (`CFG_IROM_LIMIT/4-`CFG_IROM_BASE_ADDRESS/4+1),
- .pmi_addr_width_b (clogb2_v1(`CFG_IROM_LIMIT/4-`CFG_IROM_BASE_ADDRESS/4+1)),
+ .pmi_addr_width_b (`CLOG2(`CFG_IROM_LIMIT/4-`CFG_IROM_BASE_ADDRESS/4+1)),
.pmi_data_width_b (`LM32_WORD_WIDTH),
.pmi_regmode_a ("noreg"),
@@ -420,8 +418,8 @@ reg alternate_eba_taken;
.ResetB (rst_i),
.DataInA ({32{1'b0}}),
.DataInB (irom_store_data_m),
- .AddressA (pc_a[(clogb2(`CFG_IROM_LIMIT/4-`CFG_IROM_BASE_ADDRESS/4+1)-1)+2-1:2]),
- .AddressB (irom_address_xm[(clogb2(`CFG_IROM_LIMIT/4-`CFG_IROM_BASE_ADDRESS/4+1)-1)+2-1:2]),
+ .AddressA (pc_a[`CLOG2(`CFG_IROM_LIMIT/4-`CFG_IROM_BASE_ADDRESS/4+1)+2-1:2]),
+ .AddressB (irom_address_xm[`CLOG2(`CFG_IROM_LIMIT/4-`CFG_IROM_BASE_ADDRESS/4+1)+2-1:2]),
.ClockEnA (!stall_a),
.ClockEnB (!stall_x || !stall_m),
.WrA (`FALSE),
View
20 cores/lm32/rtl/lm32_load_store_unit.v
@@ -139,7 +139,7 @@ parameter base_address = 0; // Base address of cacha
parameter limit = 0; // Limit (highest address) of cachable memory
// For bytes_per_line == 4, we set 1 so part-select range isn't reversed, even though not really used
-localparam addr_offset_width = bytes_per_line == 4 ? 1 : clogb2(bytes_per_line)-1-2;
+localparam addr_offset_width = bytes_per_line == 4 ? 1 : `CLOG2(bytes_per_line)-2;
localparam addr_offset_lsb = 2;
localparam addr_offset_msb = (addr_offset_lsb+addr_offset_width-1);
@@ -282,8 +282,6 @@ reg wb_load_complete; // Indicates when a Wish
// Functions
/////////////////////////////////////////////////////
-`include "lm32_functions.v"
-
/////////////////////////////////////////////////////
// Instantiations
/////////////////////////////////////////////////////
@@ -295,18 +293,18 @@ reg wb_load_complete; // Indicates when a Wish
// ----- Parameters -------
.pmi_family (`LATTICE_FAMILY),
- //.pmi_addr_depth_a (1 << (clogb2(`CFG_DRAM_LIMIT/4-`CFG_DRAM_BASE_ADDRESS/4+1)-1)),
- //.pmi_addr_width_a ((clogb2(`CFG_DRAM_LIMIT/4-`CFG_DRAM_BASE_ADDRESS/4+1)-1)),
+ //.pmi_addr_depth_a (1 << `CLOG2(`CFG_DRAM_LIMIT/4-`CFG_DRAM_BASE_ADDRESS/4+1)),
+ //.pmi_addr_width_a (`CLOG2(`CFG_DRAM_LIMIT/4-`CFG_DRAM_BASE_ADDRESS/4+1)),
//.pmi_data_width_a (`LM32_WORD_WIDTH),
- //.pmi_addr_depth_b (1 << (clogb2(`CFG_DRAM_LIMIT/4-`CFG_DRAM_BASE_ADDRESS/4+1)-1)),
- //.pmi_addr_width_b ((clogb2(`CFG_DRAM_LIMIT/4-`CFG_DRAM_BASE_ADDRESS/4+1)-1)),
+ //.pmi_addr_depth_b (1 << `CLOG2(`CFG_DRAM_LIMIT/4-`CFG_DRAM_BASE_ADDRESS/4+1)),
+ //.pmi_addr_width_b (`CLOG2(`CFG_DRAM_LIMIT/4-`CFG_DRAM_BASE_ADDRESS/4+1)),
//.pmi_data_width_b (`LM32_WORD_WIDTH),
.pmi_addr_depth_a (`CFG_DRAM_LIMIT/4-`CFG_DRAM_BASE_ADDRESS/4+1),
- .pmi_addr_width_a (clogb2_v1(`CFG_DRAM_LIMIT/4-`CFG_DRAM_BASE_ADDRESS/4+1)),
+ .pmi_addr_width_a (`CLOG2(`CFG_DRAM_LIMIT/4-`CFG_DRAM_BASE_ADDRESS/4+1)),
.pmi_data_width_a (`LM32_WORD_WIDTH),
.pmi_addr_depth_b (`CFG_DRAM_LIMIT/4-`CFG_DRAM_BASE_ADDRESS/4+1),
- .pmi_addr_width_b (clogb2_v1(`CFG_DRAM_LIMIT/4-`CFG_DRAM_BASE_ADDRESS/4+1)),
+ .pmi_addr_width_b (`CLOG2(`CFG_DRAM_LIMIT/4-`CFG_DRAM_BASE_ADDRESS/4+1)),
.pmi_data_width_b (`LM32_WORD_WIDTH),
.pmi_regmode_a ("noreg"),
@@ -325,8 +323,8 @@ reg wb_load_complete; // Indicates when a Wish
.ResetB (rst_i),
.DataInA ({32{1'b0}}),
.DataInB (dram_store_data_m),
- .AddressA (load_store_address_x[(clogb2(`CFG_DRAM_LIMIT/4-`CFG_DRAM_BASE_ADDRESS/4+1)-1)+2-1:2]),
- .AddressB (load_store_address_m[(clogb2(`CFG_DRAM_LIMIT/4-`CFG_DRAM_BASE_ADDRESS/4+1)-1)+2-1:2]),
+ .AddressA (load_store_address_x[`CLOG2(`CFG_DRAM_LIMIT/4-`CFG_DRAM_BASE_ADDRESS/4+1)+2-1:2]),
+ .AddressB (load_store_address_m[`CLOG2(`CFG_DRAM_LIMIT/4-`CFG_DRAM_BASE_ADDRESS/4+1)+2-1:2]),
// .ClockEnA (!stall_x & (load_x | store_x)),
.ClockEnA (!stall_x),
.ClockEnB (!stall_m),
View
1 cores/lm32/rtl/lm32_top.v
@@ -242,7 +242,6 @@ wire trace_bret; // Indicates a bret instruction
// Functions
/////////////////////////////////////////////////////
-`include "lm32_functions.v"
/////////////////////////////////////////////////////
// Instantiations
/////////////////////////////////////////////////////
View
27 cores/lm32/test/Makefile
@@ -0,0 +1,27 @@
+SOURCES=tb_lm32.v lm32_config.v
+SOURCES+=../rtl/lm32_adder.v ../rtl/lm32_addsub.v ../rtl/lm32_cpu.v ../rtl/lm32_dcache.v ../rtl/lm32_debug.v ../rtl/lm32_decoder.v ../rtl/lm32_dp_ram.v ../rtl/lm32_icache.v ../rtl/lm32_instruction_unit.v ../rtl/lm32_interrupt.v ../rtl/lm32_jtag.v ../rtl/lm32_load_store_unit.v ../rtl/lm32_logic_op.v ../rtl/lm32_mc_arithmetic.v ../rtl/lm32_multiplier.v ../rtl/lm32_ram.v ../rtl/lm32_shifter.v ../rtl/lm32_top.v
+
+all: tb_lm32
+
+sim_%: %.vh tb_lm32
+ @vvp tb_lm32 +prog=$<
+
+trace_%: %.vh tb_lm32
+ @vvp tb_lm32 +trace=trace_$*.txt +prog=$<
+
+hello_world.elf: crt.S hello_world.c
+ lm32-elf-gcc -Tlinker.ld -fno-builtin -o $@ $^
+
+pipe1.elf: pipe1.S
+ lm32-elf-gcc -Tlinker.ld -fno-builtin -o $@ $^
+
+%.vh: %.elf
+ lm32-elf-objcopy -O verilog $< $@
+
+clean:
+ rm -f tb_lm32 *.vcd *.elf *.vh trace*.txt
+
+tb_lm32: $(SOURCES)
+ iverilog -I. -I../rtl -o tb_lm32 $(SOURCES)
+
+.PHONY: clean sim
View
28 cores/lm32/test/crt.S
@@ -0,0 +1,28 @@
+.globl _start
+
+.text
+_start:
+xor r0, r0, r0
+
+mvhi sp, hi(_fstack)
+ori sp, sp, lo(_fstack)
+
+mv fp,r0
+
+mvhi r1, hi(_fbss)
+ori r1, r1, lo(_fbss)
+mvhi r2, hi(_ebss)
+ori r2, r2, lo(_ebss)
+
+1:
+bge r1, r2, 2f
+sw (r1+0), r0
+addi r1, r1, 4
+bi 1b
+2:
+
+calli main
+
+mvhi r1, 0xdead
+ori r2, r0, 0xbeef
+sw (r1+0), r2
View
15 cores/lm32/test/hello_world.c
@@ -0,0 +1,15 @@
+void putc(char c)
+{
+ char *tx = (char*)0xff000000;
+ *tx = c;
+}
+
+void puts(char *s)
+{
+ while (*s) putc(*s++);
+}
+
+void main(void)
+{
+ puts("Hello World\n");
+}
View
56 cores/lm32/test/linker.ld
@@ -0,0 +1,56 @@
+OUTPUT_FORMAT("elf32-lm32")
+ENTRY(_start)
+
+__DYNAMIC = 0;
+
+MEMORY {
+ pmem : ORIGIN = 0x00000000, LENGTH = 0x8000
+ dmem : ORIGIN = 0x00008000, LENGTH = 0x8000
+}
+
+SECTIONS
+{
+ .text :
+ {
+ _ftext = .;
+ *(.text .stub .text.* .gnu.linkonce.t.*)
+ _etext = .;
+ } > pmem
+
+ .rodata :
+ {
+ . = ALIGN(4);
+ _frodata = .;
+ *(.rodata .rodata.* .gnu.linkonce.r.*)
+ *(.rodata1)
+ _erodata = .;
+ } > dmem
+
+ .data :
+ {
+ . = ALIGN(4);
+ _fdata = .;
+ *(.data .data.* .gnu.linkonce.d.*)
+ *(.data1)
+ _gp = ALIGN(16);
+ *(.sdata .sdata.* .gnu.linkonce.s.*)
+ _edata = .;
+ } > dmem
+
+ .bss :
+ {
+ . = ALIGN(4);
+ _fbss = .;
+ *(.dynsbss)
+ *(.sbss .sbss.* .gnu.linkonce.sb.*)
+ *(.scommon)
+ *(.dynbss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ *(COMMON)
+ . = ALIGN(4);
+ _ebss = .;
+ _end = .;
+ } > dmem
+}
+
+PROVIDE(_fstack = ORIGIN(dmem) + LENGTH(dmem) - 4);
View
41 cores/lm32/test/lm32_config.v
@@ -0,0 +1,41 @@
+`ifdef LM32_CONFIG_V
+`else
+`define LM32_CONFIG_V
+
+`define CFG_EBA_RESET 32'h0
+`define CFG_DEBA_RESET 32'h0
+
+`define CFG_PL_MULTIPLY_ENABLED
+`define CFG_PL_BARREL_SHIFT_ENABLED
+`define CFG_SIGN_EXTEND_ENABLED
+`define CFG_MC_DIVIDE_ENABLED
+`define CFG_EBR_POSEDGE_REGISTER_FILE
+
+`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_LIMIT 32'h7fffffff
+
+`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_LIMIT 32'h7fffffff
+
+// Enable Debugging
+//`define CFG_JTAG_ENABLED
+//`define CFG_JTAG_UART_ENABLED
+`define CFG_DEBUG_ENABLED
+//`define CFG_HW_DEBUG_ENABLED
+`define CFG_ROM_DEBUG_ENABLED
+`define CFG_BREAKPOINTS 32'h4
+`define CFG_WATCHPOINTS 32'h4
+`define CFG_EXTERNAL_BREAK_ENABLED
+`define CFG_GDBSTUB_ENABLED
+
+`define CLOG2 $clog2
+
+`endif
View
15 cores/lm32/test/pipe1.S
@@ -0,0 +1,15 @@
+.globl _start
+
+.text
+_start:
+xor r0, r0, r0
+
+mvi r1, 10
+addi r2, r1, 1
+addi r3, r2, 1
+muli r4, r1, 10
+add r5, r4, r4
+
+mvhi r1, 0xdead
+ori r2, r0, 0xbeef
+sw (r1+0), r2
View
238 cores/lm32/test/tb_lm32.v
@@ -0,0 +1,238 @@
+`include "lm32_include.v"
+
+module soc();
+
+integer i;
+
+reg sys_rst;
+reg sys_clk;
+reg [31:0] interrupt;
+
+reg i_ack;
+wire [31:0] i_adr;
+wire i_cyc;
+wire [31:0] i_dat;
+wire i_stb;
+
+reg d_ack;
+wire [31:0] d_adr;
+wire d_cyc;
+wire [31:0] d_dat_i;
+wire [31:0] d_dat_o;
+wire [3:0] d_sel;
+wire d_stb;
+
+lm32_top lm32(
+ .clk_i(sys_clk),
+ .rst_i(sys_rst),
+
+ .interrupt(interrupt),
+
+ .I_ACK_I(i_ack),
+ .I_ADR_O(i_adr),
+ .I_BTE_O(),
+ .I_CTI_O(),
+ .I_CYC_O(i_cyc),
+ .I_DAT_I(i_dat),
+ .I_DAT_O(),
+ .I_ERR_I(1'b0),
+ .I_LOCK_O(),
+ .I_RTY_I(1'b0),
+ .I_SEL_O(),
+ .I_STB_O(i_stb),
+ .I_WE_O(),
+
+ .D_ACK_I(d_ack),
+ .D_ADR_O(d_adr),
+ .D_BTE_O(),
+ .D_CTI_O(),
+ .D_CYC_O(d_cyc),
+ .D_DAT_I(d_dat_i),
+ .D_DAT_O(d_dat_o),
+ .D_ERR_I(1'b0),
+ .D_LOCK_O(),
+ .D_RTY_I(1'b0),
+ .D_SEL_O(d_sel),
+ .D_STB_O(d_stb),
+ .D_WE_O(d_we)
+);
+
+// clock
+initial sys_clk = 1'b0;
+always #5 sys_clk = ~sys_clk;
+
+// reset
+initial begin
+ sys_rst = 1'b1;
+ #20
+ sys_rst = 1'b0;
+end
+
+// data memory
+reg [7:0] dmem[0:65536];
+wire [31:0] dmem_dat_i;
+reg [31:0] dmem_dat_o;
+wire [13:0] dmem_adr;
+wire [3:0] dmem_we;
+initial begin
+ for(i=0;i<65536;i=i+1)
+ dmem[i] = 8'b0;
+end
+always @(posedge sys_clk) begin
+ if(dmem_we[0]) dmem[{dmem_adr, 2'b11}] <= dmem_dat_i[7:0];
+ if(dmem_we[1]) dmem[{dmem_adr, 2'b10}] <= dmem_dat_i[15:8];
+ if(dmem_we[2]) dmem[{dmem_adr, 2'b01}] <= dmem_dat_i[23:16];
+ if(dmem_we[3]) dmem[{dmem_adr, 2'b00}] <= dmem_dat_i[31:24];
+ dmem_dat_o[7:0] <= dmem[{dmem_adr, 2'b11}];
+ dmem_dat_o[15:8] <= dmem[{dmem_adr, 2'b10}];
+ dmem_dat_o[23:16] <= dmem[{dmem_adr, 2'b01}];
+ dmem_dat_o[31:24] <= dmem[{dmem_adr, 2'b00}];
+end
+
+// program memory
+reg [7:0] pmem[0:65536];
+wire [31:0] pmem_dat_i;
+reg [31:0] pmem_dat_o;
+wire [13:0] pmem_adr;
+initial begin
+ for(i=0;i<65536;i=i+1)
+ pmem[i] = 8'b0;
+end
+always @(posedge sys_clk) begin
+ pmem_dat_o[7:0] <= pmem[{pmem_adr, 2'b11}];
+ pmem_dat_o[15:8] <= pmem[{pmem_adr, 2'b10}];
+ pmem_dat_o[23:16] <= pmem[{pmem_adr, 2'b01}];
+ pmem_dat_o[31:24] <= pmem[{pmem_adr, 2'b00}];
+end
+
+// uart
+always @(posedge sys_clk) begin
+ if(d_cyc & d_stb & d_we & d_ack)
+ if(d_adr == 32'hff000000)
+ $write("%c", d_dat_o[7:0]);
+end
+
+// wishbone interface for instruction bus
+always @(posedge sys_clk) begin
+ if(sys_rst)
+ i_ack <= 1'b0;
+ else begin
+ i_ack <= 1'b0;
+ if(i_cyc & i_stb & ~i_ack)
+ i_ack <= 1'b1;
+ end
+end
+
+assign i_dat = pmem_dat_o;
+assign pmem_adr = i_adr[15:2];
+
+// wishbone interface for data bus
+always @(posedge sys_clk) begin
+ if(sys_rst)
+ d_ack <= 1'b0;
+ else begin
+ d_ack <= 1'b0;
+ if(d_cyc & d_stb & ~d_ack)
+ d_ack <= 1'b1;
+ end
+end
+
+assign d_dat_i = dmem_dat_o;
+assign dmem_dat_i = d_dat_o;
+assign dmem_adr = d_adr[15:2];
+assign dmem_we = {4{d_cyc & d_stb & d_we}} & d_sel;
+
+// interrupts
+initial interrupt = 32'b0;
+
+// simulation end request
+always @(posedge sys_clk) begin
+ if(d_cyc & d_stb & d_we & d_ack)
+ if(d_adr == 32'hdead0000 && d_dat_o == 32'hbeef)
+ $finish;
+end
+
+// traces
+`ifdef TB_ENABLE_WB_TRACES
+always @(posedge sys_clk) begin
+ if(i_cyc & i_stb & i_ack)
+ $display("i load @%08x %08x", i_adr, i_dat);
+ if(d_cyc & d_stb & ~d_we & d_ack)
+ $display("d load @%08x %08x", d_adr, d_dat_o);
+ if(d_cyc & d_stb & d_we & d_ack)
+ $display("d store @%08x %08x", d_adr, d_dat_o);
+end
+`endif
+
+// dump signals
+initial $dumpfile("tb_lm32.vcd");
+initial $dumpvars(0, soc);
+
+// init memory
+reg [256*8:0] prog;
+initial begin
+ if(! $value$plusargs("prog=%s", prog)) begin
+ $display("ERROR: please specify +prog=<file>.vh to start.");
+ $finish;
+ end
+end
+
+initial $readmemh(prog, dmem);
+initial $readmemh(prog, pmem);
+
+// trace pipeline
+reg [256*8:0] tracefile;
+integer trace_started;
+integer trace_enabled;
+integer cycle;
+integer tracefd;
+initial begin
+ if($value$plusargs("trace=%s", tracefile)) begin
+ trace_enabled = 1;
+ cycle = 0;
+ tracefd = $fopen(tracefile);
+ trace_started = 0;
+ end else
+ trace_enabled = 0;
+end
+`ifdef CFG_ICACHE_ENABLED
+assign icache_ready = lm32.cpu.instruction_unit.icache.state != 1;
+`else
+assign icache_ready = `TRUE;
+`endif
+`ifdef CFG_DCACHE_ENABLED
+assign dcache_ready = lm32.cpu.load_store_unit.dcache.state != 1;
+`else
+assign dcache_ready = `TRUE;
+`endif
+always @(posedge sys_clk) begin
+ // wait until icache and dcache init is done
+ if(!trace_started && icache_ready && dcache_ready)
+ trace_started = 1;
+ if(trace_enabled && trace_started) begin
+ $fwrite(tracefd, "%-d ", cycle);
+`ifdef CFG_ICACHE_ENABLED
+ $fwrite(tracefd, "%x ", {lm32.cpu.instruction_unit.pc_a, 2'b00});
+ $fwrite(tracefd, "%1d ", lm32.cpu.valid_a);
+`endif
+ $fwrite(tracefd, "%x ", {lm32.cpu.instruction_unit.pc_f, 2'b00});
+ $fwrite(tracefd, "%1d ", lm32.cpu.kill_f);
+ $fwrite(tracefd, "%1d ", lm32.cpu.valid_f);
+ $fwrite(tracefd, "%x ", {lm32.cpu.instruction_unit.pc_d, 2'b00});
+ $fwrite(tracefd, "%1d ", lm32.cpu.kill_d);
+ $fwrite(tracefd, "%1d ", lm32.cpu.valid_d);
+ $fwrite(tracefd, "%x ", {lm32.cpu.instruction_unit.pc_x, 2'b00});
+ $fwrite(tracefd, "%1d ", lm32.cpu.kill_x);
+ $fwrite(tracefd, "%1d ", lm32.cpu.valid_x);
+ $fwrite(tracefd, "%x ", {lm32.cpu.instruction_unit.pc_m, 2'b00});
+ $fwrite(tracefd, "%1d ", lm32.cpu.kill_m);
+ $fwrite(tracefd, "%1d ", lm32.cpu.valid_m);
+ $fwrite(tracefd, "%x ", {lm32.cpu.instruction_unit.pc_w, 2'b00});
+ $fwrite(tracefd, "%1d ", lm32.cpu.kill_w);
+ $fwrite(tracefd, "%1d ", lm32.cpu.valid_w);
+ $fwrite(tracefd, "\n");
+ cycle = cycle + 1;
+ end
+end
+
+endmodule

No commit comments for this range

Something went wrong with that request. Please try again.