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

Subversion Repositories openrisc

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /openrisc/trunk
    from Rev 499 to Rev 500
    Reverse comparison

Rev 499 → Rev 500

/orpsocv2/bench/sysc/include/UartSC.h
42,16 → 42,27
sc_out < bool > uartrx;
 
// Init function
void initUart(int clk_freq_hz, int uart_baud);
void initUart(int uart_baud);
// Transmit (from ORPSoC) handling function
void checkTx();
// Receieve (in ORPSoC) generation function
void driveRx();
// Check keyboard for entry
int kbhit();
// Enable canonical mode on console
void nonblock(int state);
 
private:
int clocks_per_bit;
uint8_t current_char;
int counter;
int bits_received;
int ns_per_bit;
 
int rx_state;
int rx_counter;
int rx_bits_sent;
char rx_char;
 
}; // UartSC ()
 
#endif // UART_SC__H
/orpsocv2/bench/sysc/src/UartSC.cpp
24,12 → 24,18
 
#include <iostream>
#include <iomanip>
#include <cmath>
 
#include "UartSC.h"
 
//#define UART_SC_DEBUG
 
// Keep disabled for now, to stop any portability problems cropping up.
//#define UART_SC_STDIN_ENABLE
 
#ifdef UART_SC_STDIN_ENABLE
#include <termios.h>
#endif
 
SC_HAS_PROCESS(UartSC);
 
//! Constructor for the Uart system C model
37,83 → 43,215
//! @param[in] name Name of this module, passed to the parent constructor.
// Todo: Probably some sort of scaler parameter
 
UartSC::UartSC(sc_core::sc_module_name name):
sc_module(name)
UartSC::UartSC(sc_core::sc_module_name uart):
sc_module(uart)
{
 
SC_METHOD(checkTx);
#ifdef UART_SC_STDIN_ENABLE
SC_THREAD(driveRx);
#endif
SC_THREAD(checkTx);
dont_initialize();
sensitive << clk.pos();
//sensitive << uarttx;
sensitive << uarttx;
 
} // UartSC ()
 
void
UartSC::initUart(int clk_freq_hz, // Presume in NS
int uart_baud)
UartSC::initUart(int uart_baud)
{
// Calculate number of clocks per UART bit
clocks_per_bit = (int)(clk_freq_hz / uart_baud);
// Calculate number of ns per UART bit
ns_per_bit = (int) ((long long)1000000000/(long long)uart_baud);
bits_received = 0;
 
// Init state of RX
rx_state = 0;
// Set input, ORPSoC's RX, line to high
uartrx.write(true);
 
#ifdef UART_SC_DEBUG
printf
("UartSC Initialised: Sys. clk. freq.: %d Hz, Baud: %d, cpb: %d\n",
clk_freq_hz, uart_baud, clocks_per_bit);
("UartSC Initialised: Baud: %d, ns per bit: %d\n",
uart_baud, ns_per_bit);
#endif
}
 
// Maybe do this with threads instead?!
void UartSC::checkTx()
// Some C from
// http://cc.byexamples.com/2007/04/08/non-blocking-user-input-in-loop-without-ncurses/
//
int UartSC::kbhit()
{
#ifdef UART_SC_STDIN_ENABLE
struct timeval tv;
fd_set fds;
tv.tv_sec = 0;
tv.tv_usec = 0;
FD_ZERO(&fds);
FD_SET(STDIN_FILENO, &fds); //STDIN_FILENO is 0
select(STDIN_FILENO+1, &fds, NULL, NULL, &tv);
return FD_ISSET(STDIN_FILENO, &fds);
#else
return 0;
#endif
}
 
#define NB_ENABLE 1
#define NB_DISABLE 0
 
// The following is apparently VERY Linux-centric. Maybe a ncurses version could
// be handy if this gets used on various platforms.
void UartSC::nonblock(int state)
{
#ifdef UART_SC_STDIN_ENABLE
struct termios ttystate;
//get the terminal state
tcgetattr(STDIN_FILENO, &ttystate);
if (state==NB_ENABLE)
{
//turn off canonical mode
ttystate.c_lflag &= ~ICANON;
//minimum of number input read.
ttystate.c_cc[VMIN] = 1;
}
else if (state==NB_DISABLE)
{
//turn on canonical mode
ttystate.c_lflag |= ICANON;
}
//set the terminal attributes.
tcsetattr(STDIN_FILENO, TCSANOW, &ttystate);
#endif
}
 
 
 
