URL
https://opencores.org/ocsvn/mpx/mpx/trunk
Subversion Repositories mpx
Compare Revisions
- This comparison shows the changes necessary to convert path
/mpx/trunk/rtl
- from Rev 10 to Rev 9
- ↔ Reverse comparison
Rev 10 → Rev 9
/sim_verilator/top.cpp
0,0 → 1,306
//----------------------------------------------------------------- |
// MPX 32-bit Soft-Core Processor |
// V0.1 |
// Ultra-Embedded.com |
// Copyright 2011 - 2012 |
// |
// Email: admin@ultra-embedded.com |
// |
// License: LGPL |
// |
// If you would like a version with a different license for use |
// in commercial projects please contact the above email address |
// for more details. |
//----------------------------------------------------------------- |
// |
// Copyright (C) 2011 - 2012 Ultra-Embedded.com |
// |
// This source file may be used and distributed without |
// restriction provided that this copyright statement is not |
// removed from the file and that any derivative work contains |
// the original copyright notice and the associated disclaimer. |
// |
// This source file is free software; you can redistribute it |
// and/or modify it under the terms of the GNU Lesser General |
// Public License as published by the Free Software Foundation; |
// either version 2.1 of the License, or (at your option) any |
// later version. |
// |
// This source is distributed in the hope that it will be |
// useful, but WITHOUT ANY WARRANTY; without even the implied |
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
// PURPOSE. See the GNU Lesser General Public License for more |
// details. |
// |
// You should have received a copy of the GNU Lesser General |
// Public License along with this source; if not, write to the |
// Free Software Foundation, Inc., 59 Temple Place, Suite 330, |
// Boston, MA 02111-1307 USA |
//----------------------------------------------------------------- |
#include <stdio.h> |
#include <unistd.h> |
#include <math.h> |
#include <time.h> |
|
#include "top.h" |
|
#include "Vtop.h" |
#include "Vtop_top.h" |
#include "Vtop_sram4__S13.h" |
#include "Vtop_sram__S13.h" |
#include "Vtop_soc_core__pi1.h" |
#include "Vtop_cpu__B10000000_I10000000.h" |
|
#include "verilated.h" |
|
#if VM_TRACE |
#include <verilated_vcd_c.h> |
#endif |
|
//----------------------------------------------------------------- |
// Defines |
//----------------------------------------------------------------- |
// Memory start offset (set to 0x2000 to match FPGA version where |
// bootloader exists in first 8K) |
#define MEMORY_START 0x10000000 |
#define MEMORY_SIZE (512 * 1024) |
#define REGISTERS 32 |
|
#define CPU_INSTANCE top->v->u1_cpu->u1_cpu |
|
//----------------------------------------------------------------- |
// Locals |
//----------------------------------------------------------------- |
static Vtop *top; |
static unsigned int _stop_pc = 0xFFFFFFFF; |
|
#if VM_TRACE |
static unsigned int main_time = 0; |
static VerilatedVcdC* tfp; |
#endif |
|
//----------------------------------------------------------------- |
// top_init |
//----------------------------------------------------------------- |
int top_init(void) |
{ |
top = new Vtop(); |
|
#if VM_TRACE |
// If verilator was invoked with --trace |
Verilated::traceEverOn(true); |
VL_PRINTF("Enabling GTKWave Trace Output...\n"); |
tfp = new VerilatedVcdC; |
top->trace (tfp, 99); |
tfp->open ("wave_dump.vcd"); |
#endif |
|
// Initial |
top->clk_i = 0; |
top->rst_i = 1; |
top->en_i = 1; |
top->intr_i = 0; |
top->dbg_reg_addr_i = 0; |
top->eval(); |
|
// Reset |
top->clk_i = 1; |
top->rst_i = 1; |
top->eval(); |
|
top->clk_i = 0; |
top->rst_i = 0; |
top->eval(); |
|
return 0; |
} |
//----------------------------------------------------------------- |
// top_load |
//----------------------------------------------------------------- |
int top_load(unsigned int addr, unsigned char val) |
{ |
if (addr >= (MEMORY_SIZE - MEMORY_START)) |
return -1; |
|
addr -= MEMORY_START; |
|
switch (addr & 0x3) |
{ |
case 0: |
top->v->u1_bram->sram_gen__DOT__sram_loop__BRA__3__KET____DOT__u1_bram->ram[addr >> 2] = val; |
break; |
case 1: |
top->v->u1_bram->sram_gen__DOT__sram_loop__BRA__2__KET____DOT__u1_bram->ram[addr >> 2] = val; |
break; |
case 2: |
top->v->u1_bram->sram_gen__DOT__sram_loop__BRA__1__KET____DOT__u1_bram->ram[addr >> 2] = val; |
break; |
case 3: |
top->v->u1_bram->sram_gen__DOT__sram_loop__BRA__0__KET____DOT__u1_bram->ram[addr >> 2] = val; |
break; |
} |
|
return 0; |
} |
//----------------------------------------------------------------- |
// top_mem_read |
//----------------------------------------------------------------- |
unsigned char top_mem_read(unsigned int addr) |
{ |
unsigned char val = 0; |
|
if (addr >= (MEMORY_SIZE - MEMORY_START)) |
return 0; |
|
addr -= MEMORY_START; |
|
switch (addr & 0x3) |
{ |
case 0: |
val = top->v->u1_bram->sram_gen__DOT__sram_loop__BRA__3__KET____DOT__u1_bram->ram[addr >> 2]; |
break; |
case 1: |
val = top->v->u1_bram->sram_gen__DOT__sram_loop__BRA__2__KET____DOT__u1_bram->ram[addr >> 2]; |
break; |
case 2: |
val = top->v->u1_bram->sram_gen__DOT__sram_loop__BRA__1__KET____DOT__u1_bram->ram[addr >> 2]; |
break; |
case 3: |
val = top->v->u1_bram->sram_gen__DOT__sram_loop__BRA__0__KET____DOT__u1_bram->ram[addr >> 2]; |
break; |
} |
|
return val; |
} |
//----------------------------------------------------------------- |
// top_setbreakpoint |
//----------------------------------------------------------------- |
int top_setbreakpoint(int bp, unsigned int pc) |
{ |
if (bp != 0) |
return -1; |
else |
{ |
_stop_pc = pc; |
return 0; |
} |
} |
//----------------------------------------------------------------- |
// top_run |
//----------------------------------------------------------------- |
int top_run(int cycles, int intr_after_cycles) |
{ |
int current_cycle = 0; |
unsigned int last_pc = CPU_INSTANCE->get_pc(); |
|
// Run until fault or number of cycles completed |
while (!Verilated::gotFinish() && !top->fault_o && (current_cycle < cycles || cycles == -1)) |
{ |
// CLK->L |
top->clk_i = 0; |
top->eval(); |
|
#if VM_TRACE |
if (tfp) tfp->dump (main_time++); |
#endif |
|
// CLK->H |
top->clk_i = 1; |
top->eval(); |
|
#if VM_TRACE |
if (tfp) tfp->dump (main_time++); |
#endif |
|
if (top->uart_wr_o) |
printf("%c", top->uart_data_o); |
|
// Generate interrupt after a certain number of cycles? |
if (intr_after_cycles >= 0 && intr_after_cycles == current_cycle) |
{ |
top->intr_i = 1; |
intr_after_cycles = -1; |
} |
else |
top->intr_i = 0; |
|
unsigned int new_pc = CPU_INSTANCE->get_pc(); |
if (last_pc != new_pc) |
{ |
last_pc = new_pc; |
current_cycle++; |
} |
|
// Breakpoint hit |
if (_stop_pc == new_pc || top->break_o) |
return TOP_RES_BREAKPOINT; |
} |
|
// Fault |
if (top->fault_o) |
return TOP_RES_FAULT; |
// Number of cycles reached |
else if (current_cycle >= cycles) |
return TOP_RES_MAX_CYCLES; |
// No error |
else |
return TOP_RES_OK; |
} |
//----------------------------------------------------------------- |
// top_reset |
//----------------------------------------------------------------- |
void top_reset(void) |
{ |
// Reset = H |
top->rst_i = 1; |
|
// Clock |
top->clk_i = 1; |
top->eval(); |
top->clk_i = 0; |
top->eval(); |
|
// Reset = L |
top->rst_i = 0; |
top->eval(); |
} |
//----------------------------------------------------------------- |
// top_getreg |
//----------------------------------------------------------------- |
unsigned int top_getreg(int reg) |
{ |
top->en_i = 0; |
|
top->dbg_reg_addr_i = reg; |
|
// Clock |
top->clk_i = 1; |
top->eval(); |
top->clk_i = 0; |
top->eval(); |
|
top->en_i = 1; |
|
return top->dbg_reg_out_o; |
} |
//----------------------------------------------------------------- |
// top_reset |
//----------------------------------------------------------------- |
unsigned int top_getpc(void) |
{ |
return CPU_INSTANCE->get_pc(); |
} |
//----------------------------------------------------------------- |
// top_done |
//----------------------------------------------------------------- |
void top_done(void) |
{ |
top->final(); |
#if VM_TRACE |
if (tfp) |
{ |
tfp->close(); |
tfp = NULL; |
} |
#endif |
} |
/sim_verilator/main.cpp
0,0 → 1,164
//----------------------------------------------------------------- |
// MPX 32-bit Soft-Core Processor |
// V0.1 |
// Ultra-Embedded.com |
// Copyright 2011 - 2012 |
// |
// Email: admin@ultra-embedded.com |
// |
// License: LGPL |
// |
// If you would like a version with a different license for use |
// in commercial projects please contact the above email address |
// for more details. |
//----------------------------------------------------------------- |
// |
// Copyright (C) 2011 - 2012 Ultra-Embedded.com |
// |
// This source file may be used and distributed without |
// restriction provided that this copyright statement is not |
// removed from the file and that any derivative work contains |
// the original copyright notice and the associated disclaimer. |
// |
// This source file is free software; you can redistribute it |
// and/or modify it under the terms of the GNU Lesser General |
// Public License as published by the Free Software Foundation; |
// either version 2.1 of the License, or (at your option) any |
// later version. |
// |
// This source is distributed in the hope that it will be |
// useful, but WITHOUT ANY WARRANTY; without even the implied |
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
// PURPOSE. See the GNU Lesser General Public License for more |
// details. |
// |
// You should have received a copy of the GNU Lesser General |
// Public License along with this source; if not, write to the |
// Free Software Foundation, Inc., 59 Temple Place, Suite 330, |
// Boston, MA 02111-1307 USA |
//----------------------------------------------------------------- |
#include <stdio.h> |
#include <unistd.h> |
|
#include "top.h" |
#include "verilated.h" |
|
//----------------------------------------------------------------- |
// Defines |
//----------------------------------------------------------------- |
#define MEM_BASE 0x10000000 |
|
//----------------------------------------------------------------- |
// Locals |
//----------------------------------------------------------------- |
|
//----------------------------------------------------------------- |
// main |
//----------------------------------------------------------------- |
int main(int argc, char **argv, char **env) |
{ |
int c; |
int err; |
unsigned int loadAddr = MEM_BASE; |
char *filename = NULL; |
int help = 0; |
int exitcode = 0; |
int cycles = -1; |
int intr_after = -1; |
|
Verilated::commandArgs(argc, argv); |
|
while ((c = getopt (argc, argv, "f:l:c:i:")) != -1) |
{ |
switch(c) |
{ |
case 'l': |
loadAddr = strtoul(optarg, NULL, 0); |
break; |
case 'f': |
filename = optarg; |
break; |
case 'c': |
cycles = strtoul(optarg, NULL, 0); |
break; |
case 'i': |
intr_after = strtoul(optarg, NULL, 0); |
break; |
case '?': |
default: |
help = 1; |
break; |
} |
} |
|
if (loadAddr < MEM_BASE) |
{ |
fprintf (stderr,"Load address incorrect (0x%x)\n", loadAddr); |
exit(-1); |
} |
|
if (help) |
{ |
fprintf (stderr,"Usage:\n"); |
fprintf (stderr,"-t = Enable program trace\n"); |
fprintf (stderr,"-l 0xnnnn = Executable load address\n"); |
fprintf (stderr,"-f filename = Executable to load\n"); |
fprintf (stderr,"-c num = Max number of cycles\n"); |
fprintf (stderr,"-i num = Generate interrupt after num cycles\n"); |
|
exit(0); |
} |
|
top_init(); |
|
if (filename) |
{ |
FILE *f; |
|
printf("Opening %s\n", filename); |
f = fopen(filename, "rb"); |
if (f) |
{ |
long size; |
char *buf; |
|
// Get size |
fseek(f, 0, SEEK_END); |
size = ftell(f); |
rewind(f); |
|
buf = (char*)malloc(size+1); |
if (buf) |
{ |
unsigned int addr; |
|
// Read file data in |
int len = fread(buf, 1, size, f); |
buf[len] = 0; |
|
printf("Loading to 0x%x\n", loadAddr); |
for (addr=0;addr<len;addr++) |
top_load(loadAddr + addr, buf[addr]); |
|
free(buf); |
fclose(f); |
} |
} |
else |
{ |
printf("Could not read file!\n"); |
exit(-1); |
} |
} |
|
// Run |
err = top_run(cycles, intr_after); |
|
if (err == TOP_RES_FAULT) |
printf("FAULT PC %x!\n", top_getpc()); |
|
top_done(); |
|
printf("Exit\n"); |
exit((err == TOP_RES_FAULT) ? 1 : 0); |
} |
/sim_verilator/sram.v
0,0 → 1,90
//----------------------------------------------------------------- |
// MPX 32-bit Soft-Core Processor |
// V0.1 |
// Ultra-Embedded.com |
// Copyright 2011 - 2012 |
// |
// Email: admin@ultra-embedded.com |
// |
// License: LGPL |
// |
// If you would like a version with a different license for use |
// in commercial projects please contact the above email address |
// for more details. |
//----------------------------------------------------------------- |
// |
// Copyright (C) 2011 - 2012 Ultra-Embedded.com |
// |
// This source file may be used and distributed without |
// restriction provided that this copyright statement is not |
// removed from the file and that any derivative work contains |
// the original copyright notice and the associated disclaimer. |
// |
// This source file is free software; you can redistribute it |
// and/or modify it under the terms of the GNU Lesser General |
// Public License as published by the Free Software Foundation; |
// either version 2.1 of the License, or (at your option) any |
// later version. |
// |
// This source is distributed in the hope that it will be |
// useful, but WITHOUT ANY WARRANTY; without even the implied |
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
// PURPOSE. See the GNU Lesser General Public License for more |
// details. |
// |
// You should have received a copy of the GNU Lesser General |
// Public License along with this source; if not, write to the |
// Free Software Foundation, Inc., 59 Temple Place, Suite 330, |
// Boston, MA 02111-1307 USA |
//----------------------------------------------------------------- |
|
//----------------------------------------------------------------- |
// Module |
//----------------------------------------------------------------- |
module sram |
( |
clk_i, |
adr_i, |
dat_i, |
wr_i, |
dat_o |
); |
|
//----------------------------------------------------------------- |
// Params |
//----------------------------------------------------------------- |
parameter [31:0] WIDTH = 8; |
parameter [31:0] SIZE = 14; |
|
//----------------------------------------------------------------- |
// I/O |
//----------------------------------------------------------------- |
input clk_i /*verilator public*/; |
output [(WIDTH - 1):0] dat_o /*verilator public*/; |
input [(WIDTH - 1):0] dat_i /*verilator public*/; |
input [(SIZE - 1):0] adr_i /*verilator public*/; |
input wr_i /*verilator public*/; |
|
//----------------------------------------------------------------- |
// Registers |
//----------------------------------------------------------------- |
reg [(WIDTH - 1):0] ram [((2<< (SIZE-1)) - 1):0] /*verilator public*/; |
reg [(SIZE - 1):0] rd_addr; |
wire [(WIDTH - 1):0] dat_o; |
|
//----------------------------------------------------------------- |
// Processes |
//----------------------------------------------------------------- |
always @ (posedge clk_i) |
begin |
if (wr_i == 1'b1) |
ram[adr_i] <= dat_i; |
rd_addr <= adr_i; |
end |
|
//------------------------------------------------------------------- |
// Combinatorial |
//------------------------------------------------------------------- |
assign dat_o = ram[rd_addr]; |
|
endmodule |
/sim_verilator/top.v
0,0 → 1,185
//----------------------------------------------------------------- |
// MPX 32-bit Soft-Core Processor |
// V0.1 |
// Ultra-Embedded.com |
// Copyright 2011 - 2012 |
// |
// Email: admin@ultra-embedded.com |
// |
// License: LGPL |
// |
// If you would like a version with a different license for use |
// in commercial projects please contact the above email address |
// for more details. |
//----------------------------------------------------------------- |
// |
// Copyright (C) 2011 - 2012 Ultra-Embedded.com |
// |
// This source file may be used and distributed without |
// restriction provided that this copyright statement is not |
// removed from the file and that any derivative work contains |
// the original copyright notice and the associated disclaimer. |
// |
// This source file is free software; you can redistribute it |
// and/or modify it under the terms of the GNU Lesser General |
// Public License as published by the Free Software Foundation; |
// either version 2.1 of the License, or (at your option) any |
// later version. |
// |
// This source is distributed in the hope that it will be |
// useful, but WITHOUT ANY WARRANTY; without even the implied |
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
// PURPOSE. See the GNU Lesser General Public License for more |
// details. |
// |
// You should have received a copy of the GNU Lesser General |
// Public License along with this source; if not, write to the |
// Free Software Foundation, Inc., 59 Temple Place, Suite 330, |
// Boston, MA 02111-1307 USA |
//----------------------------------------------------------------- |
|
//----------------------------------------------------------------- |
// Module |
//----------------------------------------------------------------- |
module top |
( |
// Clocking & Reset |
clk_i, |
rst_i, |
// Global Enable |
en_i, |
// Fault Output |
fault_o, |
// Break Output |
break_o, |
// Interrupt Input |
intr_i, |
// Debug Register Access |
dbg_reg_addr_i, |
dbg_reg_out_o, |
// UART output |
uart_data_o, |
uart_wr_o |
); |
|
//----------------------------------------------------------------- |
// Params |
//----------------------------------------------------------------- |
parameter CLK_KHZ = (8192*7); |
parameter SRAM_ADDR_WIDTH = 19; |
|
//----------------------------------------------------------------- |
// I/O |
//----------------------------------------------------------------- |
input clk_i /*verilator public*/; |
input rst_i /*verilator public*/; |
input en_i /*verilator public*/; |
output fault_o /*verilator public*/; |
output break_o /*verilator public*/; |
input intr_i /*verilator public*/; |
input [8:0] dbg_reg_addr_i /*verilator public*/; |
output [31:0] dbg_reg_out_o /*verilator public*/; |
output [7:0] uart_data_o /*verilator public*/; |
output uart_wr_o /*verilator public*/; |
|
//----------------------------------------------------------------- |
// Registers / Wires |
//----------------------------------------------------------------- |
wire fault_o; |
wire break_o; |
wire [31:0] dbg_reg_out_o; |
wire [7:0] uart_data_o; |
wire uart_wr_o; |
wire [31:0] int_mem_addr_o; |
wire [31:0] int_mem_data_o; |
wire [31:0] int_mem_data_i; |
wire [3:0] int_mem_wr_o; |
|
wire [31:0] ext_mem_addr_o; |
wire [31:0] ext_mem_data_o; |
wire [31:0] ext_mem_data_i; |
wire [3:0] ext_mem_wr_o; |
|
//----------------------------------------------------------------- |
// Instantiation |
//----------------------------------------------------------------- |
|
sram4 |
#( |
.SRAM_ADDR_WIDTH(SRAM_ADDR_WIDTH) |
) |
u1_bram |
( |
.clk_i(clk_i), |
.address_i(int_mem_addr_o), |
.data_i(int_mem_data_o), |
.data_o(int_mem_data_i), |
.wr_i(int_mem_wr_o) |
); |
|
sram4 |
#( |
.SRAM_ADDR_WIDTH(SRAM_ADDR_WIDTH) |
) |
u2_bram |
( |
.clk_i(clk_i), |
.address_i(ext_mem_addr_o), |
.data_i(ext_mem_data_o), |
.data_o(ext_mem_data_i), |
.wr_i(ext_mem_wr_o) |
); |
|
soc_core |
#( |
.CLK_KHZ(CLK_KHZ), |
.UART_BAUD(115200), |
.EXTERNAL_INTERRUPTS(1), |
.BOOT_VECTOR(32'h10000000), |
.ISR_VECTOR(32'h10000000), |
.REGISTER_FILE_TYPE("SIMULATION") |
) |
u1_cpu |
( |
// Clock / Status |
.clk_i(clk_i), |
.rst_i(rst_i), |
.en_i(en_i), |
.ext_intr_i(intr_i), |
.fault_o(fault_o), |
.break_o(break_o), |
|
// UART |
.uart_tx_o(/* open */), |
.uart_rx_i(1'b0), |
|
// Internal Memory |
.int_mem_addr_o(int_mem_addr_o), |
.int_mem_data_o(int_mem_data_o), |
.int_mem_data_i(int_mem_data_i), |
.int_mem_wr_o(int_mem_wr_o), |
.int_mem_rd_o(/*open */), |
.int_mem_pause_i(1'b0), |
|
// External Memory |
.ext_mem_addr_o(ext_mem_addr_o), |
.ext_mem_data_o(ext_mem_data_o), |
.ext_mem_data_i(ext_mem_data_i), |
.ext_mem_wr_o(ext_mem_wr_o), |
.ext_mem_rd_o(/*open */), |
.ext_mem_pause_i(1'b0), |
|
// External I/O or Memory |
.ext_io_addr_o(/*open */), |
.ext_io_data_o(/*open */), |
.ext_io_data_i(32'h00000000), |
.ext_io_wr_o(/*open */), |
.ext_io_rd_o(/*open */), |
.ext_io_pause_i(1'b0), |
|
// Debug UART output |
.dbg_uart_data_o(uart_data_o), |
.dbg_uart_wr_o(uart_wr_o) |
); |
|
endmodule |
/sim_verilator/test_image.bin
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
sim_verilator/test_image.bin
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: sim_verilator/top.h
===================================================================
--- sim_verilator/top.h (nonexistent)
+++ sim_verilator/top.h (revision 9)
@@ -0,0 +1,25 @@
+#ifndef __TOP_H__
+#define __TOP_H__
+
+//--------------------------------------------------------------------
+// Defines
+//--------------------------------------------------------------------
+#define TOP_RES_FAULT -1
+#define TOP_RES_OK 0
+#define TOP_RES_MAX_CYCLES 1
+#define TOP_RES_BREAKPOINT 2
+
+//--------------------------------------------------------------------
+// Prototypes
+//--------------------------------------------------------------------
+int top_init(void);
+int top_load(unsigned int addr, unsigned char val);
+void top_reset(void);
+void top_done(void);
+unsigned int top_getreg(int reg);
+unsigned int top_getpc(void);
+int top_run(int cycles, int intr_after_cycles);
+int top_setbreakpoint(int bp, unsigned int pc);
+
+
+#endif
Index: sim_verilator/sram4.v
===================================================================
--- sim_verilator/sram4.v (nonexistent)
+++ sim_verilator/sram4.v (revision 9)
@@ -0,0 +1,100 @@
+//-----------------------------------------------------------------
+// MPX 32-bit Soft-Core Processor
+// V0.1
+// Ultra-Embedded.com
+// Copyright 2011 - 2012
+//
+// Email: admin@ultra-embedded.com
+//
+// License: LGPL
+//
+// If you would like a version with a different license for use
+// in commercial projects please contact the above email address
+// for more details.
+//-----------------------------------------------------------------
+//
+// Copyright (C) 2011 - 2012 Ultra-Embedded.com
+//
+// This source file may be used and distributed without
+// restriction provided that this copyright statement is not
+// removed from the file and that any derivative work contains
+// the original copyright notice and the associated disclaimer.
+//
+// This source file is free software; you can redistribute it
+// and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation;
+// either version 2.1 of the License, or (at your option) any
+// later version.
+//
+// This source is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied
+// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+// PURPOSE. See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General
+// Public License along with this source; if not, write to the
+// Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+// Boston, MA 02111-1307 USA
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+// Module
+//-----------------------------------------------------------------
+module sram4
+(
+ clk_i,
+ address_i,
+ data_i,
+ data_o,
+ wr_i
+);
+
+//-----------------------------------------------------------------
+// Params
+//-----------------------------------------------------------------
+parameter [31:0] SRAM_ADDR_WIDTH = 14;
+
+//-----------------------------------------------------------------
+// I/O
+//-----------------------------------------------------------------
+input clk_i /*verilator public*/;
+input [31:0] address_i /*verilator public*/;
+input [31:0] data_i /*verilator public*/;
+output [31:0] data_o /*verilator public*/;
+input [3:0] wr_i /*verilator public*/;
+
+//-----------------------------------------------------------------
+// Registers
+//-----------------------------------------------------------------
+wire [31:0] address;
+wire [31:0] data_o;
+
+//-----------------------------------------------------------------
+// Implementation
+//-----------------------------------------------------------------
+assign address = {2'b00, address_i[31:2]};
+
+generate
+begin : sram_gen
+genvar i;
+for (i=0;i<4;i=i+1)
+ begin :sram_loop
+ sram
+ #(
+ .WIDTH(8),
+ .SIZE(SRAM_ADDR_WIDTH)
+ )
+ u1_bram
+ (
+ .clk_i(clk_i),
+ .dat_o(data_o[(((i + 1) * 8) - 1):(i * 8)]),
+ .dat_i(data_i[(((i + 1) * 8) - 1):(i * 8)]),
+ .adr_i(address[(SRAM_ADDR_WIDTH - 1):0]),
+ .wr_i(wr_i[i])
+ );
+ end
+end
+endgenerate
+
+endmodule
Index: sim_verilator/Readme.txt
===================================================================
--- sim_verilator/Readme.txt (nonexistent)
+++ sim_verilator/Readme.txt (revision 9)
@@ -0,0 +1,36 @@
+MPX RTL Simulation
+------------------
+
+This directory contains the Verilator RTL simulation model.
+
+Requirements:
+- verilator-3.831 or newer
+- GTKWave
+
+To run an application binary:
+ make TEST_IMAGE=test_image.bin
+
+Where test_image.bin is your compiled source which has a starting address of 0x10000000.
+
+To generate (GTKwave) waveforms;
+ make TEST_IMAGE=test_image.bin TRACE=1
+
+To view waveform with GTKWave:
+ make view
+
+Test image expected output
+--------------------------
+
+Test:
+1. Initialised data
+2. Multiply
+3. Divide
+4. Shift left
+5. Shift right
+6. Shift right arithmetic
+7. Signed comparision
+8. Word access
+9. Byte access
+10. SYSCALL return PC check
+11. Comparision
+Exit
Index: sim_verilator/makefile
===================================================================
--- sim_verilator/makefile (nonexistent)
+++ sim_verilator/makefile (revision 9)
@@ -0,0 +1,49 @@
+
+# Default binary to load & run
+TEST_IMAGE ?= test_image.bin
+SIMARGS ?=
+
+# Default core to simulate
+RTL_CORE ?= mpx
+CORE_FILENAME ?= mpx.v
+
+# Waveform trace disabled by default
+TRACE?= 0
+
+# Top module (without .v extension)
+TOP_MODULE = top
+
+# Additional modules which can't be auto found
+ADDITIONAL_MODULES = ../$(RTL_CORE)/$(CORE_FILENAME)
+
+# CPP Source Files
+SRC_CPP = main.cpp top.cpp
+
+# Source directories
+INC_DIRS = -I../$(RTL_CORE) -I../soc -I../peripheral
+
+# Build directory
+BUILD_DIR = build
+
+VERILATOR_OPTS =
+
+ifeq ($(TRACE),1)
+ VERILATOR_OPTS += --trace
+endif
+
+all: run
+
+compile: clean
+ verilator --cc $(TOP_MODULE).v $(ADDITIONAL_MODULES) $(SRC_CPP) $(INC_DIRS) +define+CONF_MPX_TARGET_SIM+ --exe -Mdir $(BUILD_DIR) $(VERILATOR_OPTS)
+ make -j -f V$(TOP_MODULE).mk -C $(BUILD_DIR)
+
+run: compile
+ ./$(BUILD_DIR)/V$(TOP_MODULE) -f $(TEST_IMAGE) $(SIMARGS)
+
+ifeq ($(TRACE),1)
+view:
+ gtkwave wave_dump.vcd gtksettings.sav
+endif
+
+clean :
+ -rm -rf $(BUILD_DIR)
Index: mpx/mpx_regfile_xil.v
===================================================================
--- mpx/mpx_regfile_xil.v (nonexistent)
+++ mpx/mpx_regfile_xil.v (revision 9)
@@ -0,0 +1,142 @@
+//-----------------------------------------------------------------
+// MPX 32-bit Soft-Core Processor
+// V0.1
+// Ultra-Embedded.com
+// Copyright 2011 - 2012
+//
+// Email: admin@ultra-embedded.com
+//
+// License: LGPL
+//
+// If you would like a version with a different license for use
+// in commercial projects please contact the above email address
+// for more details.
+//-----------------------------------------------------------------
+//
+// Copyright (C) 2011 - 2012 Ultra-Embedded.com
+//
+// This source file may be used and distributed without
+// restriction provided that this copyright statement is not
+// removed from the file and that any derivative work contains
+// the original copyright notice and the associated disclaimer.
+//
+// This source file is free software; you can redistribute it
+// and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation;
+// either version 2.1 of the License, or (at your option) any
+// later version.
+//
+// This source is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied
+// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+// PURPOSE. See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General
+// Public License along with this source; if not, write to the
+// Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+// Boston, MA 02111-1307 USA
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+// Includes
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+// Module
+//-----------------------------------------------------------------
+module mpx_regfile_xil
+(
+ clk_i,
+ rst_i,
+ en_i,
+ wr_i,
+ rs_i,
+ rt_i,
+ rd_i,
+ reg_rs_o,
+ reg_rt_o,
+ reg_rd_i
+);
+
+//-----------------------------------------------------------------
+// I/O
+//-----------------------------------------------------------------
+input clk_i /*verilator public*/;
+input rst_i /*verilator public*/;
+input en_i /*verilator public*/;
+input wr_i /*verilator public*/;
+input [4:0] rs_i /*verilator public*/;
+input [4:0] rt_i /*verilator public*/;
+input [4:0] rd_i /*verilator public*/;
+output [31:0] reg_rs_o /*verilator public*/;
+output [31:0] reg_rt_o /*verilator public*/;
+input [31:0] reg_rd_i /*verilator public*/;
+
+//-----------------------------------------------------------------
+// Registers
+//-----------------------------------------------------------------
+reg [4:0] addr_write;
+wire [31:0] data_out1;
+wire [31:0] data_out2;
+reg write_enable;
+wire [31:0] data_out1a;
+wire [31:0] data_out1b;
+wire [31:0] data_out2a;
+wire [31:0] data_out2b;
+wire wea;
+wire web;
+
+reg [31:0] reg_rs_o;
+reg [31:0] reg_rt_o;
+
+//-----------------------------------------------------------------
+// Async Read Process
+//-----------------------------------------------------------------
+always @ (clk_i or rs_i or rt_i or rd_i or reg_rd_i or data_out1 or data_out2 or rst_i or wr_i)
+begin
+ // Read Rs
+ if (rs_i == 5'b00000)
+ reg_rs_o <= 32'h00000000;
+ else
+ reg_rs_o <= data_out1;
+
+ // Read Rt
+ if (rt_i == 5'b00000)
+ reg_rt_o <= 32'h00000000;
+ else
+ reg_rt_o <= data_out2;
+
+ // Write enabled?
+ addr_write <= rd_i[4:0];
+ if ((rd_i != 5'b00000) & (wr_i == 1'b1))
+ write_enable <= 1'b1;
+ else
+ write_enable <= 1'b0;
+end
+
+//-----------------------------------------------------------------
+// Register File (using RAM16X1D )
+//-----------------------------------------------------------------
+generate
+begin
+ genvar i;
+ for (i=0;i<32;i=i+1)
+ begin : reg_loop
+ RAM16X1D reg_bit1a(.WCLK(clk_i), .WE(wea), .A0(addr_write[0]), .A1(addr_write[1]), .A2(addr_write[2]), .A3(addr_write[3]), .D(reg_rd_i[i]), .DPRA0(rs_i[0]), .DPRA1(rs_i[1]), .DPRA2(rs_i[2]), .DPRA3(rs_i[3]), .DPO(data_out1a[i]), .SPO(/* open */));
+ RAM16X1D reg_bit1b(.WCLK(clk_i), .WE(web), .A0(addr_write[0]), .A1(addr_write[1]), .A2(addr_write[2]), .A3(addr_write[3]), .D(reg_rd_i[i]), .DPRA0(rs_i[0]), .DPRA1(rs_i[1]), .DPRA2(rs_i[2]), .DPRA3(rs_i[3]), .DPO(data_out1b[i]), .SPO(/* open */));
+ RAM16X1D reg_bit2a(.WCLK(clk_i), .WE(wea), .A0(addr_write[0]), .A1(addr_write[1]), .A2(addr_write[2]), .A3(addr_write[3]), .D(reg_rd_i[i]), .DPRA0(rt_i[0]), .DPRA1(rt_i[1]), .DPRA2(rt_i[2]), .DPRA3(rt_i[3]), .DPO(data_out2a[i]), .SPO(/* open */));
+ RAM16X1D reg_bit2b(.WCLK(clk_i), .WE(web), .A0(addr_write[0]), .A1(addr_write[1]), .A2(addr_write[2]), .A3(addr_write[3]), .D(reg_rd_i[i]), .DPRA0(rt_i[0]), .DPRA1(rt_i[1]), .DPRA2(rt_i[2]), .DPRA3(rt_i[3]), .DPO(data_out2b[i]), .SPO(/* open */));
+ end
+end
+endgenerate
+
+//-----------------------------------------------------------------
+// Combinatorial Assignments
+//-----------------------------------------------------------------
+assign data_out1 = (rs_i[4] == 1'b0) ? data_out1a : data_out1b;
+assign data_out2 = (rt_i[4] == 1'b0) ? data_out2a : data_out2b;
+assign wea = (write_enable & ~ (addr_write[4]));
+assign web = (write_enable & addr_write[4]);
+
+endmodule
Index: mpx/mpx_funcs.v
===================================================================
--- mpx/mpx_funcs.v (nonexistent)
+++ mpx/mpx_funcs.v (revision 9)
@@ -0,0 +1,301 @@
+//-----------------------------------------------------------------
+// MPX 32-bit Soft-Core Processor
+// V0.1
+// Ultra-Embedded.com
+// Copyright 2011 - 2012
+//
+// Email: admin@ultra-embedded.com
+//
+// License: LGPL
+//
+// If you would like a version with a different license for use
+// in commercial projects please contact the above email address
+// for more details.
+//-----------------------------------------------------------------
+//
+// Copyright (C) 2011 - 2012 Ultra-Embedded.com
+//
+// This source file may be used and distributed without
+// restriction provided that this copyright statement is not
+// removed from the file and that any derivative work contains
+// the original copyright notice and the associated disclaimer.
+//
+// This source file is free software; you can redistribute it
+// and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation;
+// either version 2.1 of the License, or (at your option) any
+// later version.
+//
+// This source is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied
+// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+// PURPOSE. See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General
+// Public License along with this source; if not, write to the
+// Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+// Boston, MA 02111-1307 USA
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+// shift_left: Shift left by specified amount
+// Inputs: x = input, y = shift amount
+// Return: x << y
+//-----------------------------------------------------------------
+function [31:0] shift_left;
+ input [31:0] x;
+ input [31:0] y;
+ reg [31:0] shift1l;
+ reg [31:0] shift2l;
+ reg [31:0] shift4l;
+ reg [31:0] shift8l;
+ reg [31:0] shift16l;
+begin
+ if (y[0] == 1'b1)
+ shift1l = {x[30:0],1'b0};
+ else
+ shift1l = x;
+
+ if (y[1] == 1'b1)
+ shift2l = {shift1l[29:0],2'b00};
+ else
+ shift2l = shift1l;
+
+ if (y[2] == 1'b1)
+ shift4l = {shift2l[27:0],4'b0000};
+ else
+ shift4l = shift2l;
+
+ if (y[3] == 1'b1)
+ shift8l = {shift4l[23:0],8'b00000000};
+ else
+ shift8l = shift4l;
+
+ if (y[4] == 1'b1)
+ shift16l = {shift8l[15:0],16'b0000000000000000};
+ else
+ shift16l = shift8l;
+
+ shift_left = shift16l;
+end
+endfunction
+
+//-----------------------------------------------------------------
+// shift_right: Shift right by specified amount
+// Inputs: x = input, y = shift amount
+// Return: x >> y
+//-----------------------------------------------------------------
+function [31:0] shift_right;
+ input [31:0] x;
+ input [31:0] y;
+ reg [31:16] fill;
+ reg [31:0] shift1r;
+ reg [31:0] shift2r;
+ reg [31:0] shift4r;
+ reg [31:0] shift8r;
+ reg [31:0] shift16r;
+begin
+ fill = 16'b0000000000000000;
+ if (y[0] == 1'b1)
+ shift1r = {fill[31],x[31:1]};
+ else
+ shift1r = x;
+
+ if (y[1] == 1'b1)
+ shift2r = {fill[31:30],shift1r[31:2]};
+ else
+ shift2r = shift1r;
+
+ if (y[2] == 1'b1)
+ shift4r = {fill[31:28],shift2r[31:4]};
+ else
+ shift4r = shift2r;
+
+ if (y[3] == 1'b1)
+ shift8r = {fill[31:24],shift4r[31:8]};
+ else
+ shift8r = shift4r;
+
+ if (y[4] == 1'b1)
+ shift16r = {fill[31:16],shift8r[31:16]};
+ else
+ shift16r = shift8r;
+
+ shift_right = shift16r;
+end
+endfunction
+
+//-----------------------------------------------------------------
+// shift_right_arith: Shift right by specified amount (sign extend)
+// Inputs: x = input, y = shift amount
+// Return: (int)x >> y
+//-----------------------------------------------------------------
+function [31:0] shift_right_arith;
+ input [31:0] x;
+ input [31:0] y;
+ reg [31:16] fill;
+ reg [31:0] shift1r;
+ reg [31:0] shift2r;
+ reg [31:0] shift4r;
+ reg [31:0] shift8r;
+ reg [31:0] shift16r;
+begin
+ if (x[31] == 1'b1)
+ fill = 16'b1111111111111111;
+ else
+ fill = 16'b0000000000000000;
+
+ if (y[0] == 1'b1)
+ shift1r = {fill[31],x[31:1]};
+ else
+ shift1r = x;
+
+ if (y[1] == 1'b1)
+ shift2r = {fill[31:30],shift1r[31:2]};
+ else
+ shift2r = shift1r;
+
+ if (y[2] == 1'b1)
+ shift4r = {fill[31:28],shift2r[31:4]};
+ else
+ shift4r = shift2r;
+
+ if (y[3] == 1'b1)
+ shift8r = {fill[31:24],shift4r[31:8]};
+ else
+ shift8r = shift4r;
+
+ if (y[4] == 1'b1)
+ shift16r = {fill[31:16],shift8r[31:16]};
+ else
+ shift16r = shift8r;
+
+ shift_right_arith = shift16r;
+end
+endfunction
+
+//-----------------------------------------------------------------
+// less_than_signed: Less than operator (signed)
+// Inputs: x = left operand, y = right operand
+// Return: (int)x < (int)y
+//-----------------------------------------------------------------
+function [0:0] less_than_signed;
+ input [31:0] x;
+ input [31:0] y;
+ reg [31:0] v;
+begin
+ v = (x - y);
+ if (x[31] != y[31])
+ less_than_signed = x[31];
+ else
+ less_than_signed = v[31];
+end
+endfunction
+
+//-----------------------------------------------------------------
+// less_than: Less than operator (unsigned)
+// Inputs: x = left operand, y = right operand
+// Return: x < y
+//-----------------------------------------------------------------
+function [0:0] less_than;
+ input [31:0] x;
+ input [31:0] y;
+begin
+ if (x < y)
+ less_than = 1'b1;
+ else
+ less_than = 1'b0;
+end
+endfunction
+
+//-----------------------------------------------------------------
+// sign_extend_imm16: Extend 16-bit signed value to 32-bit signed.
+// Inputs: x = operand
+// Return: (int)((short)x)
+//-----------------------------------------------------------------
+function [31:0] sign_extend_imm16;
+ input [15:0] x;
+ reg [31:0] y;
+begin
+ if (x[15] == 1'b0)
+ y[31:16] = 16'b0000000000000000;
+ else
+ y[31:16] = 16'b1111111111111111;
+
+ y[15:0] = x;
+ sign_extend_imm16 = y;
+end
+endfunction
+
+//-----------------------------------------------------------------
+// extend_imm16: Extend 16-bit unsigned value to 32-bit unsigned.
+// Inputs: x = operand
+// Return: (unsigned int)x
+//-----------------------------------------------------------------
+function [31:0] extend_imm16;
+ input [15:0] x;
+begin
+ extend_imm16 = {16'h0000,x};
+end
+endfunction
+
+//-----------------------------------------------------------------
+// less_than_zero: Is signed value less than 0?
+// Inputs: x = operand
+// Return: ((int)x) < 0
+//-----------------------------------------------------------------
+function [0:0] less_than_zero;
+ input [31:0] x;
+begin
+ if ((x != 32'h00000000) & (x[31] == 1'b1))
+ less_than_zero = 1'b1;
+ else
+ less_than_zero = 1'b0;
+end
+endfunction
+
+//-----------------------------------------------------------------
+// less_than_equal_zero: Is signed value less than or equal to 0?
+// Inputs: x = operand
+// Return: ((int)x) <= 0
+//-----------------------------------------------------------------
+function [0:0] less_than_equal_zero;
+ input [31:0] x;
+begin
+ if ((x == 32'h00000000) | (x[31] == 1'b1))
+ less_than_equal_zero = 1'b1;
+ else
+ less_than_equal_zero = 1'b0;
+end
+endfunction
+
+//-----------------------------------------------------------------
+// more_than_equal_zero: Is signed value more than or equal to 0?
+// Inputs: x = operand
+// Return: ((int)x) >= 0
+//-----------------------------------------------------------------
+function [0:0] more_than_equal_zero;
+ input [31:0] x;
+begin
+ if ((x == 32'h00000000) | (x[31] == 1'b0))
+ more_than_equal_zero = 1'b1;
+ else
+ more_than_equal_zero = 1'b0;
+end
+endfunction
+
+//-----------------------------------------------------------------
+// more_than_equal_zero: Is signed value more than 0?
+// Inputs: x = operand
+// Return: ((int)x) > 0
+//-----------------------------------------------------------------
+function [0:0] more_than_zero;
+ input [31:0] x;
+begin
+ if (((x != 32'h00000000) & (x[31] == 1'b0)))
+ more_than_zero = 1'b1;
+ else
+ more_than_zero = 1'b0;
+end
+endfunction
Index: mpx/mpx.v
===================================================================
--- mpx/mpx.v (nonexistent)
+++ mpx/mpx.v (revision 9)
@@ -0,0 +1,1329 @@
+//-----------------------------------------------------------------
+// MPX 32-bit Soft-Core Processor
+// V0.1
+// Ultra-Embedded.com
+// Copyright 2011 - 2012
+//
+// Email: admin@ultra-embedded.com
+//
+// License: LGPL
+//
+// If you would like a version with a different license for use
+// in commercial projects please contact the above email address
+// for more details.
+//-----------------------------------------------------------------
+//
+// Copyright (C) 2011 - 2012 Ultra-Embedded.com
+//
+// This source file may be used and distributed without
+// restriction provided that this copyright statement is not
+// removed from the file and that any derivative work contains
+// the original copyright notice and the associated disclaimer.
+//
+// This source file is free software; you can redistribute it
+// and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation;
+// either version 2.1 of the License, or (at your option) any
+// later version.
+//
+// This source is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied
+// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+// PURPOSE. See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General
+// Public License along with this source; if not, write to the
+// Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+// Boston, MA 02111-1307 USA
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+// Includes
+//-----------------------------------------------------------------
+`include "mpx_defs.v"
+
+//-----------------------------------------------------------------
+// Module
+//-----------------------------------------------------------------
+module cpu
+(
+ // General
+ clk_i,
+ rst_i,
+ en_i,
+ intr_i,
+ fault_o,
+ break_o,
+
+ // Data Memory
+ mem_addr_o,
+ mem_data_out_o,
+ mem_data_in_i,
+ mem_wr_o,
+ mem_rd_o,
+ mem_pause_i
+);
+
+//-----------------------------------------------------------------
+// Params
+//-----------------------------------------------------------------
+parameter [31:0] BOOT_VECTOR = 32'h00000000;
+parameter [31:0] ISR_VECTOR = 32'h0000003C;
+parameter REGISTER_FILE_TYPE = "SIMULATION";
+
+//-----------------------------------------------------------------
+// I/O
+//-----------------------------------------------------------------
+// General
+input clk_i /*verilator public*/;
+input rst_i /*verilator public*/;
+input en_i /*verilator public*/;
+input intr_i /*verilator public*/;
+output fault_o /*verilator public*/;
+output break_o /*verilator public*/;
+
+// Data Memory
+output [31:0] mem_addr_o /*verilator public*/;
+output [31:0] mem_data_out_o /*verilator public*/;
+input [31:0] mem_data_in_i /*verilator public*/;
+output [3:0] mem_wr_o /*verilator public*/;
+output mem_rd_o /*verilator public*/;
+input mem_pause_i /*verilator public*/;
+
+//-----------------------------------------------------------------
+// Registers
+//-----------------------------------------------------------------
+
+// Other registers
+reg [31:0] r_pc;
+reg [31:0] r_epc;
+reg [31:0] r_status;
+reg [3:0] r_cause;
+reg [31:0] r_fault_info;
+reg [31:0] r_isr_vector;
+reg [31:0] r_lo;
+reg [31:0] r_hi;
+
+// Register file access
+wire [4:0] r_rt;
+wire [4:0] r_rd;
+reg [4:0] r_rd_wb;
+wire [4:0] r_rs;
+wire [31:0] r_reg_rt;
+wire [31:0] r_reg_rs;
+reg [31:0] r_reg_result;
+reg [31:0] r_reg_rd_out;
+reg r_writeback;
+
+// Pipeline registers
+reg [31:0] r_opcode;
+reg [31:0] d_opcode;
+reg r_branch_dslot;
+reg [4:0] d_rd_wb;
+reg [4:0] d2_rd_wb;
+reg [31:0] d_reg_result;
+reg c_load_op;
+reg [31:0] c_mem_forward;
+reg d_mem_access;
+
+// Memory
+reg [31:0] mem_addr;
+wire [31:0] mem_addr_mux;
+reg [31:0] mem_addr_last;
+reg [31:0] mem_data_out;
+wire [31:0] mem_data_in;
+reg [3:0] mem_wr;
+reg mem_rd;
+reg [1:0] mem_offset;
+reg [1:0] d_mem_offset;
+reg r_mem_access;
+reg [31:0] r_pc_branch;
+reg r_take_intr;
+reg d_take_intr;
+reg r_flush_next;
+
+// ALU
+reg [31:0] alu_a;
+reg [31:0] alu_b;
+wire [31:0] alu_result;
+reg [31:0] d_alu_result;
+reg [3:0] alu_func;
+reg [3:0] d_alu_func;
+
+reg fault_o;
+reg break_o;
+wire [31:0] mem_addr_o;
+wire [31:0] mem_data_out_o;
+wire [3:0] mem_wr_o;
+wire mem_rd_o;
+
+//-----------------------------------------------------------------
+// Instantiation
+//-----------------------------------------------------------------
+
+// ALU
+mpx_alu alu
+(
+ .input_a(alu_a),
+ .input_b(alu_b),
+ .func(alu_func),
+ .result(alu_result)
+);
+
+// Register file
+generate
+if (REGISTER_FILE_TYPE == "XILINX")
+begin
+ mpx_regfile_xil
+ reg_bank
+ (
+ // Clocking
+ .clk_i(clk_i),
+ .rst_i(rst_i),
+ .en_i(1'b1),
+ .wr_i(r_writeback),
+
+ // Tri-port
+ .rs_i(r_rs),
+ .rt_i(r_rt),
+ .rd_i(d2_rd_wb),
+ .reg_rs_o(r_reg_rs),
+ .reg_rt_o(r_reg_rt),
+ .reg_rd_i(r_reg_rd_out)
+ );
+end
+else
+begin
+ mpx_regfile_sim
+ reg_bank
+ (
+ // Clocking
+ .clk_i(clk_i),
+ .rst_i(rst_i),
+ .en_i(1'b1),
+ .wr_i(r_writeback),
+
+ // Tri-port
+ .rs_i(r_rs),
+ .rt_i(r_rt),
+ .rd_i(d2_rd_wb),
+ .reg_rs_o(r_reg_rs),
+ .reg_rt_o(r_reg_rt),
+ .reg_rd_i(r_reg_rd_out)
+ );
+end
+endgenerate
+
+//-------------------------------------------------------------------
+// Pipeline
+//-------------------------------------------------------------------
+always @ (posedge clk_i or posedge rst_i )
+begin
+ if (rst_i == 1'b1)
+ begin
+ d_opcode <= 32'h00000000;
+ d_rd_wb <= 5'b00000;
+ d2_rd_wb <= 5'b00000;
+ d_reg_result <= 32'h00000000;
+ d_alu_result <= 32'h00000000;
+ d_alu_func <= 4'b0000;
+ d_mem_offset <= 2'b00;
+ d_mem_access <= 1'b0;
+ d_take_intr <= 1'b0;
+ mem_addr_last <= 32'h00000000;
+ end
+ else if ((en_i == 1'b1) && (mem_pause_i == 1'b0))
+ begin
+ d_opcode <= r_opcode;
+ d_rd_wb <= r_rd_wb;
+ d2_rd_wb <= d_rd_wb;
+ d_reg_result <= r_reg_result;
+ d_alu_result <= alu_result;
+ d_alu_func <= alu_func;
+ d_mem_offset <= mem_offset;
+ d_mem_access <= r_mem_access;
+ d_take_intr <= r_take_intr;
+
+ if (r_mem_access == 1'b1)
+ mem_addr_last <= mem_addr;
+ else
+ mem_addr_last <= r_pc;
+ end
+end
+
+//-------------------------------------------------------------------
+// Execute
+//-------------------------------------------------------------------
+reg [7:0] v_inst;
+reg [4:0] v_rs;
+reg [4:0] v_rt;
+reg [4:0] v_rd;
+reg [4:0] v_re;
+reg [7:0] v_func;
+reg [15:0] v_imm;
+reg [31:0] v_imm_uint32;
+reg [31:0] v_imm_int32;
+reg [25:0] v_target;
+
+reg [31:0] v_reg_rs;
+reg [31:0] v_reg_rt;
+
+reg [31:0] v_pc;
+reg [31:0] v_pc_next;
+
+reg [31:0] v_reg_result;
+
+reg [31:0] v_offset;
+
+reg v_exception;
+reg v_emulate;
+
+reg v_branch;
+reg v_jmp;
+reg v_write_rt;
+reg v_write_rd;
+
+reg [31:0] v_mem_addr;
+reg v_mem_access;
+reg [31:0] v_mem_data_in;
+
+reg [31:0] v_status;
+
+always @ (posedge clk_i or posedge rst_i )
+begin
+ if (rst_i == 1'b1)
+ begin
+
+ // Default to no ALU operation
+ alu_func <= `ALU_NONE;
+
+ r_rd_wb <= 5'b00000;
+ r_pc <= BOOT_VECTOR;
+
+ r_epc <= 32'h00000000;
+ r_status <= 32'h00000000;
+ r_cause <= `EXCEPTION_NONE;
+ r_fault_info <= 32'h00000000;
+ r_lo <= 32'h00000000;
+ r_hi <= 32'h00000000;
+ r_branch_dslot <= 1'b0;
+ r_pc_branch <= 32'h00000000;
+ r_take_intr <= 1'b0;
+
+ r_opcode <= 32'h00000000;
+
+ mem_addr <= 32'h00000000;
+ mem_data_out <= 32'h00000000;
+ mem_rd <= 1'b0;
+ mem_wr <= 4'b0000;
+ mem_offset <= 2'b00;
+
+ // Default ISR vector address
+ r_isr_vector <= ISR_VECTOR;
+
+ fault_o <= 1'b0;
+ break_o <= 1'b0;
+ r_mem_access <= 1'b0;
+
+ // Flush first instruction execute to allow fetch to occur
+ r_flush_next <= 1'b1;
+
+ end
+ else if ((en_i == 1'b1) && (mem_pause_i == 1'b0))
+ begin
+
+ mem_rd <= 1'b0;
+ mem_wr <= 4'b0000;
+
+ break_o <= 1'b0;
+
+ v_exception = 1'b0;
+ v_emulate = 1'b0;
+ v_branch = 1'b0;
+ v_jmp = 1'b0;
+ v_write_rt = 1'b0;
+ v_write_rd = 1'b0;
+ v_status = r_status;
+ v_mem_access = 1'b0;
+ v_mem_data_in = mem_data_in_i;
+
+ // If memory access was done, check for no instruction to process.
+ // As memory access has a 1 cycle latency, invalid mem_data_in_i is
+ // aligned with d_mem_access not r_mem_access.
+ if (d_mem_access == 1'b1)
+ v_mem_data_in = `OPCODE_INST_BUBBLE;
+
+ // Flush pipeline due to an exception/interrupt?
+ // NOTE: When d_take_intr=1, mem_data_in_i will be invalid for one more cycle
+ if ((r_take_intr == 1'b1) || (d_take_intr == 1'b1))
+ v_mem_data_in = `OPCODE_INST_BUBBLE;
+
+ // Flush next instruction for some reason
+ if (r_flush_next)
+ begin
+ v_mem_data_in = `OPCODE_INST_BUBBLE;
+ end
+
+ r_take_intr <= 1'b0;
+ r_flush_next <= 1'b0;
+
+ // Decode opcode
+ r_opcode <= v_mem_data_in;
+ v_inst = {2'b00,v_mem_data_in[31:26]};
+ v_rs = v_mem_data_in[25:21];
+ v_rt = v_mem_data_in[20:16];
+ v_rd = v_mem_data_in[15:11];
+ v_re = v_mem_data_in[10:6];
+ v_func = {2'b00,v_mem_data_in[5:0]};
+ v_imm = v_mem_data_in[15:0];
+ v_target = v_mem_data_in[25:0];
+
+ // Signed & unsigned imm -> 32-bits
+ v_imm_int32 = sign_extend_imm16(v_imm);
+ v_imm_uint32 = extend_imm16(v_imm);
+
+ // Load register[rs]
+ v_reg_rs = r_reg_rs;
+
+ // Load register[rt]
+ v_reg_rt = r_reg_rt;
+
+ // Register[rs] hazard detection & forwarding logic
+ // (higher priority = latest results!)
+ if (v_rs != 5'b00000)
+ begin
+ if (v_rs == r_rd_wb)
+ begin
+ // Result from memory / other
+ if (alu_func == `ALU_NONE)
+ begin
+ v_reg_rs = r_reg_result;
+ end
+ // Result from ALU
+ else
+ begin
+ v_reg_rs = alu_result;
+ end
+ end
+ else if (v_rs == d_rd_wb)
+ begin
+ // Result from memory load?
+ if (c_load_op == 1'b1)
+ begin
+ v_reg_rs = c_mem_forward;
+ end
+ // Result from memory / other
+ else if (d_alu_func == `ALU_NONE)
+ begin
+ v_reg_rs = d_reg_result;
+ end
+ // Result from ALU
+ else
+ begin
+ v_reg_rs = d_alu_result;
+ end
+ end
+ else if (v_rs == d2_rd_wb)
+ begin
+ v_reg_rs = r_reg_rd_out;
+ end
+ end
+
+ // Register[rt] hazard detection & forwarding logic
+ // (higher priority = latest results!)
+ if (v_rt != 5'b00000)
+ begin
+ if (v_rt == r_rd_wb)
+ begin
+ // Result from memory / other
+ if (alu_func == `ALU_NONE)
+ begin
+ v_reg_rt = r_reg_result;
+ end
+ // Result from ALU
+ else
+ begin
+ v_reg_rt = alu_result;
+ end
+ end
+ else if (v_rt == d_rd_wb)
+ begin
+ // Result from memory load?
+ if (c_load_op == 1'b1)
+ begin
+ v_reg_rt = c_mem_forward;
+ end
+ // Result from non ALU function
+ else if (d_alu_func == `ALU_NONE)
+ begin
+ v_reg_rt = d_reg_result;
+ end
+ // Result from ALU
+ else
+ begin
+ v_reg_rt = d_alu_result;
+ end
+
+ end
+ else if (v_rt == d2_rd_wb)
+ begin
+ v_reg_rt = r_reg_rd_out;
+ end
+ end
+
+ // Zero result
+ v_reg_result = 32'h00000000;
+
+ // Update PC to next value
+ v_pc = (r_pc + 4);
+
+ // Default to no ALU operation
+ alu_func <= `ALU_NONE;
+
+ // Default target is r_rd
+ r_rd_wb <= r_rd;
+
+ // Reset branch delay slot status
+ r_branch_dslot <= 1'b0;
+
+ // Execute instruction
+ case (v_inst)
+ 8'h00 :
+ case (v_func)
+ `INSTR_R_SLL:
+ begin
+ alu_func <= `ALU_SHIFTL;
+ alu_a <= v_reg_rt;
+ alu_b <= {27'b0, v_re};
+ v_write_rd = 1'b1;
+ end
+
+ `INSTR_R_SRL:
+ begin
+ alu_func <= `ALU_SHIFTR;
+ alu_a <= v_reg_rt;
+ alu_b <= {27'b0, v_re};
+ v_write_rd = 1'b1;
+ end
+
+ `INSTR_R_SRA:
+ begin
+ alu_func <= `ALU_SHIRTR_ARITH;
+ alu_a <= v_reg_rt;
+ alu_b <= {27'b0, v_re};
+ v_write_rd = 1'b1;
+ end
+
+ `INSTR_R_SLLV:
+ begin
+ alu_func <= `ALU_SHIFTL;
+ alu_a <= v_reg_rt;
+ alu_b <= v_reg_rs;
+ v_write_rd = 1'b1;
+ end
+
+ `INSTR_R_SRLV:
+ begin
+ alu_func <= `ALU_SHIFTR;
+ alu_a <= v_reg_rt;
+ alu_b <= v_reg_rs;
+ v_write_rd = 1'b1;
+ end
+
+ `INSTR_R_SRAV:
+ begin
+ alu_func <= `ALU_SHIRTR_ARITH;
+ alu_a <= v_reg_rt;
+ alu_b <= v_reg_rs;
+ v_write_rd = 1'b1;
+ end
+
+ `INSTR_R_JR:
+ begin
+ v_pc = v_reg_rs;
+ v_jmp = 1'b1;
+ end
+
+ `INSTR_R_JALR:
+ begin
+ v_reg_result = v_pc;
+ v_write_rd = 1'b1;
+ v_pc = v_reg_rs;
+ v_jmp = 1'b1;
+ end
+
+ `INSTR_R_SYSCALL:
+ begin
+ v_exception = 1'b1;
+ r_cause <= `EXCEPTION_SYSCALL;
+ end
+
+ `INSTR_R_BREAK:
+ begin
+ v_exception = 1'b1;
+ break_o <= 1'b1;
+ r_cause <= `EXCEPTION_BREAK;
+ end
+
+ `INSTR_R_MFHI:
+ begin
+ v_reg_result = r_hi;
+ v_write_rd = 1'b1;
+ end
+
+ `INSTR_R_MTHI:
+ begin
+ r_hi <= v_reg_rs;
+ end
+
+ `INSTR_R_MFLO:
+ begin
+ v_reg_result = r_lo;
+ v_write_rd = 1'b1;
+ end
+
+ `INSTR_R_MTLO:
+ begin
+ r_lo <= v_reg_rs;
+ end
+
+ `INSTR_R_MULT:
+ begin
+ v_exception = 1'b1;
+ v_emulate = 1'b1;
+ r_cause <= `EXCEPTION_MULT;
+ end
+
+ `INSTR_R_MULTU:
+ begin
+ v_exception = 1'b1;
+ v_emulate = 1'b1;
+ r_cause <= `EXCEPTION_UMULT;
+ end
+
+ `INSTR_R_DIV:
+ begin
+ v_exception = 1'b1;
+ v_emulate = 1'b1;
+ r_cause <= `EXCEPTION_DIV;
+ end
+
+ `INSTR_R_DIVU:
+ begin
+ v_exception = 1'b1;
+ v_emulate = 1'b1;
+ r_cause <= `EXCEPTION_UDIV;
+ end
+
+ `INSTR_R_ADD:
+ begin
+ alu_func <= `ALU_ADD;
+ alu_a <= v_reg_rs;
+ alu_b <= v_reg_rt;
+ v_write_rd = 1'b1;
+ end
+
+ `INSTR_R_ADDU:
+ begin
+ alu_func <= `ALU_ADD;
+ alu_a <= v_reg_rs;
+ alu_b <= v_reg_rt;
+ v_write_rd = 1'b1;
+ end
+
+ `INSTR_R_SUB:
+ begin
+ alu_func <= `ALU_SUB;
+ alu_a <= v_reg_rs;
+ alu_b <= v_reg_rt;
+ v_write_rd = 1'b1;
+ end
+
+ `INSTR_R_SUBU:
+ begin
+ alu_func <= `ALU_SUB;
+ alu_a <= v_reg_rs;
+ alu_b <= v_reg_rt;
+ v_write_rd = 1'b1;
+ end
+
+ `INSTR_R_AND:
+ begin
+ alu_func <= `ALU_AND;
+ alu_a <= v_reg_rs;
+ alu_b <= v_reg_rt;
+ v_write_rd = 1'b1;
+ end
+
+ `INSTR_R_OR:
+ begin
+ alu_func <= `ALU_OR;
+ alu_a <= v_reg_rs;
+ alu_b <= v_reg_rt;
+ v_write_rd = 1'b1;
+ end
+
+ `INSTR_R_XOR:
+ begin
+ alu_func <= `ALU_XOR;
+ alu_a <= v_reg_rs;
+ alu_b <= v_reg_rt;
+ v_write_rd = 1'b1;
+ end
+
+ `INSTR_R_NOR:
+ begin
+ alu_func <= `ALU_NOR;
+ alu_a <= v_reg_rs;
+ alu_b <= v_reg_rt;
+ v_write_rd = 1'b1;
+ end
+
+ `INSTR_R_SLT:
+ begin
+ alu_func <= `ALU_SLT;
+ alu_a <= v_reg_rs;
+ alu_b <= v_reg_rt;
+ v_write_rd = 1'b1;
+ end
+
+ `INSTR_R_SLTU:
+ begin
+ alu_func <= `ALU_SLTU;
+ alu_a <= v_reg_rs;
+ alu_b <= v_reg_rt;
+ v_write_rd = 1'b1;
+ end
+ default :
+ begin
+ fault_o <= 1'b1;
+ v_exception = 1'b1;
+ r_cause <= `EXCEPTION_FAULT;
+ r_fault_info <= v_mem_data_in;
+ end
+ endcase
+
+ // REGIMM
+ `INSTR_I_REGIMM :
+ case (v_rt)
+ `INSTR_I_COND_BLTZAL : // BLTZAL [ branch = ((int)v_reg_rs < 0) ]
+ begin
+ v_reg_result = v_pc;
+ v_write_rd = 1'b1;
+ r_rd_wb <= 5'b11111; // Write to $ra
+ v_branch = less_than_zero(v_reg_rs);
+ end
+
+ `INSTR_I_COND_BLTZ : // BLTZ [ branch = ((int)v_reg_rs < 0) ]
+ begin
+ v_branch = less_than_zero(v_reg_rs);
+ end
+
+ `INSTR_I_COND_BGEZAL : // BGEZAL [ branch = ((int)v_reg_rs >= 0) ]
+ begin
+ v_reg_result = v_pc;
+ v_write_rd = 1'b1;
+ r_rd_wb <= 5'b11111; // Write to $ra
+ v_branch = more_than_equal_zero(v_reg_rs);
+ end
+
+ `INSTR_I_COND_BGEZ : // BGEZ [ branch = ((int)v_reg_rs >= 0) ]
+ begin
+ v_branch = more_than_equal_zero(v_reg_rs);
+ end
+
+ default :
+ begin
+ fault_o <= 1'b1;
+ v_exception = 1'b1;
+ r_cause <= `EXCEPTION_FAULT;
+ r_fault_info <= v_mem_data_in;
+ end
+ endcase
+
+ `INSTR_J_JAL:
+ begin
+ v_reg_result = v_pc;
+ v_write_rd = 1'b1;
+ r_rd_wb <= 5'b11111; // Write to $ra
+ v_pc = {{v_pc[31:28],v_target[25:0]},2'b00};
+ v_jmp = 1'b1;
+ end
+
+ `INSTR_J_J:
+ begin
+ v_pc = {{v_pc[31:28],v_target[25:0]},2'b00};
+ v_jmp = 1'b1;
+ end
+
+ `INSTR_J_BEQ:
+ begin
+ if (v_reg_rs == v_reg_rt)
+ v_branch = 1'b1;
+ end
+
+ `INSTR_J_BNE:
+ begin
+ if (v_reg_rs != v_reg_rt)
+ v_branch = 1'b1;
+ end
+
+ `INSTR_J_BLEZ : // BLEZ [ branch = (int)v_reg_rs <= 0 ]
+ v_branch = less_than_equal_zero(v_reg_rs);
+
+ `INSTR_J_BGTZ : // BGTZ [ branch = (int)v_reg_rs > 0 ]
+ v_branch = more_than_zero(v_reg_rs);
+
+ `INSTR_I_ADDI:
+ begin
+ alu_func <= `ALU_ADD;
+ alu_a <= v_reg_rs;
+ alu_b <= v_imm_int32;
+ v_write_rt = 1'b1;
+ end
+
+ `INSTR_I_ADDIU:
+ begin
+ alu_func <= `ALU_ADD;
+ alu_a <= v_reg_rs;
+ alu_b <= v_imm_int32;
+ v_write_rt = 1'b1;
+ end
+
+ `INSTR_I_SLTI:
+ begin
+ alu_func <= `ALU_SLT;
+ alu_a <= v_reg_rs;
+ alu_b <= v_imm_int32;
+ v_write_rt = 1'b1;
+ end
+
+ `INSTR_I_SLTIU:
+ begin
+ alu_func <= `ALU_SLTU;
+ alu_a <= v_reg_rs;
+ alu_b <= v_imm_int32;
+ v_write_rt = 1'b1;
+ end
+
+ `INSTR_I_ANDI:
+ begin
+ alu_func <= `ALU_AND;
+ alu_a <= v_reg_rs;
+ alu_b <= v_imm_uint32;
+ v_write_rt = 1'b1;
+ end
+
+ `INSTR_I_ORI:
+ begin
+ alu_func <= `ALU_OR;
+ alu_a <= v_reg_rs;
+ alu_b <= v_imm_uint32;
+ v_write_rt = 1'b1;
+ end
+
+ `INSTR_I_XORI:
+ begin
+ alu_func <= `ALU_XOR;
+ alu_a <= v_reg_rs;
+ alu_b <= v_imm_uint32;
+ v_write_rt = 1'b1;
+ end
+
+ `INSTR_I_LUI:
+ begin
+ v_reg_result = {v_imm,16'h0000};
+ v_write_rt = 1'b1;
+ end
+
+ `INSTR_COP0:
+ begin
+
+ // Move from CP0
+ if (v_rs[2] == 1'b0)
+ case (v_rd)
+ `COP0_STATUS:
+ begin
+ v_reg_result = r_status;
+ v_write_rt = 1'b1;
+ end
+
+ `COP0_CAUSE:
+ begin
+ v_reg_result = {28'h0000000,r_cause};
+ v_write_rt = 1'b1;
+ end
+
+ `COP0_EPC:
+ begin
+ v_reg_result = r_epc;
+ v_write_rt = 1'b1;
+ end
+
+ `COP0_ISR_VECT:
+ begin
+ v_reg_result = r_isr_vector;
+ v_write_rt = 1'b1;
+ end
+
+ `COP0_FAULT_INFO:
+ begin
+ v_reg_result = r_fault_info;
+ v_write_rt = 1'b1;
+ end
+
+ default :
+ begin
+ end
+
+ endcase
+
+ // Move to CP0
+ else
+ case (v_rd)
+ `COP0_STATUS:
+ begin
+ r_status <= v_reg_rt;
+ v_status = v_reg_rt;
+ end
+
+ `COP0_CAUSE:
+ r_cause <= v_reg_rt[3:0];
+
+ `COP0_EPC:
+ r_epc <= v_reg_rt;
+
+ `COP0_ISR_VECT:
+ r_isr_vector <= v_reg_rt;
+
+ `COP0_FAULT_INFO:
+ r_fault_info <= v_reg_rt;
+
+ default :
+ begin
+ end
+ endcase
+ end
+
+ // Memory load / store instructions
+
+ `INSTR_I_LB, `INSTR_I_LH, `INSTR_I_LW, `INSTR_I_LBU, `INSTR_I_LHU :
+ begin
+ v_mem_addr = (v_reg_rs + v_imm_int32);
+ mem_addr <= {v_mem_addr[31:2],2'b00};
+ mem_data_out <= 32'h00000000;
+ mem_rd <= 1'b1;
+ mem_offset <= v_mem_addr[1:0];
+ v_write_rt = 1'b1;
+ v_mem_access = 1'b1;
+ end
+
+ `INSTR_I_SB:
+ begin
+ v_mem_addr = (v_reg_rs + v_imm_int32);
+ mem_addr <= {v_mem_addr[31:2],2'b00};
+ case (v_mem_addr[1:0])
+ 2'b00 :
+ begin
+ mem_data_out <= {v_reg_rt[7:0],24'h000000};
+ mem_wr <= 4'b1000;
+ v_mem_access = 1'b1;
+ end
+ 2'b01 :
+ begin
+ mem_data_out <= {{8'h00,v_reg_rt[7:0]},16'h0000};
+ mem_wr <= 4'b0100;
+ v_mem_access = 1'b1;
+ end
+ 2'b10 :
+ begin
+ mem_data_out <= {{16'h0000,v_reg_rt[7:0]},8'h00};
+ mem_wr <= 4'b0010;
+ v_mem_access = 1'b1;
+ end
+ 2'b11 :
+ begin
+ mem_data_out <= {24'h000000,v_reg_rt[7:0]};
+ mem_wr <= 4'b0001;
+ v_mem_access = 1'b1;
+ end
+ default :
+ begin
+ mem_data_out <= 32'h00000000;
+ mem_wr <= 4'b0000;
+ end
+ endcase
+ end
+
+ `INSTR_I_SH:
+ begin
+ v_mem_addr = (v_reg_rs + v_imm_int32);
+ mem_addr <= {v_mem_addr[31:2],2'b00};
+ case (v_mem_addr[1:0])
+ 2'b00 :
+ begin
+ mem_data_out <= {v_reg_rt[15:0],16'h0000};
+ mem_wr <= 4'b1100;
+ v_mem_access = 1'b1;
+ end
+ 2'b10 :
+ begin
+ mem_data_out <= {16'h0000,v_reg_rt[15:0]};
+ mem_wr <= 4'b0011;
+ v_mem_access = 1'b1;
+ end
+ default :
+ begin
+ mem_data_out <= 32'h00000000;
+ mem_wr <= 4'b0000;
+ end
+ endcase
+ end
+
+ `INSTR_I_SW:
+ begin
+ v_mem_addr = (v_reg_rs + v_imm_int32);
+ mem_addr <= {v_mem_addr[31:2],2'b00};
+ mem_data_out <= v_reg_rt;
+ mem_wr <= 4'b1111;
+ v_mem_access = 1'b1;
+ end
+
+ `INSTR_BUBBLE:
+ begin
+ end
+
+ default :
+ begin
+ fault_o <= 1'b1;
+ v_exception = 1'b1;
+ r_cause <= `EXCEPTION_FAULT;
+ r_fault_info <= v_mem_data_in;
+ end
+ endcase
+
+ // Handle branches
+ if (v_branch == 1'b1)
+ begin
+ v_offset = v_imm_int32;
+ v_offset = {v_offset[29:0],2'b00};
+ v_pc = (r_pc + v_offset);
+
+ // Next instruction is branch delay slot
+ r_branch_dslot <= 1'b1;
+ r_pc_branch <= v_pc;
+ end
+ // If not branching, handle interrupts / exceptions
+ else if ((v_jmp == 1'b0) && (v_inst != `INSTR_BUBBLE))
+ begin
+
+ // Exception (Fault/Mult/Div/Syscall/Break)
+ if (v_exception == 1'b1)
+ begin
+
+ // Schedule interrupt after pipeline flush
+ r_take_intr <= 1'b1;
+
+ // Record instruction to continue from
+ r_epc <= r_pc;
+
+ // Disable interrupts by shifting left status register
+ r_status <= {v_status[30:0],1'b0};
+ end
+ // External interrupt (and not handling an exception, branch or bubble)?
+ // NOTE: d_mem_access & r_branch_dslot are exclusive as this would result in a bubble
+ else if ((intr_i == 1'b1) && (v_status[0] == 1'b1))
+ begin
+ // Schedule interrupt after pipeline flush
+ r_take_intr <= 1'b1;
+
+ // Interrupt src is external
+ r_cause <= `EXCEPTION_EXTINT;
+
+ // Record instruction to continue from
+ r_epc <= r_pc;
+
+ // Disable interrupts by shifting left status register
+ r_status <= {v_status[30:0],1'b0};
+ end
+ end
+ // Handle jumps
+ else if (v_jmp == 1'b1)
+ begin
+ // Next instruction is branch delay slot
+ r_branch_dslot <= 1'b1;
+ r_pc_branch <= v_pc;
+ end
+
+ // Update to new PC value only if last cycle wasn't a memory access
+ if (r_mem_access == 1'b0)
+ r_pc <= v_pc;
+
+ // Stall in branch delay slot due to mem access?
+ if ((d_mem_access == 1'b1) && (r_branch_dslot == 1'b1))
+ r_pc <= r_pc_branch;
+
+ // If pipeline flushed due to interrupt request
+ if (r_take_intr == 1'b1)
+ begin
+ // Jump to ISR
+ r_pc <= r_isr_vector;
+ end
+
+ // Update other registers with variable values
+ r_reg_result <= v_reg_result;
+ r_mem_access <= v_mem_access;
+
+ // Target is Register[rt]
+ if (v_write_rt == 1'b1)
+ begin
+ // Store new value to register[rt] instead of register[rd]
+ r_rd_wb <= r_rt;
+ end
+ // No writeback required?
+ else if ((v_write_rt == 1'b0) && (v_write_rd == 1'b0))
+ begin
+ // Target register is $0 which is read-only
+ r_rd_wb <= 5'b00000;
+ end
+ end
+end
+
+//-------------------------------------------------------------------
+// Writeback
+//-------------------------------------------------------------------
+reg [31:0] wb_v_reg_result;
+reg [7:0] wb_v_inst;
+
+always @ (posedge clk_i or posedge rst_i )
+begin
+ if (rst_i == 1'b1)
+ begin
+ r_writeback <= 1'b1;
+ end
+ else
+ begin
+ r_writeback <= 1'b0;
+
+ if ((en_i == 1'b1) && (mem_pause_i == 1'b0))
+ begin
+
+ wb_v_reg_result = d_reg_result;
+
+ // Handle delayed result instructions
+ wb_v_inst = {2'b00,d_opcode[31:26]};
+ case (wb_v_inst)
+ `INSTR_I_LB:
+ begin
+ case (d_mem_offset)
+ 2'b00 :
+ wb_v_reg_result = {24'h000000,mem_data_in_i[31:24]};
+ 2'b01 :
+ wb_v_reg_result = {24'h000000,mem_data_in_i[23:16]};
+ 2'b10 :
+ wb_v_reg_result = {24'h000000,mem_data_in_i[15:8]};
+ 2'b11 :
+ wb_v_reg_result = {24'h000000,mem_data_in_i[7:0]};
+ default :
+ wb_v_reg_result = 32'h00000000;
+ endcase
+
+ // Sign extend LB
+ if (wb_v_reg_result[7] == 1'b1)
+ wb_v_reg_result = {24'hFFFFFF,wb_v_reg_result[7:0]};
+ end
+
+ `INSTR_I_LBU:
+ case (d_mem_offset)
+ 2'b00 :
+ wb_v_reg_result = {24'h000000,mem_data_in_i[31:24]};
+ 2'b01 :
+ wb_v_reg_result = {24'h000000,mem_data_in_i[23:16]};
+ 2'b10 :
+ wb_v_reg_result = {24'h000000,mem_data_in_i[15:8]};
+ 2'b11 :
+ wb_v_reg_result = {24'h000000,mem_data_in_i[7:0]};
+ default :
+ wb_v_reg_result = 32'h00000000;
+ endcase
+
+ `INSTR_I_LH:
+ begin
+ case (d_mem_offset)
+ 2'b00 :
+ wb_v_reg_result = {16'h0000,mem_data_in_i[31:16]};
+ 2'b10 :
+ wb_v_reg_result = {16'h0000,mem_data_in_i[15:0]};
+ default :
+ wb_v_reg_result = 32'h00000000;
+ endcase
+
+ // Sign extend LH
+ if (wb_v_reg_result[15] == 1'b1)
+ wb_v_reg_result = {16'h1111,wb_v_reg_result[15:0]};
+ end
+
+ `INSTR_I_LHU:
+ case (d_mem_offset)
+ 2'b00 :
+ wb_v_reg_result = {16'h0000,mem_data_in_i[31:16]};
+ 2'b10 :
+ wb_v_reg_result = {16'h0000,mem_data_in_i[15:0]};
+ default :
+ wb_v_reg_result = 32'h00000000;
+ endcase
+
+ `INSTR_I_LW:
+ wb_v_reg_result = mem_data_in_i;
+
+ default :
+ wb_v_reg_result = d_reg_result;
+ endcase
+
+ // Result from memory / other
+ if ((d_alu_func == `ALU_NONE))
+ begin
+ r_reg_rd_out <= wb_v_reg_result;
+ end
+ // Result from ALU
+ else
+ begin
+ r_reg_rd_out <= d_alu_result;
+ end
+
+ // Register writeback required?
+ if (d_rd_wb != 5'b00000)
+ r_writeback <= 1'b1;
+ end
+ end
+end
+
+//-------------------------------------------------------------------
+// Combinatorial
+//-----------------------------------------------------------------//
+
+// Memory access mux
+assign mem_data_in = mem_data_in_i;
+assign mem_addr_mux = (r_mem_access == 1'b1) ? mem_addr : r_pc;
+assign mem_addr_o = (mem_pause_i == 1'b1) ? mem_addr_last : mem_addr_mux;
+assign mem_data_out_o = mem_data_out;
+assign mem_rd_o = (r_mem_access == 1'b1) ? mem_rd : 1'b1;
+assign mem_wr_o = (mem_pause_i == 1'b0) ? mem_wr : 4'b0000;
+
+// Opcode register decoding
+assign r_rs = mem_data_in_i[25:21];
+assign r_rt = mem_data_in_i[20:16];
+assign r_rd = mem_data_in_i[15:11];
+
+//-------------------------------------------------------------------
+// Async memory result forwarding
+//-------------------------------------------------------------------
+reg [31:0] ldf_v_reg_result;
+reg [7:0] ldf_v_inst;
+
+always @ (d_opcode or mem_offset or mem_data_in_i )
+begin
+
+ // Handle delayed result instructions
+ ldf_v_inst = {2'b00,d_opcode[31:26]};
+ case (ldf_v_inst)
+
+ `INSTR_I_LB:
+ begin
+ c_load_op = 1'b1;
+ case (mem_offset)
+ 2'b00 :
+ ldf_v_reg_result = {24'h000000,mem_data_in_i[31:24]};
+ 2'b01 :
+ ldf_v_reg_result = {24'h000000,mem_data_in_i[23:16]};
+ 2'b10 :
+ ldf_v_reg_result = {24'h000000,mem_data_in_i[15:8]};
+ 2'b11 :
+ ldf_v_reg_result = {24'h000000,mem_data_in_i[7:0]};
+ default :
+ ldf_v_reg_result = 32'h00000000;
+ endcase
+
+ // Sign extend LB
+ if (ldf_v_reg_result[7] == 1'b1)
+ ldf_v_reg_result = {24'hFFFFFF,ldf_v_reg_result[7:0]};
+ end
+
+ `INSTR_I_LBU:
+ begin
+ c_load_op = 1'b1;
+ case (mem_offset)
+ 2'b00 :
+ ldf_v_reg_result = {24'h000000,mem_data_in_i[31:24]};
+ 2'b01 :
+ ldf_v_reg_result = {24'h000000,mem_data_in_i[23:16]};
+ 2'b10 :
+ ldf_v_reg_result = {24'h000000,mem_data_in_i[15:8]};
+ 2'b11 :
+ ldf_v_reg_result = {24'h000000,mem_data_in_i[7:0]};
+ default :
+ ldf_v_reg_result = 32'h00000000;
+ endcase
+ end
+
+ `INSTR_I_LH:
+ begin
+ c_load_op = 1'b1;
+ case (mem_offset)
+ 2'b00 :
+ ldf_v_reg_result = {16'h0000,mem_data_in_i[31:16]};
+ 2'b10 :
+ ldf_v_reg_result = {16'h0000,mem_data_in_i[15:0]};
+ default :
+ ldf_v_reg_result = 32'h00000000;
+ endcase
+
+ // Sign extend LH
+ if (ldf_v_reg_result[15] == 1'b1)
+ ldf_v_reg_result = {16'h1111,ldf_v_reg_result[15:0]};
+ end
+
+ `INSTR_I_LHU:
+ begin
+ c_load_op = 1'b1;
+ case (mem_offset)
+ 2'b00 :
+ ldf_v_reg_result = {16'h0000,mem_data_in_i[31:16]};
+ 2'b10 :
+ ldf_v_reg_result = {16'h0000,mem_data_in_i[15:0]};
+ default :
+ ldf_v_reg_result = 32'h00000000;
+ endcase
+ end
+
+ `INSTR_I_LW:
+ begin
+ c_load_op = 1'b1;
+ ldf_v_reg_result = mem_data_in_i;
+ end
+
+ default :
+ begin
+ c_load_op = 1'b0;
+ ldf_v_reg_result = 32'h00000000;
+ end
+ endcase
+
+ c_mem_forward = ldf_v_reg_result;
+end
+
+`include "mpx_funcs.v"
+
+//-------------------------------------------------------------------
+// Hooks for debug
+//-------------------------------------------------------------------
+`ifdef verilator
+ function [31:0] get_pc;
+ // verilator public
+ get_pc = r_pc;
+ endfunction
+`endif
+
+
+endmodule
Index: mpx/mpx_defs.v
===================================================================
--- mpx/mpx_defs.v (nonexistent)
+++ mpx/mpx_defs.v (revision 9)
@@ -0,0 +1,152 @@
+//-----------------------------------------------------------------
+// MPX 32-bit Soft-Core Processor
+// V0.1
+// Ultra-Embedded.com
+// Copyright 2011 - 2012
+//
+// Email: admin@ultra-embedded.com
+//
+// License: LGPL
+//
+// If you would like a version with a different license for use
+// in commercial projects please contact the above email address
+// for more details.
+//-----------------------------------------------------------------
+//
+// Copyright (C) 2011 - 2012 Ultra-Embedded.com
+//
+// This source file may be used and distributed without
+// restriction provided that this copyright statement is not
+// removed from the file and that any derivative work contains
+// the original copyright notice and the associated disclaimer.
+//
+// This source file is free software; you can redistribute it
+// and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation;
+// either version 2.1 of the License, or (at your option) any
+// later version.
+//
+// This source is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied
+// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+// PURPOSE. See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General
+// Public License along with this source; if not, write to the
+// Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+// Boston, MA 02111-1307 USA
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+// ALU Operations
+//-----------------------------------------------------------------
+`define ALU_NONE 4'b0000
+`define ALU_SHIFTL 4'b0001
+`define ALU_SHIFTR 4'b0010
+`define ALU_SHIRTR_ARITH 4'b0011
+`define ALU_ADD 4'b0100
+`define ALU_SUB 4'b0101
+`define ALU_AND 4'b0110
+`define ALU_OR 4'b0111
+`define ALU_XOR 4'b1000
+`define ALU_NOR 4'b1001
+`define ALU_SLT 4'b1010
+`define ALU_SLTE 4'b1011
+`define ALU_SLTU 4'b1100
+
+//-----------------------------------------------------------------
+// Instructions
+//-----------------------------------------------------------------
+
+// R Type
+`define INSTR_R_SLL 8'h00
+`define INSTR_R_SRL 8'h02
+`define INSTR_R_SRA 8'h03
+`define INSTR_R_SLLV 8'h04
+`define INSTR_R_SRLV 8'h06
+`define INSTR_R_SRAV 8'h07
+`define INSTR_R_JR 8'h08
+`define INSTR_R_JALR 8'h09
+`define INSTR_R_SYSCALL 8'h0c
+`define INSTR_R_BREAK 8'h0d
+`define INSTR_R_MFHI 8'h10
+`define INSTR_R_MTHI 8'h11
+`define INSTR_R_MFLO 8'h12
+`define INSTR_R_MTLO 8'h13
+`define INSTR_R_MULT 8'h18
+`define INSTR_R_MULTU 8'h19
+`define INSTR_R_DIV 8'h1a
+`define INSTR_R_DIVU 8'h1b
+`define INSTR_R_ADD 8'h20
+`define INSTR_R_ADDU 8'h21
+`define INSTR_R_SUB 8'h22
+`define INSTR_R_SUBU 8'h23
+`define INSTR_R_AND 8'h24
+`define INSTR_R_OR 8'h25
+`define INSTR_R_XOR 8'h26
+`define INSTR_R_NOR 8'h27
+`define INSTR_R_SLT 8'h2a
+`define INSTR_R_SLTU 8'h2b
+
+`define INSTR_COP0 8'h10
+
+// J Type
+`define INSTR_J_JAL 8'h03
+`define INSTR_J_J 8'h02
+`define INSTR_J_BEQ 8'h04
+`define INSTR_J_BNE 8'h05
+`define INSTR_J_BLEZ 8'h06
+`define INSTR_J_BGTZ 8'h07
+
+// I Type
+`define INSTR_I_ADDI 8'h08
+`define INSTR_I_ADDIU 8'h09
+`define INSTR_I_SLTI 8'h0a
+`define INSTR_I_SLTIU 8'h0b
+`define INSTR_I_ANDI 8'h0c
+`define INSTR_I_ORI 8'h0d
+`define INSTR_I_XORI 8'h0e
+`define INSTR_I_LUI 8'h0f
+`define INSTR_I_LB 8'h20
+`define INSTR_I_LH 8'h21
+`define INSTR_I_LW 8'h23
+`define INSTR_I_LBU 8'h24
+`define INSTR_I_LHU 8'h25
+`define INSTR_I_SB 8'h28
+`define INSTR_I_SH 8'h29
+`define INSTR_I_SW 8'h2b
+
+`define INSTR_I_REGIMM 8'h01
+`define INSTR_I_COND_BLTZAL 5'b10000
+`define INSTR_I_COND_BLTZ 5'b00000
+`define INSTR_I_COND_BGEZAL 5'b10001
+`define INSTR_I_COND_BGEZ 5'b00001
+
+`define INSTR_BUBBLE 8'h3F
+
+`define OPCODE_INST_BUBBLE 32'hFC000000
+
+//-----------------------------------------------------------------
+// COP0
+//-----------------------------------------------------------------
+`define COP0_STATUS 5'b01100
+`define COP0_CAUSE 5'b01101
+`define COP0_EPC 5'b01110
+`define COP0_ISR_VECT 5'b01111
+`define COP0_FAULT_INFO 5'b10000
+`define COP0_MULT_LO 5'b10001
+`define COP0_MULT_HI 5'b10010
+
+//-----------------------------------------------------------------
+// Exception Cause (COP0_CAUSE)
+//-----------------------------------------------------------------
+`define EXCEPTION_NONE 4'b0000
+`define EXCEPTION_SYSCALL 4'b0001
+`define EXCEPTION_BREAK 4'b0010
+`define EXCEPTION_EXTINT 4'b0011
+`define EXCEPTION_FAULT 4'b0100
+`define EXCEPTION_MULT 4'b0101
+`define EXCEPTION_UMULT 4'b0110
+`define EXCEPTION_DIV 4'b0111
+`define EXCEPTION_UDIV 4'b1000
Index: mpx/mpx_alu.v
===================================================================
--- mpx/mpx_alu.v (nonexistent)
+++ mpx/mpx_alu.v (revision 9)
@@ -0,0 +1,113 @@
+//-----------------------------------------------------------------
+// MPX 32-bit Soft-Core Processor
+// V0.1
+// Ultra-Embedded.com
+// Copyright 2011 - 2012
+//
+// Email: admin@ultra-embedded.com
+//
+// License: LGPL
+//
+// If you would like a version with a different license for use
+// in commercial projects please contact the above email address
+// for more details.
+//-----------------------------------------------------------------
+//
+// Copyright (C) 2011 - 2012 Ultra-Embedded.com
+//
+// This source file may be used and distributed without
+// restriction provided that this copyright statement is not
+// removed from the file and that any derivative work contains
+// the original copyright notice and the associated disclaimer.
+//
+// This source file is free software; you can redistribute it
+// and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation;
+// either version 2.1 of the License, or (at your option) any
+// later version.
+//
+// This source is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied
+// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+// PURPOSE. See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General
+// Public License along with this source; if not, write to the
+// Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+// Boston, MA 02111-1307 USA
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+// Includes
+//-----------------------------------------------------------------
+`include "mpx_defs.v"
+
+//-----------------------------------------------------------------
+// Module
+//-----------------------------------------------------------------
+module mpx_alu
+(
+ input_a,
+ input_b,
+ func,
+ result
+);
+
+//-----------------------------------------------------------------
+// I/O
+//-----------------------------------------------------------------
+input [31:0] input_a /*verilator public*/;
+input [31:0] input_b /*verilator public*/;
+input [3:0] func /*verilator public*/;
+output [31:0] result /*verilator public*/;
+
+//-----------------------------------------------------------------
+// Registers
+//-----------------------------------------------------------------
+reg [31:0] result;
+
+//-----------------------------------------------------------------
+// ALU
+//-----------------------------------------------------------------
+always @ (func or input_a or input_b )
+begin
+ case (func)
+ `ALU_SHIFTL : result = shift_left(input_a, input_b);
+ `ALU_SHIFTR : result = shift_right(input_a, input_b);
+ `ALU_SHIRTR_ARITH: result = shift_right_arith(input_a, input_b);
+ `ALU_ADD : result = (input_a + input_b);
+ `ALU_SUB : result = (input_a - input_b);
+ `ALU_AND : result = (input_a & input_b);
+ `ALU_OR : result = (input_a | input_b);
+ `ALU_XOR : result = (input_a ^ input_b);
+ `ALU_NOR : result = (~(input_a | input_b));
+ `ALU_SLT :
+ begin
+ if (less_than_signed(input_a, input_b) == 1'b1)
+ result = 32'h00000001;
+ else
+ result = 32'h00000000;
+ end
+ `ALU_SLTE :
+ begin
+ if ((less_than_signed(input_a, input_b) == 1'b1) || (input_a == input_b))
+ result = 32'h00000001;
+ else
+ result = 32'h00000000;
+ end
+ `ALU_SLTU :
+ begin
+ if (less_than(input_a, input_b) == 1'b1)
+ result = 32'h00000001;
+ else
+ result = 32'h00000000;
+ end
+ default :
+ result = 32'h00000000;
+ endcase
+end
+
+`include "mpx_funcs.v"
+
+endmodule
Index: mpx/mpx_regfile_sim.v
===================================================================
--- mpx/mpx_regfile_sim.v (nonexistent)
+++ mpx/mpx_regfile_sim.v (revision 9)
@@ -0,0 +1,372 @@
+//-----------------------------------------------------------------
+// MPX 32-bit Soft-Core Processor
+// V0.1
+// Ultra-Embedded.com
+// Copyright 2011 - 2012
+//
+// Email: admin@ultra-embedded.com
+//
+// License: LGPL
+//
+// If you would like a version with a different license for use
+// in commercial projects please contact the above email address
+// for more details.
+//-----------------------------------------------------------------
+//
+// Copyright (C) 2011 - 2012 Ultra-Embedded.com
+//
+// This source file may be used and distributed without
+// restriction provided that this copyright statement is not
+// removed from the file and that any derivative work contains
+// the original copyright notice and the associated disclaimer.
+//
+// This source file is free software; you can redistribute it
+// and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation;
+// either version 2.1 of the License, or (at your option) any
+// later version.
+//
+// This source is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied
+// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+// PURPOSE. See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General
+// Public License along with this source; if not, write to the
+// Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+// Boston, MA 02111-1307 USA
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+// Includes
+//-----------------------------------------------------------------
+`include "mpx_defs.v"
+
+//-----------------------------------------------------------------
+// Module
+//-----------------------------------------------------------------
+module mpx_regfile_sim
+(
+ clk_i,
+ rst_i,
+ en_i,
+ wr_i,
+ rs_i,
+ rt_i,
+ rd_i,
+ reg_rs_o,
+ reg_rt_o,
+ reg_rd_i
+);
+
+//-----------------------------------------------------------------
+// I/O
+//-----------------------------------------------------------------
+input clk_i /*verilator public*/;
+input rst_i /*verilator public*/;
+input en_i /*verilator public*/;
+input wr_i /*verilator public*/;
+input [4:0] rs_i /*verilator public*/;
+input [4:0] rt_i /*verilator public*/;
+input [4:0] rd_i /*verilator public*/;
+output [31:0] reg_rs_o /*verilator public*/;
+output [31:0] reg_rt_o /*verilator public*/;
+input [31:0] reg_rd_i /*verilator public*/;
+
+//-----------------------------------------------------------------
+// Registers
+//-----------------------------------------------------------------
+
+// Register file
+reg [31:0] reg_r1_at;
+reg [31:0] reg_r2_v0;
+reg [31:0] reg_r3_v1;
+reg [31:0] reg_r4_a0;
+reg [31:0] reg_r5_a1;
+reg [31:0] reg_r6_a2;
+reg [31:0] reg_r7_a3;
+reg [31:0] reg_r8;
+reg [31:0] reg_r9;
+reg [31:0] reg_r10;
+reg [31:0] reg_r11;
+reg [31:0] reg_r12;
+reg [31:0] reg_r13;
+reg [31:0] reg_r14;
+reg [31:0] reg_r15;
+reg [31:0] reg_r16;
+reg [31:0] reg_r17;
+reg [31:0] reg_r18;
+reg [31:0] reg_r19;
+reg [31:0] reg_r20;
+reg [31:0] reg_r21;
+reg [31:0] reg_r22;
+reg [31:0] reg_r23;
+reg [31:0] reg_r24;
+reg [31:0] reg_r25;
+reg [31:0] reg_k0;
+reg [31:0] reg_k1;
+reg [31:0] reg_gp;
+reg [31:0] reg_sp;
+reg [31:0] reg_fp;
+reg [31:0] reg_ra;
+
+reg [31:0] reg_rs_o;
+reg [31:0] reg_rt_o;
+
+//-----------------------------------------------------------------
+// Register File (for simulation)
+//-----------------------------------------------------------------
+
+// Synchronous register write back
+always @ (posedge clk_i or posedge rst_i)
+begin
+ if (rst_i)
+ begin
+ reg_r1_at <= 32'h00000000;
+ reg_r2_v0 <= 32'h00000000;
+ reg_r3_v1 <= 32'h00000000;
+ reg_r4_a0 <= 32'h00000000;
+ reg_r5_a1 <= 32'h00000000;
+ reg_r6_a2 <= 32'h00000000;
+ reg_r7_a3 <= 32'h00000000;
+ reg_r8 <= 32'h00000000;
+ reg_r9 <= 32'h00000000;
+ reg_r10 <= 32'h00000000;
+ reg_r11 <= 32'h00000000;
+ reg_r12 <= 32'h00000000;
+ reg_r13 <= 32'h00000000;
+ reg_r14 <= 32'h00000000;
+ reg_r15 <= 32'h00000000;
+ reg_r16 <= 32'h00000000;
+ reg_r17 <= 32'h00000000;
+ reg_r18 <= 32'h00000000;
+ reg_r19 <= 32'h00000000;
+ reg_r20 <= 32'h00000000;
+ reg_r21 <= 32'h00000000;
+ reg_r22 <= 32'h00000000;
+ reg_r23 <= 32'h00000000;
+ reg_r24 <= 32'h00000000;
+ reg_r25 <= 32'h00000000;
+ reg_k0 <= 32'h00000000;
+ reg_k1 <= 32'h00000000;
+ reg_gp <= 32'h00000000;
+ reg_sp <= 32'h00000000;
+ reg_fp <= 32'h00000000;
+ reg_ra <= 32'h00000000;
+ end
+ else if (en_i == 1'b1)
+ begin
+ if (wr_i == 1'b1)
+ case (rd_i[4:0])
+ 5'b00001 :
+ reg_r1_at <= reg_rd_i;
+ 5'b00010 :
+ reg_r2_v0 <= reg_rd_i;
+ 5'b00011 :
+ reg_r3_v1 <= reg_rd_i;
+ 5'b00100 :
+ reg_r4_a0 <= reg_rd_i;
+ 5'b00101 :
+ reg_r5_a1 <= reg_rd_i;
+ 5'b00110 :
+ reg_r6_a2 <= reg_rd_i;
+ 5'b00111 :
+ reg_r7_a3 <= reg_rd_i;
+ 5'b01000 :
+ reg_r8 <= reg_rd_i;
+ 5'b01001 :
+ reg_r9 <= reg_rd_i;
+ 5'b01010 :
+ reg_r10 <= reg_rd_i;
+ 5'b01011 :
+ reg_r11 <= reg_rd_i;
+ 5'b01100 :
+ reg_r12 <= reg_rd_i;
+ 5'b01101 :
+ reg_r13 <= reg_rd_i;
+ 5'b01110 :
+ reg_r14 <= reg_rd_i;
+ 5'b01111 :
+ reg_r15 <= reg_rd_i;
+ 5'b10000 :
+ reg_r16 <= reg_rd_i;
+ 5'b10001 :
+ reg_r17 <= reg_rd_i;
+ 5'b10010 :
+ reg_r18 <= reg_rd_i;
+ 5'b10011 :
+ reg_r19 <= reg_rd_i;
+ 5'b10100 :
+ reg_r20 <= reg_rd_i;
+ 5'b10101 :
+ reg_r21 <= reg_rd_i;
+ 5'b10110 :
+ reg_r22 <= reg_rd_i;
+ 5'b10111 :
+ reg_r23 <= reg_rd_i;
+ 5'b11000 :
+ reg_r24 <= reg_rd_i;
+ 5'b11001 :
+ reg_r25 <= reg_rd_i;
+ 5'b11010 :
+ reg_k0 <= reg_rd_i;
+ 5'b11011 :
+ reg_k1 <= reg_rd_i;
+ 5'b11100 :
+ reg_gp <= reg_rd_i;
+ 5'b11101 :
+ reg_sp <= reg_rd_i;
+ 5'b11110 :
+ reg_fp <= reg_rd_i;
+ 5'b11111 :
+ reg_ra <= reg_rd_i;
+ default :
+ ;
+ endcase
+ end
+end
+
+// Asynchronous Register read (Rs & Rd)
+always @ (rs_i or rt_i or reg_r1_at or reg_r2_v0 or reg_r3_v1 or reg_r4_a0 or reg_r5_a1 or reg_r6_a2 or reg_r7_a3 or reg_r8 or reg_r9 or reg_r10 or reg_r11 or reg_r12 or reg_r13 or reg_r14 or reg_r15 or reg_r16 or reg_r17 or reg_r18 or reg_r19 or reg_r20 or reg_r21 or reg_r22 or reg_r23 or reg_r24 or reg_r25 or reg_k0 or reg_k1 or reg_gp or reg_sp or reg_fp or reg_ra )
+begin
+ case (rs_i)
+ 5'b00000 :
+ reg_rs_o = 32'h00000000;
+ 5'b00001 :
+ reg_rs_o = reg_r1_at;
+ 5'b00010 :
+ reg_rs_o = reg_r2_v0;
+ 5'b00011 :
+ reg_rs_o = reg_r3_v1;
+ 5'b00100 :
+ reg_rs_o = reg_r4_a0;
+ 5'b00101 :
+ reg_rs_o = reg_r5_a1;
+ 5'b00110 :
+ reg_rs_o = reg_r6_a2;
+ 5'b00111 :
+ reg_rs_o = reg_r7_a3;
+ 5'b01000 :
+ reg_rs_o = reg_r8;
+ 5'b01001 :
+ reg_rs_o = reg_r9;
+ 5'b01010 :
+ reg_rs_o = reg_r10;
+ 5'b01011 :
+ reg_rs_o = reg_r11;
+ 5'b01100 :
+ reg_rs_o = reg_r12;
+ 5'b01101 :
+ reg_rs_o = reg_r13;
+ 5'b01110 :
+ reg_rs_o = reg_r14;
+ 5'b01111 :
+ reg_rs_o = reg_r15;
+ 5'b10000 :
+ reg_rs_o = reg_r16;
+ 5'b10001 :
+ reg_rs_o = reg_r17;
+ 5'b10010 :
+ reg_rs_o = reg_r18;
+ 5'b10011 :
+ reg_rs_o = reg_r19;
+ 5'b10100 :
+ reg_rs_o = reg_r20;
+ 5'b10101 :
+ reg_rs_o = reg_r21;
+ 5'b10110 :
+ reg_rs_o = reg_r22;
+ 5'b10111 :
+ reg_rs_o = reg_r23;
+ 5'b11000 :
+ reg_rs_o = reg_r24;
+ 5'b11001 :
+ reg_rs_o = reg_r25;
+ 5'b11010 :
+ reg_rs_o = reg_k0;
+ 5'b11011 :
+ reg_rs_o = reg_k1;
+ 5'b11100 :
+ reg_rs_o = reg_gp;
+ 5'b11101 :
+ reg_rs_o = reg_sp;
+ 5'b11110 :
+ reg_rs_o = reg_fp;
+ 5'b11111 :
+ reg_rs_o = reg_ra;
+ default :
+ reg_rs_o = 32'h00000000;
+ endcase
+
+ case (rt_i)
+ 5'b00000 :
+ reg_rt_o = 32'h00000000;
+ 5'b00001 :
+ reg_rt_o = reg_r1_at;
+ 5'b00010 :
+ reg_rt_o = reg_r2_v0;
+ 5'b00011 :
+ reg_rt_o = reg_r3_v1;
+ 5'b00100 :
+ reg_rt_o = reg_r4_a0;
+ 5'b00101 :
+ reg_rt_o = reg_r5_a1;
+ 5'b00110 :
+ reg_rt_o = reg_r6_a2;
+ 5'b00111 :
+ reg_rt_o = reg_r7_a3;
+ 5'b01000 :
+ reg_rt_o = reg_r8;
+ 5'b01001 :
+ reg_rt_o = reg_r9;
+ 5'b01010 :
+ reg_rt_o = reg_r10;
+ 5'b01011 :
+ reg_rt_o = reg_r11;
+ 5'b01100 :
+ reg_rt_o = reg_r12;
+ 5'b01101 :
+ reg_rt_o = reg_r13;
+ 5'b01110 :
+ reg_rt_o = reg_r14;
+ 5'b01111 :
+ reg_rt_o = reg_r15;
+ 5'b10000 :
+ reg_rt_o = reg_r16;
+ 5'b10001 :
+ reg_rt_o = reg_r17;
+ 5'b10010 :
+ reg_rt_o = reg_r18;
+ 5'b10011 :
+ reg_rt_o = reg_r19;
+ 5'b10100 :
+ reg_rt_o = reg_r20;
+ 5'b10101 :
+ reg_rt_o = reg_r21;
+ 5'b10110 :
+ reg_rt_o = reg_r22;
+ 5'b10111 :
+ reg_rt_o = reg_r23;
+ 5'b11000 :
+ reg_rt_o = reg_r24;
+ 5'b11001 :
+ reg_rt_o = reg_r25;
+ 5'b11010 :
+ reg_rt_o = reg_k0;
+ 5'b11011 :
+ reg_rt_o = reg_k1;
+ 5'b11100 :
+ reg_rt_o = reg_gp;
+ 5'b11101 :
+ reg_rt_o = reg_sp;
+ 5'b11110 :
+ reg_rt_o = reg_fp;
+ 5'b11111 :
+ reg_rt_o = reg_ra;
+ default :
+ reg_rt_o = 32'h00000000;
+ endcase
+end
+
+endmodule
Index: soc/soc_core.v
===================================================================
--- soc/soc_core.v (nonexistent)
+++ soc/soc_core.v (revision 9)
@@ -0,0 +1,539 @@
+//-----------------------------------------------------------------
+// MPX 32-bit Soft-Core Processor
+// V0.1
+// Ultra-Embedded.com
+// Copyright 2011 - 2012
+//
+// Email: admin@ultra-embedded.com
+//
+// License: LGPL
+//
+// If you would like a version with a different license for use
+// in commercial projects please contact the above email address
+// for more details.
+//-----------------------------------------------------------------
+//
+// Copyright (C) 2011 - 2012 Ultra-Embedded.com
+//
+// This source file may be used and distributed without
+// restriction provided that this copyright statement is not
+// removed from the file and that any derivative work contains
+// the original copyright notice and the associated disclaimer.
+//
+// This source file is free software; you can redistribute it
+// and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation;
+// either version 2.1 of the License, or (at your option) any
+// later version.
+//
+// This source is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied
+// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+// PURPOSE. See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General
+// Public License along with this source; if not, write to the
+// Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+// Boston, MA 02111-1307 USA
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+// Module:
+//-----------------------------------------------------------------
+module soc_core
+(
+ // General - Clocking & Reset
+ clk_i,
+ rst_i,
+ en_i,
+ ext_intr_i,
+ fault_o,
+ break_o,
+
+ // UART
+ uart_tx_o,
+ uart_rx_i,
+
+ // BootRAM
+ int_mem_addr_o,
+ int_mem_data_o,
+ int_mem_data_i,
+ int_mem_wr_o,
+ int_mem_rd_o,
+ int_mem_pause_i,
+
+ // External Memory (0x11000000 - 0x11FFFFFF)
+ ext_mem_addr_o,
+ ext_mem_data_o,
+ ext_mem_data_i,
+ ext_mem_wr_o,
+ ext_mem_rd_o,
+ ext_mem_pause_i,
+
+ // External IO ( 0x13000000 - 0x13FFFFFF)
+ ext_io_addr_o,
+ ext_io_data_o,
+ ext_io_data_i,
+ ext_io_wr_o,
+ ext_io_rd_o,
+ ext_io_pause_i,
+
+ // Other Memory (0x14000000 - 0x14FFFFFF)
+`ifdef CONF_ALTSOC_BUS_ALT
+ ext_alt_addr_o,
+ ext_alt_data_o,
+ ext_alt_data_i,
+ ext_alt_wr_o,
+ ext_alt_rd_o,
+ ext_alt_pause_i,
+`endif
+
+ // SPI Flash
+ flash_cs_o,
+ flash_si_o,
+ flash_so_i,
+ flash_sck_o,
+
+ // Debug UART output
+ dbg_uart_data_o,
+ dbg_uart_wr_o
+);
+
+//-----------------------------------------------------------------
+// Params
+//-----------------------------------------------------------------
+parameter [31:0] CLK_KHZ = 12288;
+parameter [31:0] UART_BAUD = 115200;
+parameter [31:0] SPI_FLASH_CLK_KHZ = (12288/2);
+parameter [31:0] EXTERNAL_INTERRUPTS = 1;
+parameter BOOT_VECTOR = 0;
+parameter ISR_VECTOR = 0;
+parameter REGISTER_FILE_TYPE = "SIMULATION";
+parameter ENABLE_UART = "ENABLED";
+parameter ENABLE_SPI_FLASH = "ENABLED";
+parameter SYSTICK_INTR_MS = 1;
+parameter ENABLE_SYSTICK_TIMER = "ENABLED";
+parameter ENABLE_HIGHRES_TIMER = "ENABLED";
+
+//-----------------------------------------------------------------
+// I/O
+//-----------------------------------------------------------------
+input clk_i /*verilator public*/;
+input rst_i /*verilator public*/;
+input en_i /*verilator public*/;
+output fault_o /*verilator public*/;
+output break_o /*verilator public*/;
+input [(EXTERNAL_INTERRUPTS - 1):0] ext_intr_i /*verilator public*/;
+output uart_tx_o /*verilator public*/;
+input uart_rx_i /*verilator public*/;
+output [31:0] int_mem_addr_o /*verilator public*/;
+output [31:0] int_mem_data_o /*verilator public*/;
+input [31:0] int_mem_data_i /*verilator public*/;
+output [3:0] int_mem_wr_o /*verilator public*/;
+output int_mem_rd_o /*verilator public*/;
+input int_mem_pause_i /*verilator public*/;
+output [31:0] ext_mem_addr_o /*verilator public*/;
+output [31:0] ext_mem_data_o /*verilator public*/;
+input [31:0] ext_mem_data_i /*verilator public*/;
+output [3:0] ext_mem_wr_o /*verilator public*/;
+output ext_mem_rd_o /*verilator public*/;
+input ext_mem_pause_i /*verilator public*/;
+output [31:0] ext_io_addr_o /*verilator public*/;
+output [31:0] ext_io_data_o /*verilator public*/;
+input [31:0] ext_io_data_i /*verilator public*/;
+output [3:0] ext_io_wr_o /*verilator public*/;
+output ext_io_rd_o /*verilator public*/;
+input ext_io_pause_i /*verilator public*/;
+`ifdef CONF_ALTSOC_BUS_ALT
+output [31:0] ext_alt_addr_o /*verilator public*/;
+output [31:0] ext_alt_data_o /*verilator public*/;
+input [31:0] ext_alt_data_i /*verilator public*/;
+output [3:0] ext_alt_wr_o /*verilator public*/;
+output ext_alt_rd_o /*verilator public*/;
+input ext_alt_pause_i /*verilator public*/;
+`endif
+output flash_cs_o /*verilator public*/;
+output flash_si_o /*verilator public*/;
+input flash_so_i /*verilator public*/;
+output flash_sck_o /*verilator public*/;
+output [7:0] dbg_uart_data_o /*verilator public*/;
+output dbg_uart_wr_o /*verilator public*/;
+
+//-----------------------------------------------------------------
+// Registers
+//-----------------------------------------------------------------
+wire [31:0] cpu_address;
+wire [3:0] cpu_wr;
+wire cpu_rd;
+wire [31:0] cpu_data_w;
+wire [31:0] cpu_data_r;
+wire cpu_pause;
+
+wire [31:0] io_address;
+wire [31:0] io_data_w;
+wire [31:0] io_data_r;
+wire [3:0] io_wr;
+wire io_rd;
+
+// IRQ Status
+wire intr_in;
+
+// Output Signals
+wire uart_tx_o;
+wire [31:0] int_mem_addr_o;
+wire [31:0] int_mem_data_o;
+wire [3:0] int_mem_wr_o;
+wire int_mem_rd_o;
+wire [31:0] ext_io_addr_o;
+wire [31:0] ext_io_data_o;
+wire [3:0] ext_io_wr_o;
+wire ext_io_rd_o;
+wire [31:0] ext_mem_addr_o;
+wire [31:0] ext_mem_data_o;
+wire [3:0] ext_mem_wr_o;
+wire ext_mem_rd_o;
+`ifdef CONF_ALTSOC_BUS_ALT
+wire [31:0] ext_alt_addr_o;
+wire [31:0] ext_alt_data_o;
+wire [3:0] ext_alt_wr_o;
+wire ext_alt_rd_o;
+`endif
+wire flash_cs_o;
+wire flash_si_o;
+wire flash_sck_o;
+
+// Peripheral Interface
+wire [7:0] uart_addr;
+wire [31:0] uart_data_o;
+wire [31:0] uart_data_i;
+wire [3:0] uart_wr;
+wire uart_rd;
+wire uart_intr;
+
+wire [7:0] spi_addr;
+wire [31:0] spi_data_o;
+wire [31:0] spi_data_i;
+wire [3:0] spi_wr;
+wire spi_rd;
+
+wire [7:0] timer_addr;
+wire [31:0] timer_data_o;
+wire [31:0] timer_data_i;
+wire [3:0] timer_wr;
+wire timer_rd;
+wire timer_intr_systick;
+wire timer_intr_hires;
+
+wire [7:0] intr_addr;
+wire [31:0] intr_data_o;
+wire [31:0] intr_data_i;
+wire [3:0] intr_wr;
+wire intr_rd;
+
+//-----------------------------------------------------------------
+// CPU core
+//-----------------------------------------------------------------
+cpu
+#(
+ .BOOT_VECTOR(BOOT_VECTOR),
+ .ISR_VECTOR(ISR_VECTOR),
+ .REGISTER_FILE_TYPE(REGISTER_FILE_TYPE)
+)
+u1_cpu
+(
+ .clk_i(clk_i),
+ .rst_i(rst_i),
+ .en_i(en_i),
+ .intr_i(intr_in),
+ .fault_o(fault_o),
+ .break_o(break_o),
+ .mem_addr_o(cpu_address),
+ .mem_data_out_o(cpu_data_w),
+ .mem_data_in_i(cpu_data_r),
+ .mem_wr_o(cpu_wr),
+ .mem_rd_o(cpu_rd),
+ .mem_pause_i(cpu_pause)
+);
+
+//-----------------------------------------------------------------
+// Memory MUX
+//-----------------------------------------------------------------
+mem_mux
+#(
+ .BOOT_VECTOR(BOOT_VECTOR),
+ .ADDR_MUX_START(24)
+)
+u2_mux
+(
+ .clk_i(clk_i),
+ .rst_i(rst_i),
+
+ // Input - CPU core bus
+ .mem_addr_i(cpu_address),
+ .mem_data_i(cpu_data_w),
+ .mem_data_o(cpu_data_r),
+ .mem_wr_i(cpu_wr),
+ .mem_rd_i(cpu_rd),
+ .mem_pause_o(cpu_pause),
+
+ // Outputs
+ // 0x10000000 - 0x10FFFFFF
+ .out0_addr_o(int_mem_addr_o),
+ .out0_data_o(int_mem_data_o),
+ .out0_data_i(int_mem_data_i),
+ .out0_wr_o(int_mem_wr_o),
+ .out0_rd_o(int_mem_rd_o),
+ .out0_pause_i(int_mem_pause_i),
+
+ // 0x11000000 - 0x11FFFFFF
+ .out1_addr_o(ext_mem_addr_o),
+ .out1_data_o(ext_mem_data_o),
+ .out1_data_i(ext_mem_data_i),
+ .out1_wr_o(ext_mem_wr_o),
+ .out1_rd_o(ext_mem_rd_o),
+ .out1_pause_i(ext_mem_pause_i),
+
+ // 0x12000000 - 0x12FFFFFF
+ .out2_addr_o(io_address),
+ .out2_data_o(io_data_w),
+ .out2_data_i(io_data_r),
+ .out2_wr_o(io_wr),
+ .out2_rd_o(io_rd),
+ .out2_pause_i(1'b0),
+
+ // 0x13000000 - 0x13FFFFFF
+ .out3_addr_o(ext_io_addr_o),
+ .out3_data_o(ext_io_data_o),
+ .out3_data_i(ext_io_data_i),
+ .out3_wr_o(ext_io_wr_o),
+ .out3_rd_o(ext_io_rd_o),
+ .out3_pause_i(ext_io_pause_i),
+
+ // 0x14000000 - 0x14FFFFFF
+`ifdef CONF_ALTSOC_BUS_ALT
+ .out4_addr_o(ext_alt_addr_o),
+ .out4_data_o(ext_alt_data_o),
+ .out4_data_i(ext_alt_data_i),
+ .out4_wr_o(ext_alt_wr_o),
+ .out4_rd_o(ext_alt_rd_o),
+ .out4_pause_i(ext_alt_pause_i)
+`else
+ .out4_addr_o(/*open*/),
+ .out4_data_o(/*open*/),
+ .out4_data_i(32'h00000000),
+ .out4_wr_o(/*open*/),
+ .out4_rd_o(/*open*/),
+ .out4_pause_i(1'b0)
+`endif
+);
+
+//-----------------------------------------------------------------
+// Peripheral Interconnect
+//-----------------------------------------------------------------
+soc_pif
+u2_soc
+(
+ // General - Clocking & Reset
+ .clk_i(clk_i),
+ .rst_i(rst_i),
+
+ // I/O bus (from mem_mux)
+ // 0x12000000 - 0x12FFFFFF
+ .io_addr_i(io_address),
+ .io_data_i(io_data_w),
+ .io_data_o(io_data_r),
+ .io_wr_i(io_wr),
+ .io_rd_i(io_rd),
+
+ // Peripherals
+ // UART = 0x12000000 - 0x120000FF
+ .periph0_addr_o(uart_addr),
+ .periph0_data_o(uart_data_o),
+ .periph0_data_i(uart_data_i),
+ .periph0_wr_o(uart_wr),
+ .periph0_rd_o(uart_rd),
+
+ // Timer = 0x12000100 - 0x120001FF
+ .periph1_addr_o(timer_addr),
+ .periph1_data_o(timer_data_o),
+ .periph1_data_i(timer_data_i),
+ .periph1_wr_o(timer_wr),
+ .periph1_rd_o(timer_rd),
+
+ // Interrupt Controller = 0x12000200 - 0x120002FF
+ .periph2_addr_o(intr_addr),
+ .periph2_data_o(intr_data_o),
+ .periph2_data_i(intr_data_i),
+ .periph2_wr_o(intr_wr),
+ .periph2_rd_o(intr_rd),
+
+ // SPI Flash = 0x12000300 - 0x120003FF
+ .periph3_addr_o(spi_addr),
+ .periph3_data_o(spi_data_o),
+ .periph3_data_i(spi_data_i),
+ .periph3_wr_o(spi_wr),
+ .periph3_rd_o(spi_rd),
+
+ // Unused = 0x12000400 - 0x120004FF
+ .periph4_addr_o(/*open*/),
+ .periph4_data_o(/*open*/),
+ .periph4_data_i(32'h00000000),
+ .periph4_wr_o(/*open*/),
+ .periph4_rd_o(/*open*/),
+
+ // Unused = 0x12000500 - 0x120005FF
+ .periph5_addr_o(/*open*/),
+ .periph5_data_o(/*open*/),
+ .periph5_data_i(32'h00000000),
+ .periph5_wr_o(/*open*/),
+ .periph5_rd_o(/*open*/),
+
+ // Unused = 0x12000600 - 0x120006FF
+ .periph6_addr_o(/*open*/),
+ .periph6_data_o(/*open*/),
+ .periph6_data_i(32'h00000000),
+ .periph6_wr_o(/*open*/),
+ .periph6_rd_o(/*open*/),
+
+ // Unused = 0x12000700 - 0x120007FF
+ .periph7_addr_o(/*open*/),
+ .periph7_data_o(/*open*/),
+ .periph7_data_i(32'h00000000),
+ .periph7_wr_o(/*open*/),
+ .periph7_rd_o(/*open*/)
+);
+
+//-----------------------------------------------------------------
+// UART
+//-----------------------------------------------------------------
+generate
+if (ENABLE_UART == "ENABLED")
+begin
+ // UART
+ uart_periph
+ #(
+ .UART_DIVISOR(((CLK_KHZ * 1000) / UART_BAUD))
+ )
+ u3_uart
+ (
+ .clk_i(clk_i),
+ .rst_i(rst_i),
+ .intr_o(uart_intr),
+ .addr_i(uart_addr),
+ .data_o(uart_data_i),
+ .data_i(uart_data_o),
+ .wr_i(uart_wr),
+ .rd_i(uart_rd),
+ .rx_i(uart_rx_i),
+ .tx_o(uart_tx_o)
+ );
+
+ // Debug UART
+ assign dbg_uart_data_o = uart_data_o[7:0];
+ assign dbg_uart_wr_o = (uart_wr != 4'b0000) ? 1'b1 : 1'b0;
+end
+else
+begin
+ // UART Disabled
+ assign uart_tx_o = 1'b1;
+ assign dbg_uart_data_o = 8'h00;
+ assign dbg_uart_wr_o = 1'b0;
+ assign uart_data_i = 32'h00000000;
+end
+endgenerate
+
+//-----------------------------------------------------------------
+// SPI Flash Master
+//-----------------------------------------------------------------
+generate
+if (ENABLE_SPI_FLASH == "ENABLED")
+begin
+ // SPI Flash Master
+ spim_periph
+ #(
+ .CLK_DIV(CLK_KHZ / SPI_FLASH_CLK_KHZ)
+ )
+ u4_spi_flash
+ (
+ // Clocking / Reset
+ .clk_i(clk_i),
+ .rst_i(rst_i),
+ .intr_o(/*open*/),
+ // Peripheral I/O
+ .addr_i(spi_addr),
+ .data_o(spi_data_i),
+ .data_i(spi_data_o),
+ .wr_i(spi_wr),
+ .rd_i(spi_rd),
+ // SPI interface
+ .spi_clk_o(flash_sck_o),
+ .spi_ss_o(flash_cs_o),
+ .spi_mosi_o(flash_si_o),
+ .spi_miso_i(flash_so_i)
+ );
+end
+else
+begin
+ // SPI Flash Disabled
+ assign flash_cs_o = 1'b1;
+ assign flash_si_o = 1'b0;
+ assign flash_sck_o = 1'b0;
+ assign spi_data_i = 32'h00000000;
+end
+endgenerate
+
+//-----------------------------------------------------------------
+// Timer
+//-----------------------------------------------------------------
+timer_periph
+#(
+ .CLK_KHZ(CLK_KHZ),
+ .SYSTICK_INTR_MS(SYSTICK_INTR_MS),
+ .ENABLE_SYSTICK_TIMER(ENABLE_SYSTICK_TIMER),
+ .ENABLE_HIGHRES_TIMER(ENABLE_HIGHRES_TIMER)
+)
+u5_timer
+(
+ .clk_i(clk_i),
+ .rst_i(rst_i),
+ .intr_systick_o(timer_intr_systick),
+ .intr_hires_o(timer_intr_hires),
+ .addr_i(timer_addr),
+ .data_o(timer_data_i),
+ .data_i(timer_data_o),
+ .wr_i(timer_wr),
+ .rd_i(timer_rd)
+);
+
+//-----------------------------------------------------------------
+// Interrupt Controller
+//-----------------------------------------------------------------
+intr_periph
+#(
+ .EXTERNAL_INTERRUPTS(EXTERNAL_INTERRUPTS)
+)
+u6_intr
+(
+ .clk_i(clk_i),
+ .rst_i(rst_i),
+ .intr_o(intr_in),
+
+ .intr0_i(uart_intr),
+ .intr1_i(timer_intr_systick),
+ .intr2_i(timer_intr_hires),
+ .intr3_i(1'b0),
+ .intr4_i(1'b0),
+ .intr5_i(1'b0),
+ .intr6_i(1'b0),
+ .intr7_i(1'b0),
+ .intr_ext_i(ext_intr_i),
+
+ .addr_i(intr_addr),
+ .data_o(intr_data_i),
+ .data_i(intr_data_o),
+ .wr_i(intr_wr),
+ .rd_i(intr_rd)
+);
+
+endmodule
Index: soc/soc_pif.v
===================================================================
--- soc/soc_pif.v (nonexistent)
+++ soc/soc_pif.v (revision 9)
@@ -0,0 +1,695 @@
+//-----------------------------------------------------------------
+// MPX 32-bit Soft-Core Processor
+// V0.1
+// Ultra-Embedded.com
+// Copyright 2011 - 2012
+//
+// Email: admin@ultra-embedded.com
+//
+// License: LGPL
+//
+// If you would like a version with a different license for use
+// in commercial projects please contact the above email address
+// for more details.
+//-----------------------------------------------------------------
+//
+// Copyright (C) 2011 - 2012 Ultra-Embedded.com
+//
+// This source file may be used and distributed without
+// restriction provided that this copyright statement is not
+// removed from the file and that any derivative work contains
+// the original copyright notice and the associated disclaimer.
+//
+// This source file is free software; you can redistribute it
+// and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation;
+// either version 2.1 of the License, or (at your option) any
+// later version.
+//
+// This source is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied
+// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+// PURPOSE. See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General
+// Public License along with this source; if not, write to the
+// Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+// Boston, MA 02111-1307 USA
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+// Module:
+//-----------------------------------------------------------------
+module soc_pif
+(
+ // General - Clocking & Reset
+ clk_i,
+ rst_i,
+
+ // I/O bus
+ io_addr_i,
+ io_data_i,
+ io_data_o,
+ io_wr_i,
+ io_rd_i,
+
+ // Peripherals
+ periph0_addr_o,
+ periph0_data_o,
+ periph0_data_i,
+ periph0_wr_o,
+ periph0_rd_o,
+
+ periph1_addr_o,
+ periph1_data_o,
+ periph1_data_i,
+ periph1_wr_o,
+ periph1_rd_o,
+
+ periph2_addr_o,
+ periph2_data_o,
+ periph2_data_i,
+ periph2_wr_o,
+ periph2_rd_o,
+
+ periph3_addr_o,
+ periph3_data_o,
+ periph3_data_i,
+ periph3_wr_o,
+ periph3_rd_o,
+
+ periph4_addr_o,
+ periph4_data_o,
+ periph4_data_i,
+ periph4_wr_o,
+ periph4_rd_o,
+
+ periph5_addr_o,
+ periph5_data_o,
+ periph5_data_i,
+ periph5_wr_o,
+ periph5_rd_o,
+
+ periph6_addr_o,
+ periph6_data_o,
+ periph6_data_i,
+ periph6_wr_o,
+ periph6_rd_o,
+
+ periph7_addr_o,
+ periph7_data_o,
+ periph7_data_i,
+ periph7_wr_o,
+ periph7_rd_o
+);
+
+//-----------------------------------------------------------------
+// I/O
+//-----------------------------------------------------------------
+input clk_i /*verilator public*/;
+input rst_i /*verilator public*/;
+
+input [31:0] io_addr_i /*verilator public*/;
+output [31:0] io_data_o /*verilator public*/;
+input [31:0] io_data_i /*verilator public*/;
+input [3:0] io_wr_i /*verilator public*/;
+input io_rd_i /*verilator public*/;
+
+output [7:0] periph0_addr_o /*verilator public*/;
+output [31:0] periph0_data_o /*verilator public*/;
+input [31:0] periph0_data_i /*verilator public*/;
+output [3:0] periph0_wr_o /*verilator public*/;
+output periph0_rd_o /*verilator public*/;
+
+output [7:0] periph1_addr_o /*verilator public*/;
+output [31:0] periph1_data_o /*verilator public*/;
+input [31:0] periph1_data_i /*verilator public*/;
+output [3:0] periph1_wr_o /*verilator public*/;
+output periph1_rd_o /*verilator public*/;
+
+output [7:0] periph2_addr_o /*verilator public*/;
+output [31:0] periph2_data_o /*verilator public*/;
+input [31:0] periph2_data_i /*verilator public*/;
+output [3:0] periph2_wr_o /*verilator public*/;
+output periph2_rd_o /*verilator public*/;
+
+output [7:0] periph3_addr_o /*verilator public*/;
+output [31:0] periph3_data_o /*verilator public*/;
+input [31:0] periph3_data_i /*verilator public*/;
+output [3:0] periph3_wr_o /*verilator public*/;
+output periph3_rd_o /*verilator public*/;
+
+output [7:0] periph4_addr_o /*verilator public*/;
+output [31:0] periph4_data_o /*verilator public*/;
+input [31:0] periph4_data_i /*verilator public*/;
+output [3:0] periph4_wr_o /*verilator public*/;
+output periph4_rd_o /*verilator public*/;
+
+output [7:0] periph5_addr_o /*verilator public*/;
+output [31:0] periph5_data_o /*verilator public*/;
+input [31:0] periph5_data_i /*verilator public*/;
+output [3:0] periph5_wr_o /*verilator public*/;
+output periph5_rd_o /*verilator public*/;
+
+output [7:0] periph6_addr_o /*verilator public*/;
+output [31:0] periph6_data_o /*verilator public*/;
+input [31:0] periph6_data_i /*verilator public*/;
+output [3:0] periph6_wr_o /*verilator public*/;
+output periph6_rd_o /*verilator public*/;
+
+output [7:0] periph7_addr_o /*verilator public*/;
+output [31:0] periph7_data_o /*verilator public*/;
+input [31:0] periph7_data_i /*verilator public*/;
+output [3:0] periph7_wr_o /*verilator public*/;
+output periph7_rd_o /*verilator public*/;
+
+//-----------------------------------------------------------------
+// Registers
+//-----------------------------------------------------------------
+reg [3:0] r_mem_sel;
+
+reg [31:0] io_data_o;
+
+reg [7:0] periph0_addr_o;
+reg [31:0] periph0_data_o;
+reg [3:0] periph0_wr_o;
+reg periph0_rd_o;
+
+reg [7:0] periph1_addr_o;
+reg [31:0] periph1_data_o;
+reg [3:0] periph1_wr_o;
+reg periph1_rd_o;
+
+reg [7:0] periph2_addr_o;
+reg [31:0] periph2_data_o;
+reg [3:0] periph2_wr_o;
+reg periph2_rd_o;
+
+reg [7:0] periph3_addr_o;
+reg [31:0] periph3_data_o;
+reg [3:0] periph3_wr_o;
+reg periph3_rd_o;
+
+reg [7:0] periph4_addr_o;
+reg [31:0] periph4_data_o;
+reg [3:0] periph4_wr_o;
+reg periph4_rd_o;
+
+reg [7:0] periph5_addr_o;
+reg [31:0] periph5_data_o;
+reg [3:0] periph5_wr_o;
+reg periph5_rd_o;
+
+reg [7:0] periph6_addr_o;
+reg [31:0] periph6_data_o;
+reg [3:0] periph6_wr_o;
+reg periph6_rd_o;
+
+reg [7:0] periph7_addr_o;
+reg [31:0] periph7_data_o;
+reg [3:0] periph7_wr_o;
+reg periph7_rd_o;
+
+//-----------------------------------------------------------------
+// Memory Map
+//-----------------------------------------------------------------
+always @ (io_addr_i or io_wr_i or io_rd_i or io_data_i)
+begin
+ // Decode 4-bit peripheral select
+ case (io_addr_i[11:8])
+
+ // Peripheral 0
+ 4'h0 :
+ begin
+
+ periph0_addr_o = io_addr_i[7:0];
+ periph0_wr_o = io_wr_i;
+ periph0_rd_o = io_rd_i;
+ periph0_data_o = io_data_i;
+
+ periph1_addr_o = 8'h00;
+ periph1_wr_o = 4'b0000;
+ periph1_rd_o = 1'b0;
+ periph1_data_o = 32'h00000000;
+
+ periph2_addr_o = 8'h00;
+ periph2_wr_o = 4'b0000;
+ periph2_rd_o = 1'b0;
+ periph2_data_o = 32'h00000000;
+
+ periph3_addr_o = 8'h00;
+ periph3_wr_o = 4'b0000;
+ periph3_rd_o = 1'b0;
+ periph3_data_o = 32'h00000000;
+
+ periph4_addr_o = 8'h00;
+ periph4_wr_o = 4'b0000;
+ periph4_rd_o = 1'b0;
+ periph4_data_o = 32'h00000000;
+
+ periph5_addr_o = 8'h00;
+ periph5_wr_o = 4'b0000;
+ periph5_rd_o = 1'b0;
+ periph5_data_o = 32'h00000000;
+
+ periph6_addr_o = 8'h00;
+ periph6_wr_o = 4'b0000;
+ periph6_rd_o = 1'b0;
+ periph6_data_o = 32'h00000000;
+
+ periph7_addr_o = 8'h00;
+ periph7_wr_o = 4'b0000;
+ periph7_rd_o = 1'b0;
+ periph7_data_o = 32'h00000000;
+
+ end
+
+ // Peripheral 1
+ 4'h1 :
+ begin
+ periph0_addr_o = 8'h00;
+ periph0_wr_o = 4'b0000;
+ periph0_rd_o = 1'b0;
+ periph0_data_o = 32'h00000000;
+
+ periph1_addr_o = io_addr_i[7:0];
+ periph1_wr_o = io_wr_i;
+ periph1_rd_o = io_rd_i;
+ periph1_data_o = io_data_i;
+
+ periph2_addr_o = 8'h00;
+ periph2_wr_o = 4'b0000;
+ periph2_rd_o = 1'b0;
+ periph2_data_o = 32'h00000000;
+
+ periph3_addr_o = 8'h00;
+ periph3_wr_o = 4'b0000;
+ periph3_rd_o = 1'b0;
+ periph3_data_o = 32'h00000000;
+
+ periph4_addr_o = 8'h00;
+ periph4_wr_o = 4'b0000;
+ periph4_rd_o = 1'b0;
+ periph4_data_o = 32'h00000000;
+
+ periph5_addr_o = 8'h00;
+ periph5_wr_o = 4'b0000;
+ periph5_rd_o = 1'b0;
+ periph5_data_o = 32'h00000000;
+
+ periph6_addr_o = 8'h00;
+ periph6_wr_o = 4'b0000;
+ periph6_rd_o = 1'b0;
+ periph6_data_o = 32'h00000000;
+
+ periph7_addr_o = 8'h00;
+ periph7_wr_o = 4'b0000;
+ periph7_rd_o = 1'b0;
+ periph7_data_o = 32'h00000000;
+ end
+
+ // Peripheral 2
+ 4'h2 :
+ begin
+ periph0_addr_o = 8'h00;
+ periph0_wr_o = 4'b0000;
+ periph0_rd_o = 1'b0;
+ periph0_data_o = 32'h00000000;
+
+ periph1_addr_o = 8'h00;
+ periph1_wr_o = 4'b0000;
+ periph1_rd_o = 1'b0;
+ periph1_data_o = 32'h00000000;
+
+ periph2_addr_o = io_addr_i[7:0];
+ periph2_wr_o = io_wr_i;
+ periph2_rd_o = io_rd_i;
+ periph2_data_o = io_data_i;
+
+ periph3_addr_o = 8'h00;
+ periph3_wr_o = 4'b0000;
+ periph3_rd_o = 1'b0;
+ periph3_data_o = 32'h00000000;
+
+ periph4_addr_o = 8'h00;
+ periph4_wr_o = 4'b0000;
+ periph4_rd_o = 1'b0;
+ periph4_data_o = 32'h00000000;
+
+ periph5_addr_o = 8'h00;
+ periph5_wr_o = 4'b0000;
+ periph5_rd_o = 1'b0;
+ periph5_data_o = 32'h00000000;
+
+ periph6_addr_o = 8'h00;
+ periph6_wr_o = 4'b0000;
+ periph6_rd_o = 1'b0;
+ periph6_data_o = 32'h00000000;
+
+ periph7_addr_o = 8'h00;
+ periph7_wr_o = 4'b0000;
+ periph7_rd_o = 1'b0;
+ periph7_data_o = 32'h00000000;
+ end
+
+ // Peripheral 3
+ 4'h3 :
+ begin
+ periph0_addr_o = 8'h00;
+ periph0_wr_o = 4'b0000;
+ periph0_rd_o = 1'b0;
+ periph0_data_o = 32'h00000000;
+
+ periph1_addr_o = 8'h00;
+ periph1_wr_o = 4'b0000;
+ periph1_rd_o = 1'b0;
+ periph1_data_o = 32'h00000000;
+
+ periph2_addr_o = 8'h00;
+ periph2_wr_o = 4'b0000;
+ periph2_rd_o = 1'b0;
+ periph2_data_o = 32'h00000000;
+
+ periph3_addr_o = io_addr_i[7:0];
+ periph3_wr_o = io_wr_i;
+ periph3_rd_o = io_rd_i;
+ periph3_data_o = io_data_i;
+
+ periph4_addr_o = 8'h00;
+ periph4_wr_o = 4'b0000;
+ periph4_rd_o = 1'b0;
+ periph4_data_o = 32'h00000000;
+
+ periph5_addr_o = 8'h00;
+ periph5_wr_o = 4'b0000;
+ periph5_rd_o = 1'b0;
+ periph5_data_o = 32'h00000000;
+
+ periph6_addr_o = 8'h00;
+ periph6_wr_o = 4'b0000;
+ periph6_rd_o = 1'b0;
+ periph6_data_o = 32'h00000000;
+
+ periph7_addr_o = 8'h00;
+ periph7_wr_o = 4'b0000;
+ periph7_rd_o = 1'b0;
+ periph7_data_o = 32'h00000000;
+ end
+
+ // Peripheral 4
+ 4'h4 :
+ begin
+ periph0_addr_o = 8'h00;
+ periph0_wr_o = 4'b0000;
+ periph0_rd_o = 1'b0;
+ periph0_data_o = 32'h00000000;
+
+ periph1_addr_o = 8'h00;
+ periph1_wr_o = 4'b0000;
+ periph1_rd_o = 1'b0;
+ periph1_data_o = 32'h00000000;
+
+ periph2_addr_o = 8'h00;
+ periph2_wr_o = 4'b0000;
+ periph2_rd_o = 1'b0;
+ periph2_data_o = 32'h00000000;
+
+ periph3_addr_o = 8'h00;
+ periph3_wr_o = 4'b0000;
+ periph3_rd_o = 1'b0;
+ periph3_data_o = 32'h00000000;
+
+ periph4_addr_o = io_addr_i[7:0];
+ periph4_wr_o = io_wr_i;
+ periph4_rd_o = io_rd_i;
+ periph4_data_o = io_data_i;
+
+ periph5_addr_o = 8'h00;
+ periph5_wr_o = 4'b0000;
+ periph5_rd_o = 1'b0;
+ periph5_data_o = 32'h00000000;
+
+ periph6_addr_o = 8'h00;
+ periph6_wr_o = 4'b0000;
+ periph6_rd_o = 1'b0;
+ periph6_data_o = 32'h00000000;
+
+ periph7_addr_o = 8'h00;
+ periph7_wr_o = 4'b0000;
+ periph7_rd_o = 1'b0;
+ periph7_data_o = 32'h00000000;
+ end
+
+ // Peripheral 5
+ 4'h5 :
+ begin
+ periph0_addr_o = 8'h00;
+ periph0_wr_o = 4'b0000;
+ periph0_rd_o = 1'b0;
+ periph0_data_o = 32'h00000000;
+
+ periph1_addr_o = 8'h00;
+ periph1_wr_o = 4'b0000;
+ periph1_rd_o = 1'b0;
+ periph1_data_o = 32'h00000000;
+
+ periph2_addr_o = 8'h00;
+ periph2_wr_o = 4'b0000;
+ periph2_rd_o = 1'b0;
+ periph2_data_o = 32'h00000000;
+
+ periph3_addr_o = 8'h00;
+ periph3_wr_o = 4'b0000;
+ periph3_rd_o = 1'b0;
+ periph3_data_o = 32'h00000000;
+
+ periph4_addr_o = 8'h00;
+ periph4_wr_o = 4'b0000;
+ periph4_rd_o = 1'b0;
+ periph4_data_o = 32'h00000000;
+
+ periph5_addr_o = io_addr_i[7:0];
+ periph5_wr_o = io_wr_i;
+ periph5_rd_o = io_rd_i;
+ periph5_data_o = io_data_i;
+
+ periph6_addr_o = 8'h00;
+ periph6_wr_o = 4'b0000;
+ periph6_rd_o = 1'b0;
+ periph6_data_o = 32'h00000000;
+
+ periph7_addr_o = 8'h00;
+ periph7_wr_o = 4'b0000;
+ periph7_rd_o = 1'b0;
+ periph7_data_o = 32'h00000000;
+ end
+
+ // Peripheral 6
+ 4'h6 :
+ begin
+ periph0_addr_o = 8'h00;
+ periph0_wr_o = 4'b0000;
+ periph0_rd_o = 1'b0;
+ periph0_data_o = 32'h00000000;
+
+ periph1_addr_o = 8'h00;
+ periph1_wr_o = 4'b0000;
+ periph1_rd_o = 1'b0;
+ periph1_data_o = 32'h00000000;
+
+ periph2_addr_o = 8'h00;
+ periph2_wr_o = 4'b0000;
+ periph2_rd_o = 1'b0;
+ periph2_data_o = 32'h00000000;
+
+ periph3_addr_o = 8'h00;
+ periph3_wr_o = 4'b0000;
+ periph3_rd_o = 1'b0;
+ periph3_data_o = 32'h00000000;
+
+ periph4_addr_o = 8'h00;
+ periph4_wr_o = 4'b0000;
+ periph4_rd_o = 1'b0;
+ periph4_data_o = 32'h00000000;
+
+ periph5_addr_o = 8'h00;
+ periph5_wr_o = 4'b0000;
+ periph5_rd_o = 1'b0;
+ periph5_data_o = 32'h00000000;
+
+ periph6_addr_o = io_addr_i[7:0];
+ periph6_wr_o = io_wr_i;
+ periph6_rd_o = io_rd_i;
+ periph6_data_o = io_data_i;
+
+ periph7_addr_o = 8'h00;
+ periph7_wr_o = 4'b0000;
+ periph7_rd_o = 1'b0;
+ periph7_data_o = 32'h00000000;
+ end
+
+ // Peripheral 7
+ 4'h7 :
+ begin
+ periph0_addr_o = 8'h00;
+ periph0_wr_o = 4'b0000;
+ periph0_rd_o = 1'b0;
+ periph0_data_o = 32'h00000000;
+
+ periph1_addr_o = 8'h00;
+ periph1_wr_o = 4'b0000;
+ periph1_rd_o = 1'b0;
+ periph1_data_o = 32'h00000000;
+
+ periph2_addr_o = 8'h00;
+ periph2_wr_o = 4'b0000;
+ periph2_rd_o = 1'b0;
+ periph2_data_o = 32'h00000000;
+
+ periph3_addr_o = 8'h00;
+ periph3_wr_o = 4'b0000;
+ periph3_rd_o = 1'b0;
+ periph3_data_o = 32'h00000000;
+
+ periph4_addr_o = 8'h00;
+ periph4_wr_o = 4'b0000;
+ periph4_rd_o = 1'b0;
+ periph4_data_o = 32'h00000000;
+
+ periph5_addr_o = 8'h00;
+ periph5_wr_o = 4'b0000;
+ periph5_rd_o = 1'b0;
+ periph5_data_o = 32'h00000000;
+
+ periph6_addr_o = 8'h00;
+ periph6_wr_o = 4'b0000;
+ periph6_rd_o = 1'b0;
+ periph6_data_o = 32'h00000000;
+
+ periph7_addr_o = io_addr_i[7:0];
+ periph7_wr_o = io_wr_i;
+ periph7_rd_o = io_rd_i;
+ periph7_data_o = io_data_i;
+ end
+
+ default :
+ begin
+ periph0_addr_o = 8'h00;
+ periph0_wr_o = 4'b0000;
+ periph0_rd_o = 1'b0;
+ periph0_data_o = 32'h00000000;
+
+ periph1_addr_o = 8'h00;
+ periph1_wr_o = 4'b0000;
+ periph1_rd_o = 1'b0;
+ periph1_data_o = 32'h00000000;
+
+ periph2_addr_o = 8'h00;
+ periph2_wr_o = 4'b0000;
+ periph2_rd_o = 1'b0;
+ periph2_data_o = 32'h00000000;
+
+ periph3_addr_o = 8'h00;
+ periph3_wr_o = 4'b0000;
+ periph3_rd_o = 1'b0;
+ periph3_data_o = 32'h00000000;
+
+ periph4_addr_o = 8'h00;
+ periph4_wr_o = 4'b0000;
+ periph4_rd_o = 1'b0;
+ periph4_data_o = 32'h00000000;
+
+ periph5_addr_o = 8'h00;
+ periph5_wr_o = 4'b0000;
+ periph5_rd_o = 1'b0;
+ periph5_data_o = 32'h00000000;
+
+ periph6_addr_o = 8'h00;
+ periph6_wr_o = 4'b0000;
+ periph6_rd_o = 1'b0;
+ periph6_data_o = 32'h00000000;
+
+ periph7_addr_o = 8'h00;
+ periph7_wr_o = 4'b0000;
+ periph7_rd_o = 1'b0;
+ periph7_data_o = 32'h00000000;
+ end
+ endcase
+end
+
+//-----------------------------------------------------------------
+// Read Port
+//-----------------------------------------------------------------
+always @ (r_mem_sel or periph0_data_i or periph1_data_i or periph2_data_i or
+ periph3_data_i or periph4_data_i or periph5_data_i or periph6_data_i or periph7_data_i)
+begin
+ case (r_mem_sel)
+
+ // Peripheral 0
+ 4'h0 :
+ begin
+ io_data_o = periph0_data_i;
+ end
+
+ // Peripheral 1
+ 4'h1 :
+ begin
+ io_data_o = periph1_data_i;
+ end
+
+ // Peripheral 2
+ 4'h2 :
+ begin
+ io_data_o = periph2_data_i;
+ end
+
+ // Peripheral 3
+ 4'h3 :
+ begin
+ io_data_o = periph3_data_i;
+ end
+
+ // Peripheral 4
+ 4'h4 :
+ begin
+ io_data_o = periph4_data_i;
+ end
+
+ // Peripheral 5
+ 4'h5 :
+ begin
+ io_data_o = periph5_data_i;
+ end
+
+ // Peripheral 6
+ 4'h6 :
+ begin
+ io_data_o = periph6_data_i;
+ end
+
+ // Peripheral 7
+ 4'h7 :
+ begin
+ io_data_o = periph7_data_i;
+ end
+
+ default :
+ begin
+ io_data_o = 32'h00000000;
+ end
+ endcase
+end
+
+//-----------------------------------------------------------------
+// Registered peripheral select
+//-----------------------------------------------------------------
+always @ (posedge clk_i or posedge rst_i)
+begin
+ if (rst_i == 1'b1)
+ r_mem_sel <= 4'h0;
+ else
+ r_mem_sel <= io_addr_i[11:8];
+end
+
+endmodule
Index: soc/mem_mux.v
===================================================================
--- soc/mem_mux.v (nonexistent)
+++ soc/mem_mux.v (revision 9)
@@ -0,0 +1,415 @@
+//-----------------------------------------------------------------
+// MPX 32-bit Soft-Core Processor
+// V0.1
+// Ultra-Embedded.com
+// Copyright 2011 - 2012
+//
+// Email: admin@ultra-embedded.com
+//
+// License: LGPL
+//
+// If you would like a version with a different license for use
+// in commercial projects please contact the above email address
+// for more details.
+//-----------------------------------------------------------------
+//
+// Copyright (C) 2011 - 2012 Ultra-Embedded.com
+//
+// This source file may be used and distributed without
+// restriction provided that this copyright statement is not
+// removed from the file and that any derivative work contains
+// the original copyright notice and the associated disclaimer.
+//
+// This source file is free software; you can redistribute it
+// and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation;
+// either version 2.1 of the License, or (at your option) any
+// later version.
+//
+// This source is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied
+// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+// PURPOSE. See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General
+// Public License along with this source; if not, write to the
+// Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+// Boston, MA 02111-1307 USA
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+// Module:
+//-----------------------------------------------------------------
+module mem_mux
+(
+ // General
+ clk_i,
+ rst_i,
+
+ // Input
+ mem_addr_i,
+ mem_data_i,
+ mem_data_o,
+ mem_wr_i,
+ mem_rd_i,
+ mem_pause_o,
+
+ // Outputs
+ out0_addr_o,
+ out0_data_o,
+ out0_data_i,
+ out0_wr_o,
+ out0_rd_o,
+ out0_pause_i,
+
+ out1_addr_o,
+ out1_data_o,
+ out1_data_i,
+ out1_wr_o,
+ out1_rd_o,
+ out1_pause_i,
+
+ out2_addr_o,
+ out2_data_o,
+ out2_data_i,
+ out2_wr_o,
+ out2_rd_o,
+ out2_pause_i,
+
+ out3_addr_o,
+ out3_data_o,
+ out3_data_i,
+ out3_wr_o,
+ out3_rd_o,
+ out3_pause_i,
+
+ out4_addr_o,
+ out4_data_o,
+ out4_data_i,
+ out4_wr_o,
+ out4_rd_o,
+ out4_pause_i
+);
+
+//-----------------------------------------------------------------
+// Params
+//-----------------------------------------------------------------
+parameter BOOT_VECTOR = 0;
+parameter ADDR_MUX_START = 28;
+
+//-----------------------------------------------------------------
+// I/O
+//-----------------------------------------------------------------
+input clk_i /*verilator public*/;
+input rst_i /*verilator public*/;
+input [31:0] mem_addr_i /*verilator public*/;
+input [31:0] mem_data_i /*verilator public*/;
+output [31:0] mem_data_o /*verilator public*/;
+input [3:0] mem_wr_i /*verilator public*/;
+input mem_rd_i /*verilator public*/;
+output mem_pause_o /*verilator public*/;
+output [31:0] out0_addr_o /*verilator public*/;
+output [31:0] out0_data_o /*verilator public*/;
+input [31:0] out0_data_i /*verilator public*/;
+output [3:0] out0_wr_o /*verilator public*/;
+output out0_rd_o /*verilator public*/;
+input out0_pause_i /*verilator public*/;
+output [31:0] out1_addr_o /*verilator public*/;
+output [31:0] out1_data_o /*verilator public*/;
+input [31:0] out1_data_i /*verilator public*/;
+output [3:0] out1_wr_o /*verilator public*/;
+output out1_rd_o /*verilator public*/;
+input out1_pause_i /*verilator public*/;
+output [31:0] out2_addr_o /*verilator public*/;
+output [31:0] out2_data_o /*verilator public*/;
+input [31:0] out2_data_i /*verilator public*/;
+output [3:0] out2_wr_o /*verilator public*/;
+output out2_rd_o /*verilator public*/;
+input out2_pause_i /*verilator public*/;
+output [31:0] out3_addr_o /*verilator public*/;
+output [31:0] out3_data_o /*verilator public*/;
+input [31:0] out3_data_i /*verilator public*/;
+output [3:0] out3_wr_o /*verilator public*/;
+output out3_rd_o /*verilator public*/;
+input out3_pause_i /*verilator public*/;
+output [31:0] out4_addr_o /*verilator public*/;
+output [31:0] out4_data_o /*verilator public*/;
+input [31:0] out4_data_i /*verilator public*/;
+output [3:0] out4_wr_o /*verilator public*/;
+output out4_rd_o /*verilator public*/;
+input out4_pause_i /*verilator public*/;
+
+//-----------------------------------------------------------------
+// Registers
+//-----------------------------------------------------------------
+reg [2:0] r_mem_sel;
+
+// Output Signals
+reg mem_pause_o;
+reg [31:0] mem_data_o;
+reg [31:0] out0_addr_o;
+reg [31:0] out0_data_o;
+reg [3:0] out0_wr_o;
+reg out0_rd_o;
+reg [31:0] out1_addr_o;
+reg [31:0] out1_data_o;
+reg [3:0] out1_wr_o;
+reg out1_rd_o;
+reg [31:0] out2_addr_o;
+reg [31:0] out2_data_o;
+reg [3:0] out2_wr_o;
+reg out2_rd_o;
+reg [31:0] out3_addr_o;
+reg [31:0] out3_data_o;
+reg [3:0] out3_wr_o;
+reg out3_rd_o;
+reg [31:0] out4_addr_o;
+reg [31:0] out4_data_o;
+reg [3:0] out4_wr_o;
+reg out4_rd_o;
+
+//-----------------------------------------------------------------
+// Memory Map
+//-----------------------------------------------------------------
+always @ (mem_addr_i or mem_wr_i or mem_rd_i or mem_data_i )
+begin
+ case (mem_addr_i[ADDR_MUX_START+2:ADDR_MUX_START])
+
+ 3'b000 :
+ begin
+ out0_addr_o = mem_addr_i;
+ out0_wr_o = mem_wr_i;
+ out0_rd_o = mem_rd_i;
+ out0_data_o = mem_data_i;
+
+ out1_addr_o = 32'h00000000;
+ out1_wr_o = 4'b0000;
+ out1_rd_o = 1'b0;
+ out1_data_o = 32'h00000000;
+
+ out2_addr_o = 32'h00000000;
+ out2_wr_o = 4'b0000;
+ out2_rd_o = 1'b0;
+ out2_data_o = 32'h00000000;
+
+ out3_addr_o = 32'h00000000;
+ out3_wr_o = 4'b0000;
+ out3_rd_o = 1'b0;
+ out3_data_o = 32'h00000000;
+
+ out4_addr_o = 32'h00000000;
+ out4_wr_o = 4'b0000;
+ out4_rd_o = 1'b0;
+ out4_data_o = 32'h00000000;
+ end
+
+ 3'b001 :
+ begin
+ out0_addr_o = 32'h00000000;
+ out0_wr_o = 4'b0000;
+ out0_rd_o = 1'b0;
+ out0_data_o = 32'h00000000;
+
+ out1_addr_o = mem_addr_i;
+ out1_wr_o = mem_wr_i;
+ out1_rd_o = mem_rd_i;
+ out1_data_o = mem_data_i;
+
+ out2_addr_o = 32'h00000000;
+ out2_wr_o = 4'b0000;
+ out2_rd_o = 1'b0;
+ out2_data_o = 32'h00000000;
+
+ out3_addr_o = 32'h00000000;
+ out3_wr_o = 4'b0000;
+ out3_rd_o = 1'b0;
+ out3_data_o = 32'h00000000;
+
+ out4_addr_o = 32'h00000000;
+ out4_wr_o = 4'b0000;
+ out4_rd_o = 1'b0;
+ out4_data_o = 32'h00000000;
+ end
+
+ 3'b010 :
+ begin
+ out0_addr_o = 32'h00000000;
+ out0_wr_o = 4'b0000;
+ out0_rd_o = 1'b0;
+ out0_data_o = 32'h00000000;
+
+ out1_addr_o = 32'h00000000;
+ out1_wr_o = 4'b0000;
+ out1_rd_o = 1'b0;
+ out1_data_o = 32'h00000000;
+
+ out2_addr_o = mem_addr_i;
+ out2_wr_o = mem_wr_i;
+ out2_rd_o = mem_rd_i;
+ out2_data_o = mem_data_i;
+
+ out3_addr_o = 32'h00000000;
+ out3_wr_o = 4'b0000;
+ out3_rd_o = 1'b0;
+ out3_data_o = 32'h00000000;
+
+ out4_addr_o = 32'h00000000;
+ out4_wr_o = 4'b0000;
+ out4_rd_o = 1'b0;
+ out4_data_o = 32'h00000000;
+ end
+
+ 3'b011 :
+ begin
+ out0_addr_o = 32'h00000000;
+ out0_wr_o = 4'b0000;
+ out0_rd_o = 1'b0;
+ out0_data_o = 32'h00000000;
+
+ out1_addr_o = 32'h00000000;
+ out1_wr_o = 4'b0000;
+ out1_rd_o = 1'b0;
+ out1_data_o = 32'h00000000;
+
+ out2_addr_o = 32'h00000000;
+ out2_wr_o = 4'b0000;
+ out2_rd_o = 1'b0;
+ out2_data_o = 32'h00000000;
+
+ out3_addr_o = mem_addr_i;
+ out3_wr_o = mem_wr_i;
+ out3_rd_o = mem_rd_i;
+ out3_data_o = mem_data_i;
+
+ out4_addr_o = 32'h00000000;
+ out4_wr_o = 4'b0000;
+ out4_rd_o = 1'b0;
+ out4_data_o = 32'h00000000;
+ end
+
+ 3'b100 :
+ begin
+ out0_addr_o = 32'h00000000;
+ out0_wr_o = 4'b0000;
+ out0_rd_o = 1'b0;
+ out0_data_o = 32'h00000000;
+
+ out1_addr_o = 32'h00000000;
+ out1_wr_o = 4'b0000;
+ out1_rd_o = 1'b0;
+ out1_data_o = 32'h00000000;
+
+ out2_addr_o = 32'h00000000;
+ out2_wr_o = 4'b0000;
+ out2_rd_o = 1'b0;
+ out2_data_o = 32'h00000000;
+
+ out3_addr_o = 32'h00000000;
+ out3_wr_o = 4'b0000;
+ out3_rd_o = 1'b0;
+ out3_data_o = 32'h00000000;
+
+ out4_addr_o = mem_addr_i;
+ out4_wr_o = mem_wr_i;
+ out4_rd_o = mem_rd_i;
+ out4_data_o = mem_data_i;
+ end
+
+ default :
+ begin
+ out0_addr_o = 32'h00000000;
+ out0_wr_o = 4'b0000;
+ out0_rd_o = 1'b0;
+ out0_data_o = 32'h00000000;
+
+ out1_addr_o = 32'h00000000;
+ out1_wr_o = 4'b0000;
+ out1_rd_o = 1'b0;
+ out1_data_o = 32'h00000000;
+
+ out2_addr_o = 32'h00000000;
+ out2_wr_o = 4'b0000;
+ out2_rd_o = 1'b0;
+ out2_data_o = 32'h00000000;
+
+ out3_addr_o = 32'h00000000;
+ out3_wr_o = 4'b0000;
+ out3_rd_o = 1'b0;
+ out3_data_o = 32'h00000000;
+
+ out4_addr_o = 32'h00000000;
+ out4_wr_o = 4'b0000;
+ out4_rd_o = 1'b0;
+ out4_data_o = 32'h00000000;
+ end
+ endcase
+end
+
+//-----------------------------------------------------------------
+// Read Port
+//-----------------------------------------------------------------
+always @ ( r_mem_sel or
+ out0_data_i or out0_pause_i or
+ out1_data_i or out1_pause_i or
+ out2_data_i or out2_pause_i or
+ out3_data_i or out3_pause_i or
+ out4_data_i or out4_pause_i )
+begin
+ case (r_mem_sel)
+
+ 3'b000 :
+ begin
+ mem_data_o = out0_data_i;
+ mem_pause_o = out0_pause_i;
+ end
+
+ 3'b001 :
+ begin
+ mem_data_o = out1_data_i;
+ mem_pause_o = out1_pause_i;
+ end
+
+ 3'b010 :
+ begin
+ mem_data_o = out2_data_i;
+ mem_pause_o = out2_pause_i;
+ end
+
+ 3'b011 :
+ begin
+ mem_data_o = out3_data_i;
+ mem_pause_o = out3_pause_i;
+ end
+
+ 3'b100 :
+ begin
+ mem_data_o = out4_data_i;
+ mem_pause_o = out4_pause_i;
+ end
+
+ default :
+ begin
+ mem_data_o = 32'h00000000;
+ mem_pause_o = 1'b0;
+ end
+ endcase
+end
+
+//-----------------------------------------------------------------
+// Registered device select
+//-----------------------------------------------------------------
+reg [31:0] v_mem_sel;
+
+always @ (posedge clk_i or posedge rst_i )
+begin
+ if (rst_i == 1'b1)
+ begin
+ v_mem_sel = BOOT_VECTOR;
+ r_mem_sel <= v_mem_sel[ADDR_MUX_START+2:ADDR_MUX_START];
+ end
+ else
+ r_mem_sel <= mem_addr_i[ADDR_MUX_START+2:ADDR_MUX_START];
+end
+
+endmodule
Index: peripheral/uart.v
===================================================================
--- peripheral/uart.v (nonexistent)
+++ peripheral/uart.v (revision 9)
@@ -0,0 +1,284 @@
+//-----------------------------------------------------------------
+// MPX 32-bit Soft-Core Processor
+// V0.1
+// Ultra-Embedded.com
+// Copyright 2011 - 2012
+//
+// Email: admin@ultra-embedded.com
+//
+// License: LGPL
+//
+// If you would like a version with a different license for use
+// in commercial projects please contact the above email address
+// for more details.
+//-----------------------------------------------------------------
+//
+// Copyright (C) 2011 - 2012 Ultra-Embedded.com
+//
+// This source file may be used and distributed without
+// restriction provided that this copyright statement is not
+// removed from the file and that any derivative work contains
+// the original copyright notice and the associated disclaimer.
+//
+// This source file is free software; you can redistribute it
+// and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation;
+// either version 2.1 of the License, or (at your option) any
+// later version.
+//
+// This source is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied
+// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+// PURPOSE. See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General
+// Public License along with this source; if not, write to the
+// Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+// Boston, MA 02111-1307 USA
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+// Module:
+//-----------------------------------------------------------------
+module uart
+(
+ // Clock & Reset
+ clk_i,
+ rst_i,
+ // Status
+ tx_busy_o,
+ rx_ready_o,
+ // Data
+ data_i,
+ wr_i,
+ data_o,
+ rd_i,
+ // UART pins
+ rxd_i,
+ txd_o
+);
+//-----------------------------------------------------------------
+// Params
+//-----------------------------------------------------------------
+parameter [31:0] UART_DIVISOR = 278;
+
+//-----------------------------------------------------------------
+// I/O
+//-----------------------------------------------------------------
+input clk_i /*verilator public*/;
+input rst_i /*verilator public*/;
+input [7:0] data_i /*verilator public*/;
+output [7:0] data_o /*verilator public*/;
+input wr_i /*verilator public*/;
+input rd_i /*verilator public*/;
+output tx_busy_o /*verilator public*/;
+output rx_ready_o /*verilator public*/;
+input rxd_i /*verilator public*/;
+output txd_o /*verilator public*/;
+
+//-----------------------------------------------------------------
+// Registers
+//-----------------------------------------------------------------
+parameter FULL_BIT = UART_DIVISOR;
+parameter HALF_BIT = (FULL_BIT / 2);
+
+// TX Signals
+reg [7:0] tx_buf;
+reg tx_buf_full;
+reg tx_busy;
+reg [3:0] tx_bits;
+integer tx_count;
+reg [7:0] tx_shift_reg;
+reg txd_o;
+
+// RX Signals
+reg i_rxd;
+reg [7:0] data_o;
+reg [3:0] rx_bits;
+integer rx_count;
+reg [7:0] rx_shift_reg;
+reg rx_ready_o;
+
+//-----------------------------------------------------------------
+// Re-sync RXD
+//-----------------------------------------------------------------
+always @ (posedge rst_i or posedge clk_i )
+begin
+ if (rst_i == 1'b1)
+ i_rxd <= 1'b1;
+ else
+ i_rxd <= rxd_i;
+end
+
+//-----------------------------------------------------------------
+// RX Process
+//-----------------------------------------------------------------
+always @ (posedge clk_i or posedge rst_i )
+begin
+ if (rst_i == 1'b1)
+ begin
+ rx_bits <= 0;
+ rx_count <= 0;
+ rx_ready_o <= 1'b0;
+ rx_shift_reg <= 8'h00;
+ data_o <= 8'h00;
+ end
+ else
+ begin
+
+ // If reading data, reset data ready state
+ if (rd_i == 1'b1)
+ rx_ready_o <= 1'b0;
+
+ // Rx bit timer
+ if (rx_count != 0)
+ rx_count <= (rx_count - 1);
+ else
+ begin
+ //-------------------------------
+ // Start bit detection
+ //-------------------------------
+ if (rx_bits == 0)
+ begin
+ // If RXD low, check again in half bit time
+ if (i_rxd == 1'b0)
+ begin
+ rx_count <= HALF_BIT;
+ rx_bits <= 1;
+ end
+ end
+ //-------------------------------
+ // Start bit (mid bit time point)
+ //-------------------------------
+ else if (rx_bits == 1)
+ begin
+ // RXD should still be low at mid point of bit period
+ if (i_rxd == 1'b0)
+ begin
+ rx_count <= FULL_BIT;
+ rx_bits <= rx_bits + 1'b1;
+ rx_shift_reg <= 8'h00;
+ end
+ // Start bit not still low, reset RX process
+ else
+ begin
+ rx_bits <= 0;
+ end
+ end
+ //-------------------------------
+ // Stop bit
+ //-------------------------------
+ else if (rx_bits == 10)
+ begin
+ // RXD should be still high
+ if (i_rxd == 1'b1)
+ begin
+ rx_count <= 0;
+ rx_bits <= 0;
+ data_o <= rx_shift_reg;
+ rx_ready_o <= 1'b1;
+ end
+ // Bad Stop bit - wait for a full bit period
+ // before allowing start bit detection again
+ else
+ begin
+ rx_count <= FULL_BIT;
+ rx_bits <= 0;
+ end
+ end
+ //-------------------------------
+ // Data bits
+ //-------------------------------
+ else
+ begin
+ // Receive data LSB first
+ rx_shift_reg[7] <= i_rxd;
+ rx_shift_reg[6:0]<= rx_shift_reg[7:1];
+ rx_count <= FULL_BIT;
+ rx_bits <= rx_bits + 1'b1;
+ end
+ end
+ end
+end
+
+//-----------------------------------------------------------------
+// TX Process
+//-----------------------------------------------------------------
+always @ (posedge clk_i or posedge rst_i )
+begin
+ if (rst_i == 1'b1)
+ begin
+ tx_count <= 0;
+ tx_bits <= 0;
+ tx_busy <= 1'b0;
+ txd_o <= 1'b1;
+ tx_shift_reg <= 8'h00;
+ tx_buf <= 8'h00;
+ tx_buf_full <= 1'b0;
+ end
+ else
+ begin
+
+ // Buffer data to transmit
+ if (wr_i == 1'b1)
+ begin
+ tx_buf <= data_i;
+ tx_buf_full <= 1'b1;
+ end
+
+ // Tx bit timer
+ if (tx_count != 0)
+ tx_count <= (tx_count - 1);
+ else
+ begin
+
+ //-------------------------------
+ // Start bit (TXD = L)
+ //-------------------------------
+ if (tx_bits == 0)
+ begin
+
+ tx_busy <= 1'b0;
+
+ // Data in buffer ready to transmit?
+ if (tx_buf_full == 1'b1)
+ begin
+ tx_shift_reg <= tx_buf;
+ tx_busy <= 1'b1;
+ txd_o <= 1'b0;
+ tx_buf_full <= 1'b0;
+ tx_bits <= 1;
+ tx_count <= FULL_BIT;
+ end
+ end
+ //-------------------------------
+ // Stop bit (TXD = H)
+ //-------------------------------
+ else if (tx_bits == 9)
+ begin
+ txd_o <= 1'b1;
+ tx_bits <= 0;
+ tx_count <= FULL_BIT;
+ end
+ //-------------------------------
+ // Data bits
+ //-------------------------------
+ else
+ begin
+ // Shift data out LSB first
+ txd_o <= tx_shift_reg[0];
+ tx_shift_reg[6:0]<= tx_shift_reg[7:1];
+ tx_bits <= tx_bits + 1'b1;
+ tx_count <= FULL_BIT;
+ end
+ end
+ end
+end
+
+//-----------------------------------------------------------------
+// Combinatorial
+//-----------------------------------------------------------------
+assign tx_busy_o = (tx_busy | tx_buf_full | wr_i);
+
+endmodule
Index: peripheral/uart_defs.v
===================================================================
--- peripheral/uart_defs.v (nonexistent)
+++ peripheral/uart_defs.v (revision 9)
@@ -0,0 +1,47 @@
+//-----------------------------------------------------------------
+// MPX 32-bit Soft-Core Processor
+// V0.1
+// Ultra-Embedded.com
+// Copyright 2011 - 2012
+//
+// Email: admin@ultra-embedded.com
+//
+// License: LGPL
+//
+// If you would like a version with a different license for use
+// in commercial projects please contact the above email address
+// for more details.
+//-----------------------------------------------------------------
+//
+// Copyright (C) 2011 - 2012 Ultra-Embedded.com
+//
+// This source file may be used and distributed without
+// restriction provided that this copyright statement is not
+// removed from the file and that any derivative work contains
+// the original copyright notice and the associated disclaimer.
+//
+// This source file is free software; you can redistribute it
+// and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation;
+// either version 2.1 of the License, or (at your option) any
+// later version.
+//
+// This source is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied
+// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+// PURPOSE. See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General
+// Public License along with this source; if not, write to the
+// Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+// Boston, MA 02111-1307 USA
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+// Registers
+//-----------------------------------------------------------------
+
+// Basic Peripherals
+`define UART_USR 8'h04
+`define UART_UDR 8'h08
Index: peripheral/intr_defs.v
===================================================================
--- peripheral/intr_defs.v (nonexistent)
+++ peripheral/intr_defs.v (revision 9)
@@ -0,0 +1,47 @@
+//-----------------------------------------------------------------
+// MPX 32-bit Soft-Core Processor
+// V0.1
+// Ultra-Embedded.com
+// Copyright 2011 - 2012
+//
+// Email: admin@ultra-embedded.com
+//
+// License: LGPL
+//
+// If you would like a version with a different license for use
+// in commercial projects please contact the above email address
+// for more details.
+//-----------------------------------------------------------------
+//
+// Copyright (C) 2011 - 2012 Ultra-Embedded.com
+//
+// This source file may be used and distributed without
+// restriction provided that this copyright statement is not
+// removed from the file and that any derivative work contains
+// the original copyright notice and the associated disclaimer.
+//
+// This source file is free software; you can redistribute it
+// and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation;
+// either version 2.1 of the License, or (at your option) any
+// later version.
+//
+// This source is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied
+// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+// PURPOSE. See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General
+// Public License along with this source; if not, write to the
+// Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+// Boston, MA 02111-1307 USA
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+// Registers
+//-----------------------------------------------------------------
+`define IRQ_MASK_SET 8'h00
+`define IRQ_MASK_CLR 8'h04
+`define IRQ_STATUS 8'h08
+ `define IRQ_EXT_FIRST (8)
Index: peripheral/gpio_defs.v
===================================================================
--- peripheral/gpio_defs.v (nonexistent)
+++ peripheral/gpio_defs.v (revision 9)
@@ -0,0 +1,49 @@
+//-----------------------------------------------------------------
+// MPX 32-bit Soft-Core Processor
+// V0.1
+// Ultra-Embedded.com
+// Copyright 2011 - 2012
+//
+// Email: admin@ultra-embedded.com
+//
+// License: LGPL
+//
+// If you would like a version with a different license for use
+// in commercial projects please contact the above email address
+// for more details.
+//-----------------------------------------------------------------
+//
+// Copyright (C) 2011 - 2012 Ultra-Embedded.com
+//
+// This source file may be used and distributed without
+// restriction provided that this copyright statement is not
+// removed from the file and that any derivative work contains
+// the original copyright notice and the associated disclaimer.
+//
+// This source file is free software; you can redistribute it
+// and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation;
+// either version 2.1 of the License, or (at your option) any
+// later version.
+//
+// This source is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied
+// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+// PURPOSE. See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General
+// Public License along with this source; if not, write to the
+// Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+// Boston, MA 02111-1307 USA
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+// Registers
+//-----------------------------------------------------------------
+`define GPIO_OUT 8'h00
+`define GPIO_IN 8'h04
+`define GPIO_DIR 8'h08
+`define GPIO_INT_MASK 8'h0C
+`define GPIO_INT_POLARITY 8'h10
+`define GPIO_INT_EDGE 8'h14
Index: peripheral/spim_periph.v
===================================================================
--- peripheral/spim_periph.v (nonexistent)
+++ peripheral/spim_periph.v (revision 9)
@@ -0,0 +1,202 @@
+//-----------------------------------------------------------------
+// MPX 32-bit Soft-Core Processor
+// V0.1
+// Ultra-Embedded.com
+// Copyright 2011 - 2012
+//
+// Email: admin@ultra-embedded.com
+//
+// License: LGPL
+//
+// If you would like a version with a different license for use
+// in commercial projects please contact the above email address
+// for more details.
+//-----------------------------------------------------------------
+//
+// Copyright (C) 2011 - 2012 Ultra-Embedded.com
+//
+// This source file may be used and distributed without
+// restriction provided that this copyright statement is not
+// removed from the file and that any derivative work contains
+// the original copyright notice and the associated disclaimer.
+//
+// This source file is free software; you can redistribute it
+// and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation;
+// either version 2.1 of the License, or (at your option) any
+// later version.
+//
+// This source is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied
+// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+// PURPOSE. See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General
+// Public License along with this source; if not, write to the
+// Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+// Boston, MA 02111-1307 USA
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+// Includes
+//-----------------------------------------------------------------
+`include "spim_defs.v"
+
+//-----------------------------------------------------------------
+// Module:
+//-----------------------------------------------------------------
+module spim_periph
+(
+ // General - Clocking & Reset
+ clk_i,
+ rst_i,
+ intr_o,
+
+ // SPI Bus
+ spi_clk_o,
+ spi_ss_o,
+ spi_mosi_o,
+ spi_miso_i,
+
+ // Peripheral bus
+ addr_i,
+ data_o,
+ data_i,
+ wr_i,
+ rd_i
+);
+
+//-----------------------------------------------------------------
+// Params
+//-----------------------------------------------------------------
+parameter [31:0] CLK_DIV = 32;
+
+//-----------------------------------------------------------------
+// I/O
+//-----------------------------------------------------------------
+input clk_i /*verilator public*/;
+input rst_i /*verilator public*/;
+output intr_o /*verilator public*/;
+
+output spi_clk_o /*verilator public*/;
+output spi_ss_o /*verilator public*/;
+output spi_mosi_o /*verilator public*/;
+input spi_miso_i /*verilator public*/;
+
+input [7:0] addr_i /*verilator public*/;
+output [31:0] data_o /*verilator public*/;
+input [31:0] data_i /*verilator public*/;
+input [3:0] wr_i /*verilator public*/;
+input rd_i /*verilator public*/;
+
+
+//-----------------------------------------------------------------
+// Registers / Wires
+//-----------------------------------------------------------------
+reg [31:0] data_o;
+reg spi_ss_o;
+reg spi_start;
+wire spi_busy;
+reg [7:0] spi_data_wr;
+wire [7:0] spi_data_rd;
+
+//-----------------------------------------------------------------
+// Instantiation
+//-----------------------------------------------------------------
+
+// SPI Master
+spi_master
+#(
+ .CLK_DIV(CLK_DIV),
+ .TRANSFER_WIDTH(8)
+)
+u1_spi_master
+(
+ // Clocking / Reset
+ .clk_i(clk_i),
+ .rst_i(rst_i),
+ // Control & Status
+ .start_i(spi_start),
+ .done_o(intr_o),
+ .busy_o(spi_busy),
+ // Data
+ .data_i(spi_data_wr),
+ .data_o(spi_data_rd),
+ // SPI interface
+ .spi_clk_o(spi_clk_o),
+ .spi_ss_o(/*open */),
+ .spi_mosi_o(spi_mosi_o),
+ .spi_miso_i(spi_miso_i)
+);
+
+//-----------------------------------------------------------------
+// Peripheral Register Write
+//-----------------------------------------------------------------
+always @ (posedge rst_i or posedge clk_i )
+begin
+ if (rst_i == 1'b1)
+ begin
+ spi_ss_o <= 1'b1;
+ spi_start <= 1'b0;
+ spi_data_wr <= 8'h00;
+ end
+ else
+ begin
+
+ spi_start <= 1'b0;
+
+ // Write Cycle
+ if (wr_i != 4'b0000)
+ begin
+ case (addr_i)
+
+ `SPI_MASTER_CTRL :
+ begin
+ spi_ss_o <= data_i[0];
+ end
+
+ `SPI_MASTER_DATA :
+ begin
+ spi_data_wr <= data_i[7:0];
+ spi_start <= 1'b1;
+ end
+
+ default :
+ ;
+ endcase
+ end
+ end
+end
+
+//-----------------------------------------------------------------
+// Peripheral Register Read
+//-----------------------------------------------------------------
+always @ (posedge rst_i or posedge clk_i )
+begin
+ if (rst_i == 1'b1)
+ begin
+ data_o <= 32'h00000000;
+ end
+ else
+ begin
+
+ // Read cycle?
+ if (rd_i == 1'b1)
+ begin
+ case (addr_i[7:0])
+
+ `SPI_MASTER_STAT :
+ data_o <= {31'h00000000, spi_busy};
+
+ `SPI_MASTER_DATA :
+ data_o <= {24'h000000, spi_data_rd};
+
+ default :
+ data_o <= 32'h00000000;
+ endcase
+ end
+ end
+end
+
+endmodule
Index: peripheral/timer_defs.v
===================================================================
--- peripheral/timer_defs.v (nonexistent)
+++ peripheral/timer_defs.v (revision 9)
@@ -0,0 +1,45 @@
+//-----------------------------------------------------------------
+// MPX 32-bit Soft-Core Processor
+// V0.1
+// Ultra-Embedded.com
+// Copyright 2011 - 2012
+//
+// Email: admin@ultra-embedded.com
+//
+// License: LGPL
+//
+// If you would like a version with a different license for use
+// in commercial projects please contact the above email address
+// for more details.
+//-----------------------------------------------------------------
+//
+// Copyright (C) 2011 - 2012 Ultra-Embedded.com
+//
+// This source file may be used and distributed without
+// restriction provided that this copyright statement is not
+// removed from the file and that any derivative work contains
+// the original copyright notice and the associated disclaimer.
+//
+// This source file is free software; you can redistribute it
+// and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation;
+// either version 2.1 of the License, or (at your option) any
+// later version.
+//
+// This source is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied
+// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+// PURPOSE. See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General
+// Public License along with this source; if not, write to the
+// Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+// Boston, MA 02111-1307 USA
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+// Registers
+//-----------------------------------------------------------------
+`define TIMER_SYSTICK_VAL 8'h00
+`define TIMER_HIRES 8'h04
Index: peripheral/uart_periph.v
===================================================================
--- peripheral/uart_periph.v (nonexistent)
+++ peripheral/uart_periph.v (revision 9)
@@ -0,0 +1,198 @@
+//-----------------------------------------------------------------
+// MPX 32-bit Soft-Core Processor
+// V0.1
+// Ultra-Embedded.com
+// Copyright 2011 - 2012
+//
+// Email: admin@ultra-embedded.com
+//
+// License: LGPL
+//
+// If you would like a version with a different license for use
+// in commercial projects please contact the above email address
+// for more details.
+//-----------------------------------------------------------------
+//
+// Copyright (C) 2011 - 2012 Ultra-Embedded.com
+//
+// This source file may be used and distributed without
+// restriction provided that this copyright statement is not
+// removed from the file and that any derivative work contains
+// the original copyright notice and the associated disclaimer.
+//
+// This source file is free software; you can redistribute it
+// and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation;
+// either version 2.1 of the License, or (at your option) any
+// later version.
+//
+// This source is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied
+// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+// PURPOSE. See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General
+// Public License along with this source; if not, write to the
+// Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+// Boston, MA 02111-1307 USA
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+// Includes
+//-----------------------------------------------------------------
+`include "uart_defs.v"
+
+//-----------------------------------------------------------------
+// Module:
+//-----------------------------------------------------------------
+module uart_periph
+(
+ // General - Clocking & Reset
+ clk_i,
+ rst_i,
+ intr_o,
+
+ // UART
+ tx_o,
+ rx_i,
+
+ // Peripheral bus
+ addr_i,
+ data_o,
+ data_i,
+ wr_i,
+ rd_i
+);
+
+//-----------------------------------------------------------------
+// Params
+//-----------------------------------------------------------------
+parameter [31:0] UART_DIVISOR = 1;
+
+//-----------------------------------------------------------------
+// I/O
+//-----------------------------------------------------------------
+input clk_i /*verilator public*/;
+input rst_i /*verilator public*/;
+output intr_o /*verilator public*/;
+
+output tx_o /*verilator public*/;
+input rx_i /*verilator public*/;
+
+input [7:0] addr_i /*verilator public*/;
+output [31:0] data_o /*verilator public*/;
+input [31:0] data_i /*verilator public*/;
+input [3:0] wr_i /*verilator public*/;
+input rd_i /*verilator public*/;
+
+//-----------------------------------------------------------------
+// Registers / Wires
+//-----------------------------------------------------------------
+reg [31:0] data_o;
+
+// UART
+reg [7:0] uart_tx_data;
+wire [7:0] uart_rx_data;
+reg uart_wr;
+reg uart_rd;
+wire uart_tx_busy;
+wire uart_rx_avail;
+
+//-----------------------------------------------------------------
+// Instantiation
+//-----------------------------------------------------------------
+
+// UART
+uart
+#(
+ .UART_DIVISOR(UART_DIVISOR)
+)
+u1_uart
+(
+ .clk_i(clk_i),
+ .rst_i(rst_i),
+ .data_i(uart_tx_data),
+ .data_o(uart_rx_data),
+ .wr_i(uart_wr),
+ .rd_i(uart_rd),
+ .tx_busy_o(uart_tx_busy),
+ .rx_ready_o(uart_rx_avail),
+ .rxd_i(rx_i),
+ .txd_o(tx_o)
+);
+
+//-----------------------------------------------------------------
+// Peripheral Register Write
+//-----------------------------------------------------------------
+always @ (posedge rst_i or posedge clk_i )
+begin
+ if (rst_i == 1'b1)
+ begin
+ uart_tx_data <= 8'h00;
+ uart_wr <= 1'b0;
+ end
+ else
+ begin
+
+ uart_wr <= 1'b0;
+
+ // Write Cycle
+ if (wr_i != 4'b0000)
+ begin
+ case (addr_i)
+
+ `UART_UDR :
+ begin
+ uart_tx_data <= data_i[7:0];
+ uart_wr <= 1'b1;
+ end
+
+ default :
+ ;
+ endcase
+ end
+ end
+end
+
+//-----------------------------------------------------------------
+// Peripheral Register Read
+//-----------------------------------------------------------------
+always @ (posedge rst_i or posedge clk_i )
+begin
+ if (rst_i == 1'b1)
+ begin
+ data_o <= 32'h00000000;
+ uart_rd <= 1'b0;
+ end
+ else
+ begin
+ uart_rd <= 1'b0;
+
+ // Read cycle?
+ if (rd_i == 1'b1)
+ begin
+ case (addr_i[7:0])
+
+ `UART_USR :
+ data_o <= {27'h0000000, 1'b0, uart_tx_busy, 1'b0, 1'b0, uart_rx_avail};
+
+ `UART_UDR :
+ begin
+ data_o <= {24'h000000,uart_rx_data};
+ uart_rd <= 1'b1;
+ end
+
+ default :
+ data_o <= 32'h00000000;
+ endcase
+ end
+ end
+end
+
+//-----------------------------------------------------------------
+// Assignments
+//-----------------------------------------------------------------
+assign intr_o = uart_rx_avail;
+
+endmodule
Index: peripheral/intr_periph.v
===================================================================
--- peripheral/intr_periph.v (nonexistent)
+++ peripheral/intr_periph.v (revision 9)
@@ -0,0 +1,233 @@
+//-----------------------------------------------------------------
+// MPX 32-bit Soft-Core Processor
+// V0.1
+// Ultra-Embedded.com
+// Copyright 2011 - 2012
+//
+// Email: admin@ultra-embedded.com
+//
+// License: LGPL
+//
+// If you would like a version with a different license for use
+// in commercial projects please contact the above email address
+// for more details.
+//-----------------------------------------------------------------
+//
+// Copyright (C) 2011 - 2012 Ultra-Embedded.com
+//
+// This source file may be used and distributed without
+// restriction provided that this copyright statement is not
+// removed from the file and that any derivative work contains
+// the original copyright notice and the associated disclaimer.
+//
+// This source file is free software; you can redistribute it
+// and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation;
+// either version 2.1 of the License, or (at your option) any
+// later version.
+//
+// This source is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied
+// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+// PURPOSE. See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General
+// Public License along with this source; if not, write to the
+// Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+// Boston, MA 02111-1307 USA
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+// Includes
+//-----------------------------------------------------------------
+`include "intr_defs.v"
+
+//-----------------------------------------------------------------
+// Module:
+//-----------------------------------------------------------------
+module intr_periph
+(
+ // General - Clocking & Reset
+ clk_i,
+ rst_i,
+ intr_o,
+
+ // Interrupts
+ intr0_i,
+ intr1_i,
+ intr2_i,
+ intr3_i,
+ intr4_i,
+ intr5_i,
+ intr6_i,
+ intr7_i,
+ intr_ext_i,
+
+ // Peripheral bus
+ addr_i,
+ data_o,
+ data_i,
+ wr_i,
+ rd_i
+);
+
+//-----------------------------------------------------------------
+// Params
+//-----------------------------------------------------------------
+parameter EXTERNAL_INTERRUPTS = 1;
+parameter INTERRUPT_COUNT = EXTERNAL_INTERRUPTS + 8;
+
+//-----------------------------------------------------------------
+// I/O
+//-----------------------------------------------------------------
+input clk_i /*verilator public*/;
+input rst_i /*verilator public*/;
+output intr_o /*verilator public*/;
+
+input intr0_i /*verilator public*/;
+input intr1_i /*verilator public*/;
+input intr2_i /*verilator public*/;
+input intr3_i /*verilator public*/;
+input intr4_i /*verilator public*/;
+input intr5_i /*verilator public*/;
+input intr6_i /*verilator public*/;
+input intr7_i /*verilator public*/;
+input [(EXTERNAL_INTERRUPTS - 1):0] intr_ext_i /*verilator public*/;
+input [7:0] addr_i /*verilator public*/;
+output [31:0] data_o /*verilator public*/;
+input [31:0] data_i /*verilator public*/;
+input [3:0] wr_i /*verilator public*/;
+input rd_i /*verilator public*/;
+
+//-----------------------------------------------------------------
+// Registers / Wires
+//-----------------------------------------------------------------
+reg [31:0] data_o;
+reg intr_o;
+
+// IRQ Status
+wire intr_in;
+reg [INTERRUPT_COUNT-1:0] irq_status;
+reg [INTERRUPT_COUNT-1:0] irq_mask;
+reg [INTERRUPT_COUNT-1:0] v_irq_status;
+
+//-----------------------------------------------------------------
+// Peripheral Register Write
+//-----------------------------------------------------------------
+always @ (posedge rst_i or posedge clk_i )
+begin
+ if (rst_i == 1'b1)
+ begin
+ irq_status <= {(INTERRUPT_COUNT){1'b0}};
+ irq_mask <= {(INTERRUPT_COUNT){1'b0}};
+ intr_o <= 1'b0;
+ end
+ else
+ begin
+
+ // Get current IRQ status
+ v_irq_status = irq_status;
+
+ // IRQ0
+ if (intr0_i == 1'b1)
+ v_irq_status[0] = 1'b1;
+
+ // IRQ1
+ if (intr1_i == 1'b1)
+ v_irq_status[1] = 1'b1;
+
+ // IRQ2
+ if (intr2_i == 1'b1)
+ v_irq_status[2] = 1'b1;
+
+ // IRQ3
+ if (intr3_i == 1'b1)
+ v_irq_status[3] = 1'b1;
+
+ // IRQ4
+ if (intr4_i == 1'b1)
+ v_irq_status[4] = 1'b1;
+
+ // IRQ5
+ if (intr5_i == 1'b1)
+ v_irq_status[5] = 1'b1;
+
+ // IRQ6
+ if (intr6_i == 1'b1)
+ v_irq_status[6] = 1'b1;
+
+ // IRQ7
+ if (intr7_i == 1'b1)
+ v_irq_status[7] = 1'b1;
+
+ // External interrupts
+ begin : ext_ints_loop
+ integer i;
+ for (i=0; i< EXTERNAL_INTERRUPTS; i=i+1)
+ begin
+ if (intr_ext_i[i] == 1'b1)
+ v_irq_status[(`IRQ_EXT_FIRST + i)] = 1'b1;
+ end
+ end
+
+ // Update IRQ status
+ irq_status <= v_irq_status;
+
+ // Generate interrupt based on masked status
+ intr_o <= ((v_irq_status & irq_mask) != {(INTERRUPT_COUNT){1'b0}}) ? 1'b1 : 1'b0;
+
+ // Write Cycle
+ if (wr_i != 4'b0000)
+ begin
+ case (addr_i)
+
+ `IRQ_MASK_SET :
+ irq_mask <= (irq_mask | data_i[INTERRUPT_COUNT-1:0]);
+
+ `IRQ_MASK_CLR :
+ irq_mask <= (irq_mask & ~ (data_i[INTERRUPT_COUNT-1:0]));
+
+ `IRQ_STATUS : // (IRQ Acknowledge)
+ irq_status <= (v_irq_status & ~ (data_i[INTERRUPT_COUNT-1:0]));
+
+ default :
+ ;
+ endcase
+ end
+ end
+end
+
+//-----------------------------------------------------------------
+// Peripheral Register Read
+//-----------------------------------------------------------------
+always @ (posedge rst_i or posedge clk_i )
+begin
+ if (rst_i == 1'b1)
+ begin
+ data_o <= 32'h00000000;
+ end
+ else
+ begin
+ // Read cycle?
+ if (rd_i == 1'b1)
+ begin
+ case (addr_i[7:0])
+
+ `IRQ_MASK_SET :
+ data_o <= {{(32-INTERRUPT_COUNT){1'b0}}, irq_mask};
+
+ `IRQ_MASK_CLR :
+ data_o <= {{(32-INTERRUPT_COUNT){1'b0}}, irq_mask};
+
+ `IRQ_STATUS :
+ data_o <= {{(32-INTERRUPT_COUNT){1'b0}}, irq_status};
+
+ default :
+ data_o <= 32'h00000000;
+ endcase
+ end
+ end
+end
+
+endmodule
Index: peripheral/gpio_periph.v
===================================================================
--- peripheral/gpio_periph.v (nonexistent)
+++ peripheral/gpio_periph.v (revision 9)
@@ -0,0 +1,287 @@
+//-----------------------------------------------------------------
+// MPX 32-bit Soft-Core Processor
+// V0.1
+// Ultra-Embedded.com
+// Copyright 2011 - 2012
+//
+// Email: admin@ultra-embedded.com
+//
+// License: LGPL
+//
+// If you would like a version with a different license for use
+// in commercial projects please contact the above email address
+// for more details.
+//-----------------------------------------------------------------
+//
+// Copyright (C) 2011 - 2012 Ultra-Embedded.com
+//
+// This source file may be used and distributed without
+// restriction provided that this copyright statement is not
+// removed from the file and that any derivative work contains
+// the original copyright notice and the associated disclaimer.
+//
+// This source file is free software; you can redistribute it
+// and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation;
+// either version 2.1 of the License, or (at your option) any
+// later version.
+//
+// This source is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied
+// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+// PURPOSE. See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General
+// Public License along with this source; if not, write to the
+// Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+// Boston, MA 02111-1307 USA
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+// Includes
+//-----------------------------------------------------------------
+`include "gpio_defs.v"
+
+//-----------------------------------------------------------------
+// Module:
+//-----------------------------------------------------------------
+module gpio_periph
+(
+ // General
+ clk_i,
+ rst_i,
+ intr_o,
+
+ // Ports
+ gpio_i,
+ gpio_o,
+ gpio_out_en_o,
+
+ // Peripheral bus
+ addr_i,
+ data_o,
+ data_i,
+ wr_i,
+ rd_i
+);
+
+//-----------------------------------------------------------------
+// Params
+//-----------------------------------------------------------------
+parameter GPIO_WIDTH = 8;
+
+//-----------------------------------------------------------------
+// I/O
+//-----------------------------------------------------------------
+input clk_i /*verilator public*/;
+input rst_i /*verilator public*/;
+output intr_o /*verilator public*/;
+input [GPIO_WIDTH-1:0] gpio_i /*verilator public*/;
+output [GPIO_WIDTH-1:0] gpio_o /*verilator public*/;
+output [GPIO_WIDTH-1:0] gpio_out_en_o /*verilator public*/;
+input [7:0] addr_i /*verilator public*/;
+output [31:0] data_o /*verilator public*/;
+input [31:0] data_i /*verilator public*/;
+input [3:0] wr_i /*verilator public*/;
+input rd_i /*verilator public*/;
+
+//-----------------------------------------------------------------
+// Registers / Wires
+//-----------------------------------------------------------------
+
+reg [31:0] data_o;
+wire[GPIO_WIDTH-1:0] gpio_o;
+wire[GPIO_WIDTH-1:0] gpio_out_en_o;
+reg intr_o;
+
+reg [GPIO_WIDTH-1:0] gpio_out;
+reg [GPIO_WIDTH-1:0] gpio_in;
+reg [GPIO_WIDTH-1:0] gpio_in_last;
+reg [GPIO_WIDTH-1:0] gpio_in_sync;
+reg [GPIO_WIDTH-1:0] gpio_out_en;
+reg [GPIO_WIDTH-1:0] gpio_int_mask;
+reg [GPIO_WIDTH-1:0] gpio_int_polarity;
+reg [GPIO_WIDTH-1:0] gpio_int_edge;
+
+//-----------------------------------------------------------------
+// Resync inputs
+//-----------------------------------------------------------------
+always @ (posedge rst_i or posedge clk_i )
+begin
+ if (rst_i == 1'b1)
+ begin
+ gpio_in_sync <= {(GPIO_WIDTH){1'b0}};
+ gpio_in <= {(GPIO_WIDTH){1'b0}};
+ end
+ else
+ begin
+ gpio_in_sync <= gpio_i;
+ gpio_in <= gpio_in_sync;
+ end
+end
+
+//-----------------------------------------------------------------
+// GPIO interrupt handling
+//-----------------------------------------------------------------
+reg v_gpio_in;
+reg v_intr_out;
+
+always @ (posedge rst_i or posedge clk_i )
+begin
+ if (rst_i == 1'b1)
+ begin
+ gpio_in_last <= {(GPIO_WIDTH){1'b0}};
+ intr_o <= 1'b0;
+ end
+ else
+ begin
+ gpio_in_last <= gpio_in;
+
+ v_intr_out = 1'b0;
+
+ // GPIO interrupt?
+ begin : ext_ints_loop
+ integer i;
+ for (i=0; i< GPIO_WIDTH; i=i+1)
+ begin
+
+ // Input & interrupt enabled on this input
+ if (gpio_out_en[i] == 1'b0 && gpio_int_mask[i] == 1'b1)
+ begin
+ // Level sensitive interrupt
+ if (gpio_int_edge[i] == 1'b0)
+ begin
+ v_gpio_in = gpio_in[i];
+
+ // Invert polarity for active low interrupts?
+ if (gpio_int_polarity[i] == 1'b0)
+ v_gpio_in = !v_gpio_in;
+
+ // Interrupt active?
+ if (v_gpio_in == 1'b1)
+ v_intr_out = 1'b1;
+ end
+ // Edge sensitive interrupt
+ else
+ begin
+
+ // Falling edge triggered
+ if (gpio_int_polarity[i] == 1'b0)
+ begin
+
+ // Pin H -> L
+ if (gpio_in_last[i] == 1'b1 && gpio_in[i] == 1'b0)
+ v_intr_out = 1'b1;
+
+ end
+ // Rising edge triggered
+ else
+ begin
+
+ // Pin L -> H
+ if (gpio_in_last[i] == 1'b0 && gpio_in[i] == 1'b1)
+ v_intr_out = 1'b1;
+
+ end
+ end
+ end
+
+ end
+ end
+
+ intr_o <= v_intr_out;
+ end
+end
+
+//-----------------------------------------------------------------
+// Peripheral Register Write
+//-----------------------------------------------------------------
+always @ (posedge rst_i or posedge clk_i )
+begin
+ if (rst_i == 1'b1)
+ begin
+ gpio_out <= {(GPIO_WIDTH){1'b0}};
+ gpio_out_en <= {(GPIO_WIDTH){1'b1}};
+ gpio_int_mask <= {(GPIO_WIDTH){1'b0}};
+ gpio_int_polarity <= {(GPIO_WIDTH){1'b0}};
+ gpio_int_edge <= {(GPIO_WIDTH){1'b0}};
+ end
+ else
+ begin
+
+ // Write Cycle
+ if (wr_i != 4'b0000)
+ begin
+ case (addr_i)
+
+ `GPIO_OUT :
+ gpio_out <= data_i[GPIO_WIDTH-1:0];
+
+ `GPIO_DIR :
+ gpio_out_en <= data_i[GPIO_WIDTH-1:0];
+
+ `GPIO_INT_MASK :
+ gpio_int_mask <= data_i[GPIO_WIDTH-1:0];
+
+ `GPIO_INT_POLARITY :
+ gpio_int_polarity <= data_i[GPIO_WIDTH-1:0];
+
+ `GPIO_INT_EDGE :
+ gpio_int_edge <= data_i[GPIO_WIDTH-1:0];
+
+ default :
+ ;
+ endcase
+ end
+ end
+end
+
+//-----------------------------------------------------------------
+// Peripheral Register Read
+//-----------------------------------------------------------------
+always @ (posedge rst_i or posedge clk_i )
+begin
+ if (rst_i == 1'b1)
+ begin
+ data_o <= 32'h00000000;
+ end
+ else
+ begin
+ // Read cycle?
+ if (rd_i == 1'b1)
+ begin
+ case (addr_i[7:0])
+
+ `GPIO_OUT :
+ data_o <= {{(32-GPIO_WIDTH){1'b0}}, gpio_out};
+
+ `GPIO_DIR :
+ data_o <= {{(32-GPIO_WIDTH){1'b0}}, gpio_out_en};
+
+ `GPIO_IN :
+ data_o <= {{(32-GPIO_WIDTH){1'b0}}, gpio_in};
+
+ `GPIO_INT_MASK :
+ data_o <= {{(32-GPIO_WIDTH){1'b0}}, gpio_int_mask};
+
+ `GPIO_INT_POLARITY :
+ data_o <= {{(32-GPIO_WIDTH){1'b0}}, gpio_int_polarity};
+
+ `GPIO_INT_EDGE :
+ data_o <= {{(32-GPIO_WIDTH){1'b0}}, gpio_int_edge};
+
+ default :
+ data_o <= 32'h00000000;
+ endcase
+ end
+ end
+end
+
+//-----------------------------------------------------------------
+// Assignments
+//-----------------------------------------------------------------
+assign gpio_o = gpio_out;
+assign gpio_out_en_o = gpio_out_en;
+
+endmodule
Index: peripheral/spi_master.v
===================================================================
--- peripheral/spi_master.v (nonexistent)
+++ peripheral/spi_master.v (revision 9)
@@ -0,0 +1,214 @@
+//-----------------------------------------------------------------
+// MPX 32-bit Soft-Core Processor
+// V0.1
+// Ultra-Embedded.com
+// Copyright 2011 - 2012
+//
+// Email: admin@ultra-embedded.com
+//
+// License: LGPL
+//
+// If you would like a version with a different license for use
+// in commercial projects please contact the above email address
+// for more details.
+//-----------------------------------------------------------------
+//
+// Copyright (C) 2011 - 2012 Ultra-Embedded.com
+//
+// This source file may be used and distributed without
+// restriction provided that this copyright statement is not
+// removed from the file and that any derivative work contains
+// the original copyright notice and the associated disclaimer.
+//
+// This source file is free software; you can redistribute it
+// and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation;
+// either version 2.1 of the License, or (at your option) any
+// later version.
+//
+// This source is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied
+// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+// PURPOSE. See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General
+// Public License along with this source; if not, write to the
+// Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+// Boston, MA 02111-1307 USA
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+// Module
+//-----------------------------------------------------------------
+module spi_master
+(
+ // Clocking & Reset
+ clk_i,
+ rst_i,
+ // Control & Status
+ start_i,
+ done_o,
+ busy_o,
+ // Data
+ data_i,
+ data_o,
+ // SPI Bus
+ spi_clk_o,
+ spi_ss_o,
+ spi_mosi_o,
+ spi_miso_i
+);
+
+//-----------------------------------------------------------------
+// Params
+//-----------------------------------------------------------------
+parameter [31:0] CLK_DIV = 32;
+parameter [31:0] TRANSFER_WIDTH = 8;
+
+//-----------------------------------------------------------------
+// I/O
+//-----------------------------------------------------------------
+input clk_i /*verilator public*/;
+input rst_i /*verilator public*/;
+input start_i /*verilator public*/;
+output done_o /*verilator public*/;
+output busy_o /*verilator public*/;
+input [(TRANSFER_WIDTH - 1):0] data_i /*verilator public*/;
+output [(TRANSFER_WIDTH - 1):0] data_o /*verilator public*/;
+output spi_clk_o /*verilator public*/;
+output spi_ss_o /*verilator public*/;
+output spi_mosi_o /*verilator public*/;
+input spi_miso_i /*verilator public*/;
+
+//-----------------------------------------------------------------
+// Registers
+//-----------------------------------------------------------------
+reg running;
+integer cycle_count;
+reg [(TRANSFER_WIDTH - 1):0] shift_reg;
+reg spi_clk_gen;
+reg last_clk_gen;
+integer clk_div_count;
+reg done_o;
+reg spi_ss_o;
+reg spi_clk_o;
+
+//-----------------------------------------------------------------
+// Implementation
+//-----------------------------------------------------------------
+
+// SPI Clock Generator
+always @ (posedge clk_i or posedge rst_i )
+begin
+ // Async Reset
+ if (rst_i == 1'b1)
+ begin
+ clk_div_count <= 0;
+ spi_clk_gen <= 1'b0;
+ end
+ else
+ begin
+ // SPI transfer active?
+ if (running == 1'b1)
+ begin
+ // Clock divider cycle_count matched?
+ if (clk_div_count == (CLK_DIV - 1))
+ begin
+ // Toggle clock (input to SPI transfer process)
+ spi_clk_gen <= ~(spi_clk_gen);
+
+ // Reset counter
+ clk_div_count <= 0;
+ end
+ // Increment SPI clock divider counter
+ else
+ clk_div_count <= (clk_div_count + 1);
+ end
+ else // (!running)
+ spi_clk_gen <= 1'b0;
+ end
+end
+
+// SPI transfer process
+always @ (posedge clk_i or posedge rst_i )
+begin
+ // Async Reset
+ if (rst_i == 1'b1)
+ begin
+ cycle_count <= 0;
+ shift_reg <= {(TRANSFER_WIDTH - 0){1'b0}};
+ last_clk_gen <= 1'b0;
+ spi_clk_o <= 1'b0;
+ running <= 1'b0;
+ done_o <= 1'b0;
+ spi_ss_o <= 1'b0;
+ end
+ else
+ begin
+
+ // Update previous SCLK value
+ last_clk_gen <= spi_clk_gen;
+
+ done_o <= 1'b0;
+
+ //-------------------------------
+ // SPI = IDLE
+ //-------------------------------
+ if (running == 1'b0)
+ begin
+ // Wait until start_i = 1 to start_i transfer
+ if (start_i == 1'b1)
+ begin
+ cycle_count <= 0;
+ shift_reg <= data_i;
+ running <= 1'b1;
+ spi_ss_o <= 1'b1;
+ end
+ end
+ else
+ //-------------------------------
+ // SPI = RUNNING
+ //-------------------------------
+ begin
+ // SCLK 1->0 - Falling Edge
+ if ((last_clk_gen == 1'b1) && (spi_clk_gen == 1'b0))
+ begin
+ // SCLK_OUT = L
+ spi_clk_o <= 1'b0;
+
+ // Increment cycle counter
+ cycle_count <= (cycle_count + 1);
+
+ // Shift left & add MISO to LSB
+ shift_reg <= {shift_reg[(TRANSFER_WIDTH - 2):0],spi_miso_i};
+
+ // End of SPI transfer reached
+ if (cycle_count == (TRANSFER_WIDTH - 1))
+ begin
+ // Go back to IDLE running
+ running <= 1'b0;
+
+ // Set transfer complete flags
+ done_o <= 1'b1;
+ spi_ss_o <= 1'b0;
+ end
+ end
+ // SCLK 0->1 - Rising Edge
+ else if ((last_clk_gen == 1'b0) & (spi_clk_gen == 1'b1))
+ begin
+ // SCLK_OUT = H
+ spi_clk_o <= 1'b1;
+ end
+ end
+ end
+end
+
+//-----------------------------------------------------------------
+// Combinatorial Logic
+//-----------------------------------------------------------------
+assign spi_mosi_o = shift_reg[(TRANSFER_WIDTH - 1)];
+assign data_o = shift_reg;
+assign busy_o = ((running == 1'b1) || (start_i == 1'b1)) ? 1'b1 : 1'b0;
+
+endmodule
Index: peripheral/timer_periph.v
===================================================================
--- peripheral/timer_periph.v (nonexistent)
+++ peripheral/timer_periph.v (revision 9)
@@ -0,0 +1,282 @@
+//-----------------------------------------------------------------
+// MPX 32-bit Soft-Core Processor
+// V0.1
+// Ultra-Embedded.com
+// Copyright 2011 - 2012
+//
+// Email: admin@ultra-embedded.com
+//
+// License: LGPL
+//
+// If you would like a version with a different license for use
+// in commercial projects please contact the above email address
+// for more details.
+//-----------------------------------------------------------------
+//
+// Copyright (C) 2011 - 2012 Ultra-Embedded.com
+//
+// This source file may be used and distributed without
+// restriction provided that this copyright statement is not
+// removed from the file and that any derivative work contains
+// the original copyright notice and the associated disclaimer.
+//
+// This source file is free software; you can redistribute it
+// and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation;
+// either version 2.1 of the License, or (at your option) any
+// later version.
+//
+// This source is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied
+// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+// PURPOSE. See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General
+// Public License along with this source; if not, write to the
+// Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+// Boston, MA 02111-1307 USA
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+// Includes
+//-----------------------------------------------------------------
+`include "timer_defs.v"
+
+//-----------------------------------------------------------------
+// Module:
+//-----------------------------------------------------------------
+module timer_periph
+(
+ // General - Clocking & Reset
+ clk_i,
+ rst_i,
+
+ // Interrupts
+ intr_systick_o,
+ intr_hires_o,
+
+ // Peripheral bus
+ addr_i,
+ data_o,
+ data_i,
+ wr_i,
+ rd_i
+);
+
+//-----------------------------------------------------------------
+// Params
+//-----------------------------------------------------------------
+parameter [31:0] CLK_KHZ = 12288;
+parameter SYSTICK_INTR_MS = 1;
+parameter ENABLE_SYSTICK_TIMER = "ENABLED";
+parameter ENABLE_HIGHRES_TIMER = "ENABLED";
+
+//-----------------------------------------------------------------
+// I/O
+//-----------------------------------------------------------------
+input clk_i /*verilator public*/;
+input rst_i /*verilator public*/;
+
+output intr_systick_o /*verilator public*/;
+output intr_hires_o /*verilator public*/;
+
+input [7:0] addr_i /*verilator public*/;
+output [31:0] data_o /*verilator public*/;
+input [31:0] data_i /*verilator public*/;
+input [3:0] wr_i /*verilator public*/;
+input rd_i /*verilator public*/;
+
+//-----------------------------------------------------------------
+// Registers / Wires
+//-----------------------------------------------------------------
+
+reg [31:0] data_o;
+
+// Systick Timer
+reg systick_event;
+reg [31:0] systick_count;
+reg [31:0] systick_clk_count;
+
+// Hi-res system clock tick counter
+reg hr_timer_intr;
+reg [31:0] hr_timer_cnt;
+reg [31:0] hr_timer_match;
+
+//-----------------------------------------------------------------
+// Systick
+//-----------------------------------------------------------------
+generate
+if (ENABLE_SYSTICK_TIMER == "ENABLED")
+begin
+
+ // SysTick Timer (1 ms resolution)
+ always @ (posedge rst_i or posedge clk_i )
+ begin
+ if (rst_i == 1'b1)
+ begin
+ systick_count <= 32'h00000000;
+ systick_clk_count <= 32'h00000000;
+ systick_event <= 1'b0;
+ end
+ else
+ begin
+ systick_event <= 1'b0;
+
+ if (systick_clk_count == CLK_KHZ)
+ begin
+ systick_count <= (systick_count + 1);
+ systick_event <= 1'b1;
+ systick_clk_count <= 32'h00000000;
+ end
+ else
+ systick_clk_count <= (systick_clk_count + 1);
+ end
+ end
+
+ // SysTick Interrupt
+ integer systick_event_count;
+ reg systick_event_intr;
+
+ always @ (posedge rst_i or posedge clk_i )
+ begin
+ if (rst_i == 1'b1)
+ begin
+ systick_event_count <= 0;
+ systick_event_intr <= 1'b0;
+ end
+ else
+ begin
+ systick_event_intr <= 1'b0;
+
+ if (systick_event)
+ begin
+ systick_event_count <= (systick_event_count + 1);
+
+ if (systick_event_count == (SYSTICK_INTR_MS-1))
+ begin
+ systick_event_intr <= 1'b1;
+ systick_event_count <= 0;
+ end
+ end
+ end
+ end
+
+ assign intr_systick_o = systick_event_intr;
+end
+else
+begin
+ // Systick disabled
+ always @ (posedge rst_i or posedge clk_i )
+ begin
+ if (rst_i == 1'b1)
+ systick_count <= 32'h00000000;
+ else
+ systick_count <= 32'h00000000;
+ end
+
+ assign intr_systick_o = 1'b0;
+end
+endgenerate
+
+//-----------------------------------------------------------------
+// Hi Resolution Timer
+//-----------------------------------------------------------------
+generate
+if (ENABLE_HIGHRES_TIMER == "ENABLED")
+begin
+
+ always @ (posedge rst_i or posedge clk_i)
+ begin
+ if (rst_i == 1'b1)
+ begin
+ hr_timer_cnt <= 32'h00000000;
+ hr_timer_intr <= 1'b0;
+ end
+ else
+ begin
+ hr_timer_intr <= 1'b0;
+
+ // Clock tick counter
+ hr_timer_cnt <= (hr_timer_cnt + 1);
+
+ // Hi-res Timer IRQ
+ if ((hr_timer_match != 32'h00000000) && (hr_timer_match == hr_timer_cnt))
+ hr_timer_intr <= 1'b1;
+ end
+ end
+
+ assign intr_hires_o = hr_timer_intr;
+end
+else
+begin
+ // Hi resolution timer disabled
+ always @ (posedge rst_i or posedge clk_i )
+ begin
+ if (rst_i == 1'b1)
+ hr_timer_cnt <= 32'h00000000;
+ else
+ hr_timer_cnt <= 32'h00000000;
+ end
+
+ assign intr_hires_o = 1'b0;
+end
+endgenerate
+//-----------------------------------------------------------------
+// Peripheral Register Write
+//-----------------------------------------------------------------
+always @ (posedge rst_i or posedge clk_i )
+begin
+ if (rst_i == 1'b1)
+ begin
+ hr_timer_match <= 32'h00000000;
+ end
+ else
+ begin
+ // Write Cycle
+ if (wr_i != 4'b0000)
+ begin
+ case (addr_i)
+
+ `TIMER_HIRES :
+ hr_timer_match <= data_i;
+
+ default :
+ ;
+ endcase
+ end
+ end
+end
+
+//-----------------------------------------------------------------
+// Peripheral Register Read
+//-----------------------------------------------------------------
+always @ (posedge rst_i or posedge clk_i )
+begin
+ if (rst_i == 1'b1)
+ begin
+ data_o <= 32'h00000000;
+ end
+ else
+ begin
+ // Read cycle?
+ if (rd_i == 1'b1)
+ begin
+ case (addr_i[7:0])
+
+ // 32-bit systick/1ms counter
+ `TIMER_SYSTICK_VAL :
+ data_o <= systick_count;
+
+ // Hi res timer (clock rate)
+ `TIMER_HIRES :
+ data_o <= hr_timer_cnt;
+
+ default :
+ data_o <= 32'h00000000;
+ endcase
+ end
+ end
+end
+
+endmodule
Index: peripheral/spim_defs.v
===================================================================
--- peripheral/spim_defs.v (nonexistent)
+++ peripheral/spim_defs.v (revision 9)
@@ -0,0 +1,46 @@
+//-----------------------------------------------------------------
+// MPX 32-bit Soft-Core Processor
+// V0.1
+// Ultra-Embedded.com
+// Copyright 2011 - 2012
+//
+// Email: admin@ultra-embedded.com
+//
+// License: LGPL
+//
+// If you would like a version with a different license for use
+// in commercial projects please contact the above email address
+// for more details.
+//-----------------------------------------------------------------
+//
+// Copyright (C) 2011 - 2012 Ultra-Embedded.com
+//
+// This source file may be used and distributed without
+// restriction provided that this copyright statement is not
+// removed from the file and that any derivative work contains
+// the original copyright notice and the associated disclaimer.
+//
+// This source file is free software; you can redistribute it
+// and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation;
+// either version 2.1 of the License, or (at your option) any
+// later version.
+//
+// This source is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied
+// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+// PURPOSE. See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General
+// Public License along with this source; if not, write to the
+// Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+// Boston, MA 02111-1307 USA
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+// Registers
+//-----------------------------------------------------------------
+`define SPI_MASTER_CTRL 8'h00
+`define SPI_MASTER_STAT 8'h00
+`define SPI_MASTER_DATA 8'h04