diff --git a/verilog/dv/cocotb/caravel_tests.py b/verilog/dv/cocotb/caravel_tests.py index 2dfe83e6..0fd19184 100644 --- a/verilog/dv/cocotb/caravel_tests.py +++ b/verilog/dv/cocotb/caravel_tests.py @@ -42,7 +42,7 @@ from tests.timer.timer import * from tests.uart.uart import * from tests.spi_master.spi_master import * from tests.logicAnalyzer.la import * - +from tests.debug.debug import * # archive tests diff --git a/verilog/dv/cocotb/tests.json b/verilog/dv/cocotb/tests.json index a37326a1..f8d697a8 100644 --- a/verilog/dv/cocotb/tests.json +++ b/verilog/dv/cocotb/tests.json @@ -283,5 +283,11 @@ "GL":["r_gl","nightly","weekly","tape_out"], "GL_SDF":["r_sdf","weekly","tape_out"], "description":"check logic analyzer input and output enable"} + ,"debug" :{"level":0, + "SW":true, + "RTL":[], + "GL":[], + "GL_SDF":[], + "description":""} } } \ No newline at end of file diff --git a/verilog/dv/cocotb/tests/debug/debug.c b/verilog/dv/cocotb/tests/debug/debug.c new file mode 100644 index 00000000..3c0e16b5 --- /dev/null +++ b/verilog/dv/cocotb/tests/debug/debug.c @@ -0,0 +1,72 @@ +/* + * SPDX-FileCopyrightText: 2020 Efabless Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +// -------------------------------------------------------- + +void main() +{ + int j; + reg_wb_enable =1; // for enable writing to reg_debug_1 and reg_debug_2 + reg_debug_1 = 0x0; + reg_debug_2 = 0x0; + + + reg_mprj_io_6 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_5 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; + + // Set clock to 64 kbaud and enable the UART. It is important to do this + // before applying the configuration, or else the Tx line initializes as + // zero, which indicates the start of a byte to the receiver. + + + // Now, apply the configuration + reg_mprj_xfer = 1; + while (reg_mprj_xfer == 1); + // reg_uart_enable = 1; + // start of the test + reg_debug_1 = 0xAA; + // very long wait + for (j = 0; j < 160; j++); + for (j = 0; j < 160; j++); + for (j = 0; j < 160; j++); + + + // Set clock to 64 kbaud and enable the UART. It is important to do this + // before applying the configuration, or else the Tx line initializes as + // zero, which indicates the start of a byte to the receiver. + +// // these instruction work without using interrupt, they seem to be timing dependent +// reg_uart_enable = 1; +// reg_debug_irq_en = 1; +// reg_reset = 1; + + +// irq_setmask(0); +// irq_setie(1); +// irq_setmask(irq_getmask() | (1 << USER_IRQ_3_INTERRUPT)); + +// for (j = 0; j < 500; j++); + +// // reg_uart_data = 0xab; + +// // Allow transmission to complete before signalling that the program +// // has ended. +// for (j = 0; j < 160; j++); +} diff --git a/verilog/dv/cocotb/tests/debug/debug.py b/verilog/dv/cocotb/tests/debug/debug.py new file mode 100644 index 00000000..09a8a479 --- /dev/null +++ b/verilog/dv/cocotb/tests/debug/debug.py @@ -0,0 +1,114 @@ +from curses import baudrate +import random +import cocotb +from cocotb.triggers import FallingEdge,RisingEdge,ClockCycles,Timer,Edge +import cocotb.log +from interfaces.cpu import RiskV +from interfaces.defsParser import Regs +from cocotb.result import TestSuccess +from tests.common_functions.test_functions import * +from tests.bitbang.bitbang_functions import * +from interfaces.caravel import GPIO_MODE +from interfaces.common import Macros + + +bit_time_ns = 0 +reg = Regs() + + +@cocotb.test() +@repot_test +async def debug(dut): + caravelEnv,clock = await test_configure(dut,timeout_cycles=375862) + cpu = RiskV(dut) + cpu.cpu_force_reset() + cpu.cpu_release_reset() + # calculate bit time + clk = clock.period/1000 + global bit_time_ns + bit_time_ns = round(10**5 * clk / (96)) + cocotb.log.info(f"[TEST] bit time in nano second = {bit_time_ns}") + caravelEnv.drive_gpio_in((0,0),0) # IO[0] affects the uart selecting btw system and debug + caravelEnv.drive_gpio_in((5,5),1) + # wait for start of sending + await wait_reg1(cpu,caravelEnv,0XAA) + cocotb.log.info(f"[TEST] Start debug test") + # send random data to address 30'h00400024 and expect to recieve the same data back it back + address = 0x00000410 + data = random.getrandbits(32) + data = 0xFFFFFFFF + cocotb.log.info (f"[TEST] Executing DFF2 write address={hex(address)} data = {hex(data)}") + await wb_write(caravelEnv,address,data) + receieved_data = await wb_read(caravelEnv,address) + if data != receieved_data: + cocotb.log.error(f"[TEST] DFF2 write failed expected data = {hex(data)} recieved data = {hex(receieved_data)}") + else: + cocotb.log.info(f"[TEST] DFF2 write succeeded") + + +async def start_of_tx(caravelEnv): + while (True): # wait for the start of the transimission it 1 then 0 + if (caravelEnv.monitor_gpio((6,6)).integer == 0): + break + await Timer(bit_time_ns, units='ns') + await Timer(bit_time_ns, units='ns') + +async def uart_send_char(caravelEnv,char): + cocotb.log.info (f"[uart_send_char] start sending on uart {char}") + #send start bit + caravelEnv.drive_gpio_in((5,5),0) + await Timer(bit_time_ns, units='ns') + #send bits + for i in range(8): + caravelEnv.drive_gpio_in((5,5),char[i]) + await Timer(bit_time_ns, units='ns') + + # stop of frame + caravelEnv.drive_gpio_in((5,5),1) + await Timer(bit_time_ns, units='ns') + await Timer(bit_time_ns, units='ns') + # insert 4 bit delay just for debugging + await Timer(bit_time_ns, units='ns') + await Timer(bit_time_ns, units='ns') + await Timer(bit_time_ns, units='ns') + await Timer(bit_time_ns, units='ns') + +async def uart_get_char(caravelEnv): + await start_of_tx(caravelEnv) + char = '' + for i in range (8): + char = char + caravelEnv.monitor_gpio((6,6)).binstr + await Timer(bit_time_ns, units='ns') + cocotb.log.info (f"[uart_get_char] recieving {char} from uart") + + return char + +async def wb_write(caravelEnv,addr,data): + addr_bits = bin(addr)[2:].zfill(32)[::-1] + data_bits = bin(data)[2:].zfill(32)[::-1] + cocotb.log.info(f"[TEST] address bits = {addr_bits} {type(addr_bits)}") + await uart_send_char(caravelEnv, '10000000') # write cmd + await uart_send_char(caravelEnv, '10000000') # size + await uart_send_char(caravelEnv, addr_bits[24:32]) + await uart_send_char(caravelEnv, addr_bits[16:24]) + await uart_send_char(caravelEnv, addr_bits[8:16]) + await uart_send_char(caravelEnv, addr_bits[0:8]) + await uart_send_char(caravelEnv, data_bits[24:32]) + await uart_send_char(caravelEnv, data_bits[16:24]) + await uart_send_char(caravelEnv, data_bits[8:16]) + await uart_send_char(caravelEnv, data_bits[0:8]) + + +async def wb_read(caravelEnv,addr): + addr_bits = bin(addr)[2:].zfill(32)[::-1] + await uart_send_char(caravelEnv, '01000000') # read cmd + await uart_send_char(caravelEnv, '10000000') # size + await uart_send_char(caravelEnv, addr_bits[24:32]) + await uart_send_char(caravelEnv, addr_bits[16:24]) + await uart_send_char(caravelEnv, addr_bits[8:16]) + await uart_send_char(caravelEnv, addr_bits[0:8]) + data_bits = await uart_get_char(caravelEnv) + data_bits += await uart_get_char(caravelEnv) + data_bits += await uart_get_char(caravelEnv) + data_bits += await uart_get_char(caravelEnv) + return int(data_bits,2)