void UartSC::driveRx()
{
static char c;
 
UartSC::nonblock(NB_ENABLE);
 
while(1)
{
if (rx_state == 0) // Waiting for a character input from user
{
 
// Do we have a character on input?
//c=cin.peek();
 
if (kbhit())
{
c = fgetc(stdin);
#ifdef UART_SC_DEBUG
//printf("Uart TX activity: level is : 0x%x\n", uarttx.read()&1);
cout << "UartSC::driveRX got " << c << endl;
#endif
rx_state++;
}
 
// Check the number of bits received
if (bits_received == 0) {
// Check if tx is low
if ((uarttx.read() & 1) == 0) {
// Line pulled low, begin receive of new char
current_char = 0;
// Start
counter = 1;
bits_received++; // We got the start bit
wait(1000000, SC_NS);
 
}
else if (rx_state == 1)
{
#ifdef UART_SC_DEBUG
cout << "UartSC checkTx: got start bit at time " <<
sc_time_stamp() << endl;
cout << "UartSC::driveRX start-bit " << c << endl;
#endif
// Start bit - low
uartrx.write(false);
rx_state++;
// Wait a bit
wait(ns_per_bit, SC_NS);
}
} else if (bits_received > 0 && bits_received < 9) {
// Check the counter - see if it's time to sample the line
// We do an extra half-bit delay on first bit read
if (((bits_received == 1) &&
(counter == (clocks_per_bit + (clocks_per_bit / 2)))) ||
((bits_received > 1) && (counter == clocks_per_bit))) {
//printf("UartSC checkTx: read bit %d as 0x%x at time", bits_received, uarttx.read()&1);
//cout << sc_time_stamp() << endl;
else if (rx_state > 1 && rx_state < 10)
{
#ifdef UART_SC_DEBUG
cout << "UartSC::driveRX bit " << rx_state-2 << " " <<
(c & (1 << rx_state-2)) << endl;
#endif
 
// Shift in the current value of the tx into our char
current_char |=
((uarttx.read() & 1) << (bits_received - 1));
// Reset the counter
counter = 1;
if (c & (1 << rx_state-2))
uartrx.write(true);
else
uartrx.write(false);
rx_state++;
// Wait a bit
wait(ns_per_bit, SC_NS);
}
else if (rx_state == 10)
{
#ifdef UART_SC_DEBUG
cout << "UartSC::driveRX stop bit" << endl;
#endif
rx_state = 0;
// Stop bit
uartrx.write(true);
// Wait a bit
wait(ns_per_bit + (ns_per_bit/2), SC_NS);
}
}
}
 
 
// Maybe do this with threads instead?!
void UartSC::checkTx()
{
while(1){
 
// Check the number of bits received
if (bits_received == 0) {
// Check if tx is low
if ((uarttx.read() & 1) == 0) {
// Line pulled low, begin receive of new char
current_char = 0;
//counter = 1;
 
bits_received++; // We got the start bit
// Now wait until next bit
wait(ns_per_bit, SC_NS);
#ifdef UART_SC_DEBUG
cout << "UartSC checkTx: got start bit at time "
<< sc_time_stamp() << endl;
#endif
}
else
// Nothing yet - keep waiting
wait(ns_per_bit/2, SC_NS);
 
} else if (bits_received > 0 && bits_received < 9) {
current_char |= ((uarttx.read() & 1) <<
(bits_received - 1));
// Increment bit number
bits_received++;
} else
counter++;
} else if (bits_received == 9) {
// Now check for stop bit 1
if (counter == clocks_per_bit) {
// Check that the value is 1 - this should be the stop bit
 
// Wait for next bit
wait(ns_per_bit, SC_NS);
} else if (bits_received == 9) {
 
// Now check for stop bit 1
if ((uarttx.read() & 1) != 1) {
printf("UART TX framing error at time\n");
cout << sc_time_stamp() << endl;
 
// Perhaps do something else here to deal with this
// Perhaps do something else here to deal with
// this.
bits_received = 0;
counter = 0;
} else {
}
else
{
// Print the char
#ifdef UART_SC_DEBUG
printf("Char received: 0x%2x time: ",
120,14 → 258,13
current_char);
cout << sc_time_stamp() << endl;
#endif
// cout'ing the char didn't work for some systems - jb 090613ol
// cout'ing the char didn't work for some
// systems.
//cout << current_char;
printf("%c", current_char);
 
bits_received = 0;
counter = 0;
}
} else
counter++;
}
}
}
/orpsocv2/bench/sysc/src/OrpsocMain.cpp
355,7 → 355,7
 
#ifdef UART0
// Init the UART function
uart->initUart(50000000, 115200);
uart->initUart(115200);
#endif
 
if (do_program_file_load) // Did the user specify a file to load?
/orpsocv2/sim/bin/Makefile
428,7 → 428,7
 
# This file name corresponds to the VMEM file the RAM models will attempt to
# load via $readmemh().
SIM_VMEM_IMAGE ?=sram.vmem
SIM_DIR_VMEM_IMAGE ?=sram.vmem
 
ifeq ($(USER_ELF),)
ELF_FILE=$(TEST_SW_DIR)/$(TEST).elf
448,12 → 448,12
# If USER_ELF was specified, then we need a slightly different way of
# generating the VMEM file from it than a usual test
ifeq ($(USER_ELF),)
$(SIM_VMEM_IMAGE): $(VMEM_FILE)
$(SIM_DIR_VMEM_IMAGE): $(VMEM_FILE)
$(Q)if [ -L $@ ]; then unlink $@; fi
$(Q)if [ -e $@ ]; then rm $@; fi
$(Q)ln -s $< $@
else
$(SIM_VMEM_IMAGE): $(USER_ELF)
$(SIM_DIR_VMEM_IMAGE): $(USER_ELF)
$(Q)$(MAKE) -C $(SW_DIR)/lib \
USER_ELF_BIN=`pwd`/$(ELF_FILE_NOTDIR_BASENAME).bin \
USER_ELF_VMEM=`pwd`/$(ELF_FILE_NOTDIR_BASENAME).vmem \
468,7 → 468,7
USER_VMEM_NOTDIR=$(notdir $(USER_VMEM))
TEST=$(basename $(USER_VMEM_NOTDIR))
 
$(SIM_VMEM_IMAGE): $(VMEM_FILE)
$(SIM_DIR_VMEM_IMAGE): $(VMEM_FILE)
cp -v $< $@
 
endif
477,7 → 477,7
 
 
.PHONY : sw-vmem sw-elf
sw-vmem: $(SIM_VMEM_IMAGE)
sw-vmem: $(SIM_DIR_VMEM_IMAGE)
 
$(TEST_SW_DIR)/$(TEST).vmem:
$(Q) echo; echo "\t### Compiling software ###"; echo;
535,7 → 535,7
$(Q)rm -f $(TEST_DEFINES_VLG)
 
clean-sim-test-sw:
$(Q)if [ -L $(SIM_VMEM_IMAGE) ]; then unlink $(SIM_VMEM_IMAGE); fi
$(Q)if [ -L $(SIM_DIR_VMEM_IMAGE) ]; then unlink $(SIM_DIR_VMEM_IMAGE); fi
 
clean-sw:
$(Q) echo; echo "\t### Cleaning simulation sw directories ###"; echo;
/orpsocv2/boards/xilinx/ml501/sim/bin/Makefile
432,7 → 432,7
 
 
.PHONY: rtl-test
rtl-test: clean-sim-test-sw sw clean-test-defines $(TEST_DEFINES_VLG) \
rtl-test: clean-sim-test-sw sw-vmem clean-test-defines $(TEST_DEFINES_VLG) \
$(SIMULATOR)
 
# Run an RTL test followed by checking of generated results
480,13 → 480,13
BOARD_SW_TEST_DIR=$(BOARD_SW_DIR)/tests/$(TEST_MODULE)/sim
COMMON_SW_TEST_DIR=$(COMMON_SW_DIR)/tests/$(TEST_MODULE)/sim
# Do this by testing for the file's existence
SW_TEST_DIR=$(shell if [ -e $(BOARD_SW_TEST_DIR)/$(TEST).[cS] ]; then echo $(BOARD_SW_TEST_DIR); else echo $(COMMON_SW_TEST_DIR); fi)
TEST_SW_DIR=$(shell if [ -e $(BOARD_SW_TEST_DIR)/$(TEST).[cS] ]; then echo $(BOARD_SW_TEST_DIR); else echo $(COMMON_SW_TEST_DIR); fi)
 
print-test-sw-dir:
@echo; echo "\tTest software is in the following path"; echo;
@echo $(BOARD_SW_DIR); echo;
@echo $(BOARD_SW_TEST_DIR); echo;
@echo $(SW_TEST_DIR); echo;
@echo $(TEST_SW_DIR); echo;
 
print-sw-tests:
$(Q) $(MAKE) -C $(COMMON_SW_DIR)/lib print-sw-tests
499,44 → 499,88
# Set PRELOAD_RAM=1 to preload the system memory - be sure the bootROM program
# chosen in board.h is the one booting from the reset vector.
ifeq ($(PRELOAD_RAM), 1)
SIM_SW_IMAGE ?=sram.vmem
SIM_DIR_VMEM_IMAGE ?=sram.vmem
else
SIM_SW_IMAGE ?=flash.in
SIM_DIR_VMEM_IMAGE ?=flash.in
endif
 
# Amount to pad the image we'll load into the SPI flash
HEX_IMAGE_PADDING ?=0x1c0000
# Ability to bypass all stuffing around involved with generating software and
# directly specify an ELF
ifeq ($(USER_ELF),)
ELF_FILE=$(TEST_SW_DIR)/$(TEST).elf
else
ELF_FILE=$(USER_ELF)
ELF_FILE_NOTDIR=$(notdir $(USER_ELF))
ELF_FILE_NOTDIR_BASENAME=$(basename $(ELF_FILE_NOTDIR))
endif
 
.PHONY : sw
sw: $(SIM_SW_IMAGE)
 
# Rules allowing user to specify a pre-existing VMEM file to load into the
# simulation, instead of compiling a test.
ifeq ($(USER_VMEM),)
 
flash.in: $(SW_TEST_DIR)/$(TEST).flashin
$(Q)if [ -L $@ ]; then unlink $@; fi
$(Q)ln -s $< $@
 
sram.vmem: $(SW_TEST_DIR)/$(TEST).vmem
ifeq ($(PRELOAD_RAM), 1)
VMEM_FILE ?= $(TEST_SW_DIR)/$(TEST).vmem
else
VMEM_FILE ?= $(TEST_SW_DIR)/$(TEST).flashin
endif
.PHONY: $(VMEM_FILE)
 
 
# If USER_ELF was specified, then we need a slightly different way of
# generating the VMEM file from it than a usual test
ifeq ($(USER_ELF),)
$(SIM_DIR_VMEM_IMAGE): $(VMEM_FILE)
$(Q)if [ -L $@ ]; then unlink $@; fi
$(Q)if [ -e $@ ]; then rm $@; fi
$(Q)ln -s $< $@
else # !($(USER_ELF),) - USER_ELF set on command line
$(SIM_DIR_VMEM_IMAGE): $(USER_ELF)
$(Q)$(MAKE) -C $(COMMON_SW_DIR)/lib \
USER_ELF_BIN=`pwd`/$(ELF_FILE_NOTDIR_BASENAME).bin \
USER_ELF_VMEM=`pwd`/$(ELF_FILE_NOTDIR_BASENAME).vmem \
gen-user-elf-vmem
$(Q)cp -v $(ELF_FILE_NOTDIR_BASENAME).vmem $@
 
.PHONY: $(SW_TEST_DIR)/$(TEST).flashin
$(SW_TEST_DIR)/$(TEST).flashin:
TEST=$(ELF_FILE_NOTDIR_BASENAME)
endif
 
else # !($(USER_VMEM),) - USER_VMEM set on command line
VMEM_FILE=$(USER_VMEM)
USER_VMEM_NOTDIR=$(notdir $(USER_VMEM))
TEST=$(basename $(USER_VMEM_NOTDIR))
 
$(SIM_DIR_VMEM_IMAGE): $(VMEM_FILE)
cp -v $< $@
 
endif
 
 
# Amount to pad the image we'll load into the SPI flash for ML501 sims
HEX_IMAGE_PADDING ?=0x1c0000
 
.PHONY : sw-vmem sw-elf
sw-vmem: $(SIM_DIR_VMEM_IMAGE)
 
.PHONY: $(TEST_SW_DIR)/$(TEST).flashin
$(TEST_SW_DIR)/$(TEST).flashin:
$(Q) echo; echo "\t### Compiling software ###"; echo;
$(Q)$(MAKE) -C $(SW_TEST_DIR) $(TEST).flashin \
$(Q)$(MAKE) -C $(TEST_SW_DIR) $(TEST).flashin \
HEX_IMAGE_PADDING=$(HEX_IMAGE_PADDING)
 
.PHONY: $(SW_TEST_DIR)/$(TEST).vmem
$(SW_TEST_DIR)/$(TEST).vmem:
.PHONY: $(TEST_SW_DIR)/$(TEST).vmem
$(TEST_SW_DIR)/$(TEST).vmem:
$(Q) echo; echo "\t### Compiling software ###"; echo;
$(Q)$(MAKE) -C $(SW_TEST_DIR) $(TEST).vmem
$(Q)$(MAKE) -C $(TEST_SW_DIR) $(TEST).vmem
 
# Create test software disassembly
 
sw-dis: $(SW_TEST_DIR)/$(TEST).dis
sw-dis: $(TEST_SW_DIR)/$(TEST).dis
$(Q)cp -v $< .
 
$(SW_TEST_DIR)/$(TEST).dis:
$(Q)$(MAKE) -C $(SW_TEST_DIR) $(TEST).dis
$(TEST_SW_DIR)/$(TEST).dis:
$(Q)$(MAKE) -C $(TEST_SW_DIR) $(TEST).dis
 
#
# Cleaning rules
558,7 → 602,7
$(Q)rm -f $(TEST_DEFINES_VLG)
 
clean-sim-test-sw:
$(Q)if [ -e $(SIM_SW_IMAGE) ]; then unlink $(SIM_SW_IMAGE); fi
$(Q)if [ -L $(SIM_DIR_VMEM_IMAGE) ]; then unlink $(SIM_DIR_VMEM_IMAGE); fi
 
clean-sw:
$(Q) echo; echo "\t### Cleaning simulation sw directories ###"; echo;

powered by: WebSVN 2.1.0

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