OpenCores
URL https://opencores.org/ocsvn/altor32/altor32/trunk

Subversion Repositories altor32

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /altor32
    from Rev 4 to Rev 5
    Reverse comparison

Rev 4 → Rev 5

/trunk/rtl/sim_verilator/top.cpp
0,0 → 1,293
//-----------------------------------------------------------------
// AltOR32
// Alternative Lightweight OpenRisc
// 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 "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 0x0000
#define MEMORY_SIZE (512 * 1024)
#define REGISTERS 32
 
//-----------------------------------------------------------------
// 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 current_cycle = 0;
unsigned int last_pc = top->dbg_pc_o;
 
// 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);
 
if (last_pc != top->dbg_pc_o)
{
last_pc = top->dbg_pc_o;
current_cycle++;
}
 
if (_stop_pc == top->dbg_pc_o || top->break_o)
break;
}
 
// Fault
if (top->fault_o)
return TOP_RES_FAULT;
// Number of cycles reached
else if (current_cycle >= cycles)
return TOP_RES_MAX_CYCLES;
// Breakpoint hit
else if (_stop_pc == top->dbg_pc_o || top->break_o)
return TOP_RES_BREAKPOINT;
// 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 top->dbg_pc_o;
}
//-----------------------------------------------------------------
// top_done
//-----------------------------------------------------------------
void top_done(void)
{
top->final();
#if VM_TRACE
if (tfp)
{
tfp->close();
tfp = NULL;
}
#endif
}
/trunk/rtl/sim_verilator/main.cpp
0,0 → 1,152
//-----------------------------------------------------------------
// AltOR32
// Alternative Lightweight OpenRisc
// 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
//-----------------------------------------------------------------
 
//-----------------------------------------------------------------
// Locals
//-----------------------------------------------------------------
 
//-----------------------------------------------------------------
// main
//-----------------------------------------------------------------
int main(int argc, char **argv, char **env)
{
int c;
int err;
unsigned int loadAddr = 0x00000000;
char *filename = NULL;
int help = 0;
int exitcode = 0;
int cycles = -1;
 
Verilated::commandArgs(argc, argv);
 
while ((c = getopt (argc, argv, "f:l:c:")) != -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 '?':
default:
help = 1;
break;
}
}
 
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");
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);
 
if (err == TOP_RES_FAULT)
printf("FAULT PC %x!\n", top_getpc());
 
top_done();
 
printf("Exit\n");
exit(0);
}
/trunk/rtl/sim_verilator/sram.v
0,0 → 1,90
//-----------------------------------------------------------------
// AltOR32
// Alternative Lightweight OpenRisc
// 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
/trunk/rtl/sim_verilator/top.v
0,0 → 1,164
//-----------------------------------------------------------------
// AltOR32
// Alternative Lightweight OpenRisc
// 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,
dbg_pc_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 [31:0] dbg_pc_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 [31:0] dbg_pc_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;
 
//-----------------------------------------------------------------
// 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)
);
 
