Skip to content

Commit

Permalink
Merge pull request #184 from GreenWaves-Technologies/3.8.0_dev
Browse files Browse the repository at this point in the history
3.8 release updates
  • Loading branch information
Yaooooo authored Dec 1, 2020
2 parents f0cf9a3 + b706c70 commit 3cf3519
Show file tree
Hide file tree
Showing 101 changed files with 800 additions and 11,315 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@ BUILD
junit-reports/
/rtos/pulp/archi/
/rtos/pulp/hal/
*.a
.tiler_url

7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,16 @@

The GAP8 SDK allows you to compile and execute applications on the GAP8 IoT Application Processor. This SDK is an extract of the necessary elements from the pulp-sdk (https://github.com/pulp-platform/pulp-sdk) produced by the PULP project, to provide a development environment for the GAP8 series processors.

We provide you with all the necessary tools and two different operating systems for GAP8:
We provide you with a set of tool and two different operating systems for GAP8:

* Tools
* [Tools](https://greenwaves-technologies.com/tools-and-software/)
- GAP8 RISCV GNU toolchain: a pre-compiled toolchain inherited from RISC V project with support for our extensions to the RISC-V Instruction Set Architecture.
* Program / control GAP8
* Debug your application using GDB
* Program the GAPuino flash memory with applications
- [NNTOOL](https://github.com/GreenWaves-Technologies/gap_sdk/blob/master/tools/nntool/README.md): a set of tool based on python helps to port NN graphs from various NN training packages to GAP8
- [Autotiler](https://greenwaves-technologies.com/manuals/BUILD/AUTOTILER/html/index.html): a code generator for GAP8, which can generate a user algorithm (CNN, MatrixAdd, MatrixMult, FFT, MFCC, etc) with optimized memory management.
- gapy: a set of tool based on python for building the flashimage, creating partitions, creating FS, executing the openOCD, etc.

* Operating Systems
- PULP OS - The open source embedded RTOS produced by the PULP project
Expand Down
4 changes: 2 additions & 2 deletions gvsoc/gvsoc/engine/src/vp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1206,8 +1206,8 @@ void vp::reg::init(vp::component *top, std::string name, int bits, uint8_t *valu
this->name = name;
if (reset_value)
memcpy((void *)this->reset_value_bytes, (void *)reset_value, this->nb_bytes);
top->traces.new_trace(name, &this->trace, vp::TRACE);
top->traces.new_trace_event(name + "/vcd", &this->reg_event, bits);
top->traces.new_trace(name + "/trace", &this->trace, vp::TRACE);
top->traces.new_trace_event(name, &this->reg_event, bits);
}

void vp::reg::reset(bool active)
Expand Down
4 changes: 4 additions & 0 deletions gvsoc/gvsoc/models/cpu/iss/include/irq.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ static inline void iss_irq_check(iss_t *iss)
iss_msg(iss, "Interrupting pending elw\n");
iss->cpu.current_insn = iss->cpu.state.elw_insn;
iss->cpu.state.elw_insn = NULL;
// Keep the information that we interrupted it, so that features like HW loop
// knows that the instruction is being replayed
iss->cpu.state.elw_interrupted = 1;
}

iss->cpu.csr.epc = iss->cpu.current_insn->addr;
Expand Down Expand Up @@ -130,6 +133,7 @@ static inline void iss_irq_build(iss_t *iss)

static inline void iss_irq_init(iss_t *iss)
{
iss->cpu.state.elw_interrupted = 0;
iss->cpu.irq.irq_enable = 0;
iss->cpu.irq.req_irq = -1;
iss->cpu.irq.req_debug = false;
Expand Down
31 changes: 29 additions & 2 deletions gvsoc/gvsoc/models/cpu/iss/include/pulp_v2.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -539,18 +539,36 @@ static inline iss_insn_t *hwloop_check_exec(iss_t *iss, iss_insn_t *insn)
{
iss_reg_t pc = insn->addr;

// Check now is the instruction has been replayed to know if it is the first
// time it is executed
bool elw_interrupted = iss->cpu.state.elw_interrupted;

// First execute the instructions as it is the last one of the loop body.
// The real handler has been saved when the loop was started.
iss_insn_t *insn_next = iss_exec_insn_handler(iss, insn, insn->hwloop_handler);

if (elw_interrupted)
{
// This flag is 1 when the instruction has been previously interrupted and is now
// being replayed. In this case, return the instruction which has been computed
// during the first execution of the instruction, to avoid accounting several
// times the end of HW loop.
return iss->cpu.state.hwloop_next_insn;
}

// First check HW loop 0 as it has higher priority compared to HW loop 1
if (iss->cpu.pulpv2.hwloop_regs[PULPV2_HWLOOP_LPCOUNT0] && iss->cpu.pulpv2.hwloop_regs[PULPV2_HWLOOP_LPEND0] == pc)
{
iss->cpu.pulpv2.hwloop_regs[PULPV2_HWLOOP_LPCOUNT0]--;
iss_decoder_msg(iss, "Reached end of HW loop (index: 0, loop count: %d)\n", iss->cpu.pulpv2.hwloop_regs[PULPV2_HWLOOP_LPCOUNT0]);

// If counter is not zero, we must jump back to beginning of the loop.
if (iss->cpu.pulpv2.hwloop_regs[PULPV2_HWLOOP_LPCOUNT0]) return iss->cpu.state.hwloop_start_insn[0];
if (iss->cpu.pulpv2.hwloop_regs[PULPV2_HWLOOP_LPCOUNT0])
{
// Remember next instruction in case the current instruction is replayed
iss->cpu.state.hwloop_next_insn = iss->cpu.state.hwloop_start_insn[0];
return iss->cpu.state.hwloop_start_insn[0];
}
}

// We get here either if HW loop 0 was not active or if the counter reached 0.
Expand All @@ -560,10 +578,17 @@ static inline iss_insn_t *hwloop_check_exec(iss_t *iss, iss_insn_t *insn)
iss->cpu.pulpv2.hwloop_regs[PULPV2_HWLOOP_LPCOUNT1]--;
// If counter is not zero, we must jump back to beginning of the loop.
iss_decoder_msg(iss, "Reached end of HW loop (index: 1, loop count: %d)\n", iss->cpu.pulpv2.hwloop_regs[PULPV2_HWLOOP_LPCOUNT1]);
if (iss->cpu.pulpv2.hwloop_regs[PULPV2_HWLOOP_LPCOUNT1]) return iss->cpu.state.hwloop_start_insn[1];
if (iss->cpu.pulpv2.hwloop_regs[PULPV2_HWLOOP_LPCOUNT1])
{
// Remember next instruction in case the current instruction is replayed
iss->cpu.state.hwloop_next_insn = iss->cpu.state.hwloop_start_insn[1];
return iss->cpu.state.hwloop_start_insn[1];
}
}

// In case no HW loop jumped back, just continue with the next instruction.
iss->cpu.state.hwloop_next_insn = insn_next;

return insn_next;
}

Expand Down Expand Up @@ -726,6 +751,8 @@ static inline iss_insn_t *p_elw_exec(iss_t *iss, iss_insn_t *insn)
{
uint32_t value = 0;
iss->cpu.state.elw_insn = insn;
// Init this flag so that we can check afterwards that theelw has been replayed
iss->cpu.state.elw_interrupted = 0;
iss_lsu_elw_perf(iss, insn, REG_GET(0) + SIM_GET(0), 4, REG_OUT(0));
if (iss->cpu.state.insn_cycles != -1)
iss->cpu.state.elw_insn = NULL;
Expand Down
2 changes: 2 additions & 0 deletions gvsoc/gvsoc/models/cpu/iss/include/types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,8 @@ typedef struct iss_cpu_state_s {
iss_reg_t vf1;

iss_insn_t *elw_insn;
int elw_interrupted;
iss_insn_t *hwloop_next_insn;

iss_fcsr_t fcsr;

Expand Down
4 changes: 3 additions & 1 deletion gvsoc/gvsoc/models/cpu/iss/src/iss.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ void iss_reset(iss_t *iss, int active)
{
for (int i=0; i<ISS_NB_TOTAL_REGS; i++)
{
iss->cpu.regfile.regs[i] = 0;
iss->cpu.regfile.regs[i] = i == 0 ? 0 : 0x57575757;
}

iss_cache_flush(iss);
Expand All @@ -284,6 +284,8 @@ int iss_open(iss_t *iss)

iss->cpu.regfile.regs[0] = 0;
iss->cpu.current_insn = NULL;
iss->cpu.stall_insn = NULL;
iss->cpu.prev_insn = NULL;
iss->cpu.state.fetch_cycles = 0;

iss_irq_build(iss);
Expand Down
12 changes: 6 additions & 6 deletions gvsoc/gvsoc/models/cpu/iss/src/trace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ static char *trace_dump_debug(iss_t *iss, iss_insn_t *insn, char *buff)
return buff + MAX_DEBUG_INFO_WIDTH + 1;
}

static void iss_trace_dump_insn(iss_t *iss, iss_insn_t *insn, char *buff, int buffer_size, iss_insn_arg_t *saved_args, bool is_long, int mode) {
static void iss_trace_dump_insn(iss_t *iss, iss_insn_t *insn, char *buff, int buffer_size, iss_insn_arg_t *saved_args, bool is_long, int mode, bool is_event) {

char *init_buff = buff;
static int max_len = 20;
Expand All @@ -318,7 +318,7 @@ static void iss_trace_dump_insn(iss_t *iss, iss_insn_t *insn, char *buff, int bu
buff = trace_dump_debug(iss, insn, buff);
}

if (1) {
if (!is_event) {
buff += sprintf(buff, "%c %" PRIxFULLREG " ", iss_trace_get_mode(mode), insn->addr);
}

Expand Down Expand Up @@ -349,7 +349,7 @@ static void iss_trace_dump_insn(iss_t *iss, iss_insn_t *insn, char *buff, int bu
}
if (nb_args != 0) buff += sprintf(buff, " ");

if (1) {
if (!is_event) {
len = buff - start_buff;

if (len > max_arg_len) max_arg_len = len;
Expand All @@ -360,7 +360,7 @@ static void iss_trace_dump_insn(iss_t *iss, iss_insn_t *insn, char *buff, int bu
}
}

if (1)
if (!is_event)
{
prev_arg = NULL;
for (int i=0; i<nb_args; i++) {
Expand Down Expand Up @@ -426,7 +426,7 @@ void iss_trace_dump(iss_t *iss, iss_insn_t *insn)

iss_trace_save_args(iss, insn, iss->cpu.state.saved_args, true);

iss_trace_dump_insn(iss, insn, buffer, 1024, iss->cpu.state.saved_args, iss_trace_format(iss) == TRACE_FORMAT_LONG, 3);
iss_trace_dump_insn(iss, insn, buffer, 1024, iss->cpu.state.saved_args, iss_trace_format(iss) == TRACE_FORMAT_LONG, 3, 0);

iss_insn_msg(iss, buffer);
}
Expand All @@ -435,7 +435,7 @@ void iss_event_dump(iss_t *iss, iss_insn_t *insn)
{
char buffer[1024];

iss_trace_dump_insn(iss, insn, buffer, 1024, iss->cpu.state.saved_args, false, 3);
iss_trace_dump_insn(iss, insn, buffer, 1024, iss->cpu.state.saved_args, false, 3, 1);

char *current = buffer;
while (*current)
Expand Down
3 changes: 3 additions & 0 deletions gvsoc/gvsoc/models/cpu/iss/vp/include/iss_wrapper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class iss_wrapper : public vp::component
void exec_first_instr(vp::clock_event *event);
static void exec_instr_check_all(void *__this, vp::clock_event *event);
static inline void exec_misaligned(void *__this, vp::clock_event *event);
static inline void irq_req_sync_handler(void *__this, vp::clock_event *event);

static void irq_req_sync(void *__this, int irq);
void debug_req();
Expand Down Expand Up @@ -152,8 +153,10 @@ class iss_wrapper : public vp::component
vp::clock_event *instr_event;
vp::clock_event *check_all_event;
vp::clock_event *misaligned_event;
vp::clock_event *irq_sync_event;

int irq_req;
int irq_req_value;

bool iss_opened;
int halt_cause;
Expand Down
21 changes: 18 additions & 3 deletions gvsoc/gvsoc/models/cpu/iss/vp/src/iss_wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -508,16 +508,29 @@ void iss_wrapper::wait_for_interrupt()
}


void iss_wrapper::irq_req_sync(void *__this, int irq)
void iss_wrapper::irq_req_sync_handler(void *__this, vp::clock_event *event)
{
iss_t *_this = (iss_t *)__this;
_this->irq_req = irq;
_this->irq_req = _this->irq_req_value;
_this->irq_check();
iss_irq_req(_this, irq);
iss_irq_req(_this, _this->irq_req);
_this->wfi.set(false);
_this->check_state();
}


void iss_wrapper::irq_req_sync(void *__this, int irq)
{
iss_t *_this = (iss_t *)__this;
_this->irq_req_value = irq;
// Handle the sync in an event with 0 delay to always take into account interrupts after the
// instruction has been executed
if (!_this->irq_sync_event->is_enqueued())
{
_this->event_enqueue(_this->irq_sync_event, 0);
}
}

void iss_wrapper::debug_req()
{
this->cpu.irq.req_debug = true;
Expand Down Expand Up @@ -1125,6 +1138,7 @@ int iss_wrapper::build()
instr_event = event_new(iss_wrapper::exec_instr);
check_all_event = event_new(iss_wrapper::exec_instr_check_all);
misaligned_event = event_new(iss_wrapper::exec_misaligned);
irq_sync_event = event_new(iss_wrapper::irq_req_sync_handler);

this->riscv_dbg_unit = this->get_js_config()->get_child_bool("riscv_dbg_unit");
this->bootaddr_offset = get_config_int("bootaddr_offset");
Expand Down Expand Up @@ -1200,6 +1214,7 @@ void iss_wrapper::reset(bool active)

this->ipc_stat_nb_insn = 0;
this->ipc_stat_delay = 10;
this->clock_active = false;

iss_reset(this, 1);
}
Expand Down
Loading

0 comments on commit 3cf3519

Please sign in to comment.