alt_soc
#(
.CLK_KHZ(CLK_KHZ),
.UART_BAUD(115200),
.EXTERNAL_INTERRUPTS(1),
.CORE_ID(32'h00000000),
.BOOT_VECTOR(32'h00002000),
.ISR_VECTOR(32'h0000203C)
)
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 */),
// 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 Access
.dbg_pc_o(dbg_pc_o),
// Debug UART output
.dbg_uart_data_o(uart_data_o),
.dbg_uart_wr_o(uart_wr_o)
);
endmodule
/trunk/rtl/sim_verilator/test_image.bin Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
trunk/rtl/sim_verilator/test_image.bin Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: trunk/rtl/sim_verilator/top.h =================================================================== --- trunk/rtl/sim_verilator/top.h (nonexistent) +++ trunk/rtl/sim_verilator/top.h (revision 5) @@ -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 top_setbreakpoint(int bp, unsigned int pc); + + +#endif Index: trunk/rtl/sim_verilator/sram4.v =================================================================== --- trunk/rtl/sim_verilator/sram4.v (nonexistent) +++ trunk/rtl/sim_verilator/sram4.v (revision 5) @@ -0,0 +1,100 @@ +//----------------------------------------------------------------- +// AltOR32 +// Alternative Lightweight OpenRisc +// 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: trunk/rtl/sim_verilator/Readme.txt =================================================================== --- trunk/rtl/sim_verilator/Readme.txt (nonexistent) +++ trunk/rtl/sim_verilator/Readme.txt (revision 5) @@ -0,0 +1,35 @@ +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 0x00000100. + +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. Comparision +Exit Index: trunk/rtl/sim_verilator/makefile =================================================================== --- trunk/rtl/sim_verilator/makefile (nonexistent) +++ trunk/rtl/sim_verilator/makefile (revision 5) @@ -0,0 +1,41 @@ + +# Default binary to load & run +TEST_IMAGE?= test_image.bin + +# Waveform trace disabled by default +TRACE?= 0 + +# Top module (without .v extension) +TOP_MODULE = top + +# CPP Source Files +SRC_CPP = main.cpp top.cpp + +# Source directories +INC_DIRS = -I../altor32 -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 $(SRC_CPP) $(INC_DIRS) +define+CONF_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) + +ifeq ($(TRACE),1) +view: + gtkwave wave_dump.vcd gtksettings.sav +endif + +clean : + -rm -rf $(BUILD_DIR) Index: trunk/rtl/sim_verilator =================================================================== --- trunk/rtl/sim_verilator (nonexistent) +++ trunk/rtl/sim_verilator (revision 5)
trunk/rtl/sim_verilator Property changes : Added: bugtraq:number ## -0,0 +1 ## +true \ No newline at end of property Index: trunk/rtl/soc/alt_soc.v =================================================================== --- trunk/rtl/soc/alt_soc.v (nonexistent) +++ trunk/rtl/soc/alt_soc.v (revision 5) @@ -0,0 +1,697 @@ +//----------------------------------------------------------------- +// AltOR32 +// Alternative Lightweight OpenRisc +// 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 "alt_soc_defs.v" +`include "alt_soc_conf.v" + +//----------------------------------------------------------------- +// Module: +//----------------------------------------------------------------- +module alt_soc +( + // 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, + + // External IO + ext_io_addr_o, + ext_io_data_o, + ext_io_data_i, + ext_io_wr_o, + ext_io_rd_o, + ext_io_pause_i, + + // SPI Flash + flash_cs_o, + flash_si_o, + flash_so_i, + flash_sck_o, + + // Debug Status + dbg_pc_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 CORE_ID = 0; +parameter BOOT_VECTOR = 0; +parameter ISR_VECTOR = 0; + +//----------------------------------------------------------------- +// 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*/; +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*/; +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 [31:0] dbg_pc_o /*verilator public*/; +output [7:0] dbg_uart_data_o /*verilator public*/; +output dbg_uart_wr_o /*verilator public*/; + +//----------------------------------------------------------------- +// Registers +//----------------------------------------------------------------- +wire alt_reset; + +reg [31:0] v_irq_status; +reg [2:0] r_mem_sel; +wire [31:0] cpu_address; +wire [3:0] cpu_byte_we; +wire cpu_oe; +wire [31:0] cpu_data_w; +reg [31:0] cpu_data_r; +reg cpu_pause; + +reg [31:0] io_address; +reg [31:0] io_data_w; +reg [31:0] io_data_r; +reg [3:0] io_wr; +reg io_rd; + +// 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; + +// Systick Timer +reg systick_intr; +reg [31:0] systick_count; +reg [31:0] systick_clk_count; + +// Hi-res system clock tick counter +reg [31:0] hr_timer_cnt; +reg [31:0] hr_timer_match; + +// IRQ Status +wire intr_in; +reg [31:0] irq_status; +reg [31:0] irq_mask; + +// Watchdog +`ifdef SOC_CONF_ENABLE_WATCHDOG + reg watchdog_enable; + reg [15:0] watchdog_threshold; + reg watchdog_expired; + reg watchdog_load; + reg [15:0] watchdog_counter; + reg watchdog_alt_reset; +`endif + +// SPI Flash +`ifdef SOC_CONF_ENABLE_SPI_FLASH + reg spi_flash_start; + wire spi_flash_busy; + reg [7:0] spi_flash_data_wr; + wire [7:0] spi_flash_data_rd; +`endif + +// Output Signals +wire uart_tx_o; +reg [31:0] int_mem_addr_o; +reg [31:0] int_mem_data_o; +reg [3:0] int_mem_wr_o; +reg int_mem_rd_o; +reg [31:0] ext_io_addr_o; +reg [31:0] ext_io_data_o; +reg [3:0] ext_io_wr_o; +reg ext_io_rd_o; +reg flash_cs_o; +wire flash_si_o; +wire flash_sck_o; + +//----------------------------------------------------------------- +// Instantiation +//----------------------------------------------------------------- + +// MPX CPU +altor32 +u1_cpu +( + .clk_i(clk_i), + .rst_i(alt_reset), + .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_byte_we), + .mem_rd_o(cpu_oe), + .mem_pause_i(cpu_pause), + .dbg_pc_o(dbg_pc_o) +); + +// UART +uart +#( + .UART_DIVISOR(((CLK_KHZ * 1000) / UART_BAUD)) +) +u3_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(uart_rx_i), + .txd_o(uart_tx_o) +); + +`ifdef SOC_CONF_ENABLE_SPI_FLASH + // SPI Flash Master + spi_master + #( + .CLK_DIV(CLK_KHZ / SPI_FLASH_CLK_KHZ), + .TRANSFER_WIDTH(8) + ) + u4_spi_flash + ( + // Clocking / Reset + .clk_i(clk_i), + .rst_i(rst_i), + // Control & Status + .start_i(spi_flash_start), + .done_o(/*open */), + .busy_o(spi_flash_busy), + // Data + .data_i(spi_flash_data_wr), + .data_o(spi_flash_data_rd), + // SPI interface + .spi_clk_o(flash_sck_o), + .spi_ss_o(/*open */), + .spi_mosi_o(flash_si_o), + .spi_miso_i(flash_so_i) + ); +`else + // SPI Flash Disabled + assign flash_cs_o = 1'b1; + assign flash_si_o = 1'b0; + assign flash_sck_o = 1'b0; +`endif + +//----------------------------------------------------------------- +// I/O Handlers +//----------------------------------------------------------------- +always @ (posedge rst_i or posedge clk_i ) +begin + if (rst_i == 1'b1) + begin + // UART + uart_tx_data <= 8'h00; + uart_wr <= 1'b0; + + // Interrupt Status + irq_status <= 32'h00000000; + irq_mask <= 32'h00000000; + hr_timer_cnt <= 32'h00000000; + hr_timer_match <= 32'h00000000; + + // SPI Flash (Configuration PROM) + `ifdef SOC_CONF_ENABLE_SPI_FLASH + flash_cs_o <= 1'b1; + spi_flash_start <= 1'b0; + spi_flash_data_wr<= 8'h00; + `endif + + // Watchdog + `ifdef SOC_CONF_ENABLE_WATCHDOG + watchdog_enable <= 1'b0; + watchdog_load <= 1'b0; + watchdog_threshold <= 16'h0000; + `endif + end + else + begin + + uart_wr <= 1'b0; + `ifdef SOC_CONF_ENABLE_SPI_FLASH + spi_flash_start <= 1'b0; + `endif + `ifdef SOC_CONF_ENABLE_WATCHDOG + watchdog_load <= 1'b0; + `endif + + // Get current IRQ status + v_irq_status = irq_status; + + // Clock tick counter + hr_timer_cnt <= (hr_timer_cnt + 1); + + // Systick IRQ? + if (systick_intr == 1'b1) + v_irq_status[`IRQ_SYSTICK] = 1'b1; + + // UART IRQ? + if (uart_rx_avail == 1'b1) + v_irq_status[`IRQ_UART_RX_AVAIL] = 1'b1; + + // Hi-res Timer IRQ [IRQ6] + if ((hr_timer_match != 32'h00000000) && (hr_timer_match == hr_timer_cnt)) + v_irq_status[`IRQ_PIT] = 1'b1; + + // External interrupts + begin : ext_ints_loop + integer i; + for (i=0; i< EXTERNAL_INTERRUPTS; i=i+1) + begin + if (ext_intr_i[i] == 1'b1) + v_irq_status[(`IRQ_EXT_FIRST + i)] = 1'b1; + end + end + + // Update IRQ status + irq_status <= v_irq_status; + + // IO Write Cycle + if (io_wr != 4'b0000) + case (io_address[7:0]) + + `UART_UDR : + begin + uart_tx_data <= io_data_w[7:0]; + uart_wr <= 1'b1; + end + + `IRQ_MASK_SET : + irq_mask <= (irq_mask | io_data_w); + + `IRQ_MASK_CLR : + irq_mask <= (irq_mask & ~ (io_data_w)); + + `IRQ_STATUS : // (IRQ Acknowledge) + irq_status <= (v_irq_status & ~ (io_data_w)); + + `ifdef SOC_CONF_ENABLE_WATCHDOG + `WATCHDOG_CTRL : + begin + // Enable watchdog if non-zero + if (io_data_w[15:0] != 16'h0000) + watchdog_enable <= 1'b1; + else + watchdog_enable <= 1'b0; + + // Store threshold for timeout (16-bit x 1ms) + watchdog_threshold <= io_data_w[15:0]; + watchdog_load <= 1'b1; + end + `endif + + `SYS_CLK_COUNT : + hr_timer_match <= io_data_w; + + `ifdef SOC_CONF_ENABLE_SPI_FLASH + `SPI_PROM_CTRL : + begin + flash_cs_o <= io_data_w[0]; + end + + `SPI_PROM_DATA : + begin + spi_flash_data_wr <= io_data_w[7:0]; + spi_flash_start <= 1'b1; + end + `endif + default : + ; + endcase + end +end + +// IO memory space READ handler +always @ (posedge rst_i or posedge clk_i ) +begin + if (rst_i == 1'b1) + begin + io_data_r <= 32'h00000000; + uart_rd <= 1'b0; + end + else + begin + uart_rd <= 1'b0; + + // Read cycle? + if (io_rd == 1'b1) + case (io_address[7:0]) + + `CORE_ID : + io_data_r <= CORE_ID; + + `UART_USR : + io_data_r <= {27'h0000000, 1'b0, uart_tx_busy, 1'b0, 1'b0, uart_rx_avail}; + + `UART_UDR : + begin + io_data_r <= {24'h000000,uart_rx_data}; + uart_rd <= 1'b1; + end + + `TIMER_VAL : // (32-bit 1ms counter) + io_data_r <= systick_count; + + `IRQ_MASK_SET : + io_data_r <= irq_mask; + + `IRQ_MASK_CLR : + io_data_r <= irq_mask; + + `IRQ_STATUS : + io_data_r <= (irq_status & irq_mask); + + `ifdef SOC_CONF_ENABLE_WATCHDOG + `WATCHDOG_CTRL : + io_data_r <= {15'h000000, watchdog_expired, watchdog_counter}; + `endif + + `SYS_CLK_COUNT : + io_data_r <= hr_timer_cnt; + + `ifdef SOC_CONF_ENABLE_SPI_FLASH + `SPI_PROM_STAT : + io_data_r <= {31'h00000000, spi_flash_busy}; + + `SPI_PROM_DATA : + io_data_r <= {24'h000000, spi_flash_data_rd}; + `endif + + default : + io_data_r <= 32'h00000000; + endcase + end +end + +// 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_intr <= 1'b0; + end + else + begin + systick_intr <= 1'b0; + + if (systick_clk_count == CLK_KHZ) + begin + systick_count <= (systick_count + 1); + systick_intr <= 1'b1; + systick_clk_count <= 32'h00000000; + end + else + systick_clk_count <= (systick_clk_count + 1); + end +end + +// Watchdog +`ifdef SOC_CONF_ENABLE_WATCHDOG + always @ (posedge rst_i or posedge clk_i ) + begin + if (rst_i == 1'b1) + begin + watchdog_counter <= 16'h0000; + watchdog_expired <= 1'b0; + watchdog_alt_reset <= 1'b0; + end + else + begin + + // On 1ms tick - decrement watchdog if enabled + if (systick_intr == 1'b1) + if (watchdog_enable == 1'b1) + begin + // Count down or expire if 0 + if (watchdog_counter != 16'h0000) + watchdog_counter <= (watchdog_counter - 1); + else + begin + // Clear reset if already high + watchdog_alt_reset <= 1'b0; + + // If not already expired, start reset sequence + if (watchdog_expired != 1'b1) + begin + watchdog_expired <= 1'b1; + watchdog_alt_reset <= 1'b1; + + // Hold reset high for a couple of ms + watchdog_counter <= 16'h002; + end + end + end + + // If watchdog reset signalled, reset counter with new threshold value + if (watchdog_load == 1'b1) + begin + watchdog_counter <= watchdog_threshold; + watchdog_expired <= 1'b0; + end + end + end +`endif + +//----------------------------------------------------------------- +// Memory Map +//----------------------------------------------------------------- +always @ (cpu_address or cpu_byte_we or cpu_oe or cpu_data_w ) +begin + case (cpu_address[30:28]) + + // Block RAM + `MEM_REGION_INTERNAL : + begin + int_mem_addr_o = cpu_address; + int_mem_wr_o = cpu_byte_we; + int_mem_rd_o = cpu_oe; + int_mem_data_o = cpu_data_w; + + io_address = 32'h00000000; + io_wr = 4'b0000; + io_rd = 1'b0; + io_data_w = 32'h00000000; + + ext_io_addr_o = 32'h00000000; + ext_io_wr_o = 4'b0000; + ext_io_rd_o = 1'b0; + ext_io_data_o = 32'h00000000; + end + + // Core I/O peripherals + `MEM_REGION_CORE_IO : + begin + io_address = cpu_address; + io_wr = cpu_byte_we; + io_rd = cpu_oe; + io_data_w = cpu_data_w; + + int_mem_addr_o = 32'h00000000; + int_mem_wr_o = 4'b0000; + int_mem_rd_o = 1'b0; + int_mem_data_o = 32'h00000000; + + ext_io_addr_o = 32'h00000000; + ext_io_wr_o = 4'b0000; + ext_io_rd_o = 1'b0; + ext_io_data_o = 32'h00000000; + end + + // Extended I/O peripherals + `MEM_REGION_EXT_IO : + begin + ext_io_addr_o = cpu_address; + ext_io_wr_o = cpu_byte_we; + ext_io_rd_o = cpu_oe; + ext_io_data_o = cpu_data_w; + + int_mem_addr_o = 32'h00000000; + int_mem_wr_o = 4'b0000; + int_mem_rd_o = 1'b0; + int_mem_data_o = 32'h00000000; + + io_address = 32'h00000000; + io_wr = 4'b0000; + io_rd = 1'b0; + io_data_w = 32'h00000000; + end + + default : + begin + io_address = 32'h00000000; + io_wr = 4'b0000; + io_rd = 1'b0; + io_data_w = 32'h00000000; + + int_mem_addr_o = 32'h00000000; + int_mem_wr_o = 4'b0000; + int_mem_rd_o = 1'b0; + int_mem_data_o = 32'h00000000; + + ext_io_addr_o = 32'h00000000; + ext_io_wr_o = 4'b0000; + ext_io_rd_o = 1'b0; + ext_io_data_o = 32'h00000000; + end + endcase +end + +//----------------------------------------------------------------- +// Read Port +//----------------------------------------------------------------- +always @ (r_mem_sel or int_mem_data_i or io_data_r or ext_io_data_i) +begin + case (r_mem_sel) + + // Block RAM + `MEM_REGION_INTERNAL : + begin + cpu_data_r = int_mem_data_i; + cpu_pause = 1'b0; + end + + // Core I/O peripherals + `MEM_REGION_CORE_IO : + begin + cpu_data_r = io_data_r; + cpu_pause = 1'b0; + end + + // Extended I/O peripherals + `MEM_REGION_EXT_IO : + begin + cpu_data_r = ext_io_data_i; + cpu_pause = 1'b0; + end + + default : + begin + cpu_data_r = 32'h00000000; + cpu_pause = 1'b0; + end + endcase +end + +//----------------------------------------------------------------- +// Registered device select +//----------------------------------------------------------------- +reg [31:0] v_mem_sel; + +always @ (posedge clk_i or posedge alt_reset ) +begin + if (alt_reset == 1'b1) + begin + v_mem_sel = BOOT_VECTOR; + r_mem_sel <= v_mem_sel[30:28]; + end + else + r_mem_sel <= cpu_address[30:28]; +end + +//----------------------------------------------------------------- +// Combinatorial Logic +//----------------------------------------------------------------- +assign intr_in = ((irq_mask & irq_status) != 32'h00000000) ? 1'b1 : 1'b0; +`ifdef SOC_CONF_ENABLE_WATCHDOG +assign alt_reset = (rst_i | watchdog_alt_reset); +`else +assign alt_reset = rst_i; +`endif + +//----------------------------------------------------------------- +// External Interface +//----------------------------------------------------------------- +// Debug UART +assign dbg_uart_data_o = uart_tx_data; +assign dbg_uart_wr_o = uart_wr; + +endmodule Index: trunk/rtl/soc/alt_soc_defs.v =================================================================== --- trunk/rtl/soc/alt_soc_defs.v (nonexistent) +++ trunk/rtl/soc/alt_soc_defs.v (revision 5) @@ -0,0 +1,79 @@ +//----------------------------------------------------------------- +// AltOR32 +// Alternative Lightweight OpenRisc +// 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 +//----------------------------------------------------------------- + +//----------------------------------------------------------------- +// Memory Map +//----------------------------------------------------------------- +`define MEM_REGION_INTERNAL 3'b000 +`define MEM_REGION_EXTERNAL 3'b001 +`define MEM_REGION_CORE_IO 3'b010 +`define MEM_REGION_EXT_IO 3'b011 + +//----------------------------------------------------------------- +// I/O +//----------------------------------------------------------------- + +// General +`define CORE_ID 8'h00 + +// Basic Peripherals +`define UART_USR 8'h04 +`define UART_UDR 8'h08 +`define TIMER_VAL 8'h10 +`define IRQ_MASK_SET 8'h14 +`define IRQ_MASK_STATUS 8'h14 +`define IRQ_MASK_CLR 8'h18 +`define IRQ_STATUS 8'h1C + `define IRQ_SYSTICK (0) + `define IRQ_UART_RX_AVAIL (1) + `define IRQ_SW (2) + `define IRQ_PIT (6) + `define IRQ_EXT_FIRST (8) + +`define WATCHDOG_CTRL 8'h20 + `define WATCHDOG_EXPIRED (16) + +`define SYS_CLK_COUNT 8'h60 + +// SPI Configuration PROM +`define SPI_PROM_CTRL 8'h70 +`define SPI_PROM_STAT 8'h70 +`define SPI_PROM_DATA 8'h74 Index: trunk/rtl/soc/alt_soc_conf.v =================================================================== --- trunk/rtl/soc/alt_soc_conf.v (nonexistent) +++ trunk/rtl/soc/alt_soc_conf.v (revision 5) @@ -0,0 +1,46 @@ +//----------------------------------------------------------------- +// AltOR32 +// Alternative Lightweight OpenRisc +// 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 +//----------------------------------------------------------------- + +//----------------------------------------------------------------- +// Configuration +//----------------------------------------------------------------- +//`define SOC_CONF_ENABLE_WATCHDOG +`define SOC_CONF_ENABLE_SPI_FLASH \ No newline at end of file Index: trunk/rtl/soc =================================================================== --- trunk/rtl/soc (nonexistent) +++ trunk/rtl/soc (revision 5)
trunk/rtl/soc Property changes : Added: bugtraq:number ## -0,0 +1 ## +true \ No newline at end of property Index: trunk/rtl/peripheral/uart.v =================================================================== --- trunk/rtl/peripheral/uart.v (nonexistent) +++ trunk/rtl/peripheral/uart.v (revision 5) @@ -0,0 +1,285 @@ +//----------------------------------------------------------------- +// AltOR32 +// Alternative Lightweight OpenRisc +// 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); + 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); + 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); + tx_count <= FULL_BIT; + end + end + end +end + +//----------------------------------------------------------------- +// Combinatorial +//----------------------------------------------------------------- +assign tx_busy_o = (tx_busy | tx_buf_full | wr_i); + +endmodule Index: trunk/rtl/peripheral/spi_master.v =================================================================== --- trunk/rtl/peripheral/spi_master.v (nonexistent) +++ trunk/rtl/peripheral/spi_master.v (revision 5) @@ -0,0 +1,215 @@ +//----------------------------------------------------------------- +// AltOR32 +// Alternative Lightweight OpenRisc +// 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: trunk/rtl/peripheral =================================================================== --- trunk/rtl/peripheral (nonexistent) +++ trunk/rtl/peripheral (revision 5)
trunk/rtl/peripheral Property changes : Added: bugtraq:number ## -0,0 +1 ## +true \ No newline at end of property

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.