summaryrefslogtreecommitdiff
path: root/tb
diff options
context:
space:
mode:
Diffstat (limited to 'tb')
-rw-r--r--tb/avalon.hpp3
-rw-r--r--tb/avalon.impl.hpp3
-rw-r--r--tb/platform.sv119
-rw-r--r--tb/sim/descifrador.S72
-rw-r--r--tb/sim/descifrador.py20
-rw-r--r--tb/sim/smp_boot.S25
-rw-r--r--tb/sim/smp_boot.py4
-rw-r--r--tb/sim/strex.S23
-rw-r--r--tb/sim/strex.py9
-rw-r--r--tb/sim_slave.cpp60
-rw-r--r--tb/sim_slave.hpp36
-rw-r--r--tb/sim_slave.sv28
-rw-r--r--tb/top/conspiracion.cpp44
13 files changed, 326 insertions, 120 deletions
diff --git a/tb/avalon.hpp b/tb/avalon.hpp
index 6c720bc..b184999 100644
--- a/tb/avalon.hpp
+++ b/tb/avalon.hpp
@@ -98,6 +98,9 @@ namespace taller::avalon
inline virtual void tick() noexcept
{}
+ inline virtual void tick_falling() noexcept
+ {}
+
inline virtual void bail() noexcept
{}
diff --git a/tb/avalon.impl.hpp b/tb/avalon.impl.hpp
index efae0b9..12483f9 100644
--- a/tb/avalon.impl.hpp
+++ b/tb/avalon.impl.hpp
@@ -120,6 +120,9 @@ namespace taller::avalon
template<class Platform>
void interconnect<Platform>::tick_falling() noexcept
{
+ for (auto &binding : devices)
+ binding.dev.tick_falling();
+
if (!plat.avl_waitrequest)
active = nullptr;
}
diff --git a/tb/platform.sv b/tb/platform.sv
index 13b94d7..bbf1088 100644
--- a/tb/platform.sv
+++ b/tb/platform.sv
@@ -65,13 +65,19 @@ module platform
logic mem_0_waitrequest, mem_1_waitrequest, mem_2_waitrequest, mem_3_waitrequest;
logic[15:0] mem_0_byteenable, mem_1_byteenable, mem_2_byteenable, mem_3_byteenable;
- logic[31:0] cpu_0_address, cpu_1_address, cpu_2_address, cpu_3_address;
- logic cpu_0_read, cpu_1_read, cpu_2_read, cpu_3_read;
- logic cpu_0_write, cpu_1_write, cpu_2_write, cpu_3_write;
- logic cpu_0_lock, cpu_1_lock, cpu_2_lock, cpu_3_lock;
- logic[31:0] cpu_0_readdata, cpu_1_readdata, cpu_2_readdata, cpu_3_readdata;
- logic[31:0] cpu_0_writedata, cpu_1_writedata, cpu_2_writedata, cpu_3_writedata;
- logic cpu_0_waitrequest, cpu_1_waitrequest, cpu_2_waitrequest, cpu_3_waitrequest;
+ logic[31:0] cpu_0_address, cpu_1_address, cpu_2_address, cpu_3_address,
+ dbg_0_address, dbg_1_address, dbg_2_address, dbg_3_address;
+ logic cpu_0_read, cpu_1_read, cpu_2_read, cpu_3_read,
+ dbg_0_read, dbg_1_read, dbg_2_read, dbg_3_read,
+ cpu_0_write, cpu_1_write, cpu_2_write, cpu_3_write,
+ dbg_0_write, dbg_1_write, dbg_2_write, dbg_3_write,
+ cpu_0_lock, cpu_1_lock, cpu_2_lock, cpu_3_lock;
+ logic[31:0] cpu_0_readdata, cpu_1_readdata, cpu_2_readdata, cpu_3_readdata,
+ dbg_0_readdata, dbg_1_readdata, dbg_2_readdata, dbg_3_readdata;
+ logic[31:0] cpu_0_writedata, cpu_1_writedata, cpu_2_writedata, cpu_3_writedata,
+ dbg_0_writedata, dbg_1_writedata, dbg_2_writedata, dbg_3_writedata;
+ logic cpu_0_waitrequest, cpu_1_waitrequest, cpu_2_waitrequest, cpu_3_waitrequest,
+ dbg_0_waitrequest, dbg_1_waitrequest, dbg_2_waitrequest, dbg_3_waitrequest;
logic[1:0] cpu_0_response, cpu_1_response, cpu_2_response, cpu_3_response;
logic[3:0] cpu_0_byteenable, cpu_1_byteenable, cpu_2_byteenable, cpu_3_byteenable;
@@ -196,6 +202,25 @@ module platform
.out_token(token_0),
.out_token_valid(token_valid_0),
+ .dbg_read(dbg_0_read),
+ .dbg_write(dbg_0_write),
+ .dbg_address(dbg_0_address[2:0]),
+ .dbg_readdata(dbg_0_readdata),
+ .dbg_writedata(dbg_0_writedata),
+ .dbg_waitrequest(dbg_0_waitrequest),
+
+ .*
+ );
+
+ sim_slave smp_dbg_0
+ (
+ .read(dbg_0_read),
+ .write(dbg_0_write),
+ .address(dbg_0_address),
+ .readdata(dbg_0_readdata),
+ .writedata(dbg_0_writedata),
+ .waitrequest(dbg_0_waitrequest),
+
.*
);
@@ -233,6 +258,25 @@ module platform
.out_token(token_1),
.out_token_valid(token_valid_1),
+ .dbg_read(dbg_1_read),
+ .dbg_write(dbg_1_write),
+ .dbg_address(dbg_1_address[2:0]),
+ .dbg_readdata(dbg_1_readdata),
+ .dbg_writedata(dbg_1_writedata),
+ .dbg_waitrequest(dbg_1_waitrequest),
+
+ .*
+ );
+
+ sim_slave smp_dbg_1
+ (
+ .read(dbg_1_read),
+ .write(dbg_1_write),
+ .address(dbg_1_address),
+ .readdata(dbg_1_readdata),
+ .writedata(dbg_1_writedata),
+ .waitrequest(dbg_1_waitrequest),
+
.*
);
@@ -270,6 +314,25 @@ module platform
.out_token(token_2),
.out_token_valid(token_valid_2),
+ .dbg_read(dbg_2_read),
+ .dbg_write(dbg_2_write),
+ .dbg_address(dbg_2_address[2:0]),
+ .dbg_readdata(dbg_2_readdata),
+ .dbg_writedata(dbg_2_writedata),
+ .dbg_waitrequest(dbg_2_waitrequest),
+
+ .*
+ );
+
+ sim_slave smp_dbg_2
+ (
+ .read(dbg_2_read),
+ .write(dbg_2_write),
+ .address(dbg_2_address),
+ .readdata(dbg_2_readdata),
+ .writedata(dbg_2_writedata),
+ .waitrequest(dbg_2_waitrequest),
+
.*
);
@@ -307,6 +370,40 @@ module platform
.out_token(token_3),
.out_token_valid(token_valid_3),
+ .dbg_read(dbg_3_read),
+ .dbg_write(dbg_3_write),
+ .dbg_address(dbg_3_address[2:0]),
+ .dbg_readdata(dbg_3_readdata),
+ .dbg_writedata(dbg_3_writedata),
+ .dbg_waitrequest(dbg_3_waitrequest),
+
+ .*
+ );
+
+ sim_slave smp_dbg_3
+ (
+ .read(dbg_3_read),
+ .write(dbg_3_write),
+ .address(dbg_3_address),
+ .readdata(dbg_3_readdata),
+ .writedata(dbg_3_writedata),
+ .waitrequest(dbg_3_waitrequest),
+
+ .*
+ );
+
+ word smp_readdata, smp_writedata;
+ logic smp_read, smp_write;
+
+ sim_slave smp_sim
+ (
+ .read(smp_read),
+ .write(smp_write),
+ .address(),
+ .readdata(smp_readdata),
+ .writedata(smp_writedata),
+ .waitrequest(0),
+
.*
);
@@ -317,10 +414,10 @@ module platform
smp_ctrl smp
(
- .avl_read(0),
- .avl_write(0),
- .avl_writedata(),
- .avl_readdata(),
+ .avl_read(smp_read),
+ .avl_write(smp_write),
+ .avl_writedata(smp_writedata),
+ .avl_readdata(smp_readdata),
.*
);
diff --git a/tb/sim/descifrador.S b/tb/sim/descifrador.S
deleted file mode 100644
index 84b529c..0000000
--- a/tb/sim/descifrador.S
+++ /dev/null
@@ -1,72 +0,0 @@
-.global reset
-reset:
-
-@ IO utilizado:
-@ 5 switches para la llave
-@ 1 switch de selección de algoritmo (xor o not)
-@ 1 botón de inicio
-
-.equ START_BUTTON, 0x30050000 @ Dirección de memoria del botón
-.equ KEY_SWITCHES, 0x30060000 @ Dirección de memoria de los switches
-.equ START, 0x00010000 @ Dirección de memoria de los pixeles
-.equ VRAM, 0x38000000
-
-@ Dirección inicial de lectura, contador y tamaño de la imagen
-ldr r1, =START
-ldr r11, =VRAM
-mov r7, #0x0
-ldr r8, =(640*480)
-
-init:
- ldr r4, [r1], #4 @ Guarda en r4 el dato en la posición de memoria de start
- str r4, [r11], #4 @ Vuelve a guardar en memoria ya modificado
- add r7, r7, #1 @ Incrementa contador de tamaño de la imagen
- cmp r7, r8 @ Compara contador con tamaño de la imagen 640 * 480
- bne init
-
-ldr r1, =START
-ldr r11, =VRAM
-mov r7, #0x0
-
-@Esperar botón
-ldr r2, =START_BUTTON
-ldr r3, =KEY_SWITCHES
-
-idle:
- ldr r5, [r2] @ Lee valor del botón
- ldr r6, [r3] @ Lee valores de los switches
- tst r5, #1 @ Si el botón de inicio es 1, se salta a start
- beq idle
-
-@ Verificar el algoritmo seleccionado
-tst r6, #1 @ Si el valor es 1, se salta a xor, si es 0 a not
-bne xor
-
-@ Recorrer la memoria desde START y hacer not al valor en cada posicion
-@ y volverlo a guardar
-not:
- @Procesar la mask
- ldr r0, =0x00ffffff
- b loop
-
-xor:
-@Procesar la llave
- lsr r9, r6, #1
- mov r0, r9
- orr r0, r0, r9, lsl #8
- orr r0, r0, r9, lsl #16
-
-loop:
- ldr r4, [r1] @ Guarda en r4 el dato en la posición de memoria de start
- eor r4, r4, r0 @ Hace XOR entre r4
- str r4, [r1], #4 @ Vuelve a guardar en memoria ya modificado
- add r7, r7, #1 @ Incrementa contador de tamaño de la imagen
- cmp r7, r8 @ Compara contador con tamaño de la imagen 640 * 480
- bne loop
-
-release:
- ldr r5, [r2] @ Lee valor del botón
- tst r5, #1 @ Si el botón de inicio es 1, se salta a start
- bne release
-
- b reset \ No newline at end of file
diff --git a/tb/sim/descifrador.py b/tb/sim/descifrador.py
deleted file mode 100644
index a77375b..0000000
--- a/tb/sim/descifrador.py
+++ /dev/null
@@ -1,20 +0,0 @@
-LOG = 'image_processing/log'
-FILE = 'image_processing/out_file'
-SIZE = 640 * 480 * 4
-START = 0x10000
-
-loads = {START: FILE}
-consts = {0x30050000: 1, 0x30060000: 0}
-cycles = 23000000
-mem_dumps = [range(START, START + SIZE)]
-enable_video = True
-
-def final():
- words = []
- with open(FILE, 'rb') as file:
- while data := file.read(4):
- words.append(int.from_bytes(data, 'little') ^ 0x00ffffff)
-
- assert_mem(START, words)
- with open(LOG, 'w') as log:
- print(read_mem(START, SIZE), file=log)
diff --git a/tb/sim/smp_boot.S b/tb/sim/smp_boot.S
new file mode 100644
index 0000000..669508b
--- /dev/null
+++ b/tb/sim/smp_boot.S
@@ -0,0 +1,25 @@
+.global reset
+
+reset:
+ adr r0, cpus
+
+.inc_cpus:
+ ldrex r1, [r0]
+ add r1, r1, #1
+ strex r2, r1, [r0]
+ teq r2, #0
+ bne .inc_cpus
+
+ cmp r1, #1
+ movne pc, lr
+
+ ldr r1, =0x30140000
+ ldr r2, [r1]
+ ldr r3, =0x01010100
+ str r3, [r1]
+ ldr r3, [r1]
+.wait:
+ ldr r1, [r0]
+ b .wait
+
+cpus: .word 0
diff --git a/tb/sim/smp_boot.py b/tb/sim/smp_boot.py
new file mode 100644
index 0000000..40c3012
--- /dev/null
+++ b/tb/sim/smp_boot.py
@@ -0,0 +1,4 @@
+def final():
+ assert_reg(r1, 4)
+ assert_reg(r2, 0x01010100)
+ assert_reg(r3, 0)
diff --git a/tb/sim/strex.S b/tb/sim/strex.S
new file mode 100644
index 0000000..575a839
--- /dev/null
+++ b/tb/sim/strex.S
@@ -0,0 +1,23 @@
+.global reset
+
+reset:
+ ldr r0, =0x1000
+ ldr r1, =0x01234567
+ str r1, [r0]
+ mvn r1, r1
+ str r1, [r0, #4]
+ mov r12, lr
+ swi #0
+ mov lr, r12
+ strex r2, r0, [r0] @ Debe fallar
+ ldrex r3, [r0]
+ add r0, r0, #4
+ ldrex r4, [r0]
+ strex r5, r3, [r0] @ Debe fallar
+ sub r0, r0, #4
+ strex r6, r4, [r0] @ Debe servir
+ mov pc, lr
+
+.global swi
+swi:
+ movs pc, lr
diff --git a/tb/sim/strex.py b/tb/sim/strex.py
new file mode 100644
index 0000000..d53c355
--- /dev/null
+++ b/tb/sim/strex.py
@@ -0,0 +1,9 @@
+mem_dumps = [range(0x1000, 0x1008)]
+
+def final():
+ assert_reg(r2, 1)
+ assert_reg(r5, 1)
+ assert_reg(r6, 0)
+
+ assert_mem(0x1000, 0xfedcba98)
+ assert_mem(0x1004, 0x01234567)
diff --git a/tb/sim_slave.cpp b/tb/sim_slave.cpp
new file mode 100644
index 0000000..24528d2
--- /dev/null
+++ b/tb/sim_slave.cpp
@@ -0,0 +1,60 @@
+#include <cstdint>
+
+#include "avalon.hpp"
+#include "sim_slave.hpp"
+
+namespace taller::avalon
+{
+ sim_slave::sim_slave(verilated_slave &dev, std::uint32_t base, std::uint32_t size)
+ : slave(base, size, 4),
+ dev(dev)
+ {
+ dev.avl_read = 0;
+ dev.avl_write = 0;
+ }
+
+ void sim_slave::tick() noexcept
+ {
+ if (latch) {
+ dev.avl_read = 0;
+ dev.avl_write = 0;
+ }
+ }
+
+ void sim_slave::tick_falling() noexcept
+ {
+ if ((dev.avl_read || dev.avl_write) && !dev.avl_waitrequest) {
+ latch = true;
+ latch_readdata = dev.avl_readdata;
+ }
+ }
+
+ bool sim_slave::read(std::uint32_t addr, std::uint32_t &data)
+ {
+ if (latch) {
+ data = latch_readdata;
+
+ latch = false;
+ return true;
+ } else if (!dev.avl_read && !dev.avl_write) {
+ dev.avl_read = 1;
+ dev.avl_address = addr;
+ }
+
+ return false;
+ }
+
+ bool sim_slave::write(std::uint32_t addr, std::uint32_t data, unsigned byte_enable)
+ {
+ if (latch) {
+ latch = false;
+ return true;
+ } else if (!dev.avl_read && !dev.avl_write) {
+ dev.avl_write = 1;
+ dev.avl_address = addr;
+ dev.avl_writedata = data;
+ }
+
+ return false;
+ }
+}
diff --git a/tb/sim_slave.hpp b/tb/sim_slave.hpp
new file mode 100644
index 0000000..cdcea78
--- /dev/null
+++ b/tb/sim_slave.hpp
@@ -0,0 +1,36 @@
+#ifndef TALLER_SIM_SLAVE_HPP
+#define TALLER_SIM_SLAVE_HPP
+
+#include <cstdint>
+
+#include "Vconspiracion_sim_slave.h"
+
+#include "avalon.hpp"
+
+namespace taller::avalon
+{
+ using verilated_slave = Vconspiracion_sim_slave;
+
+ class sim_slave : public slave
+ {
+ public:
+ sim_slave(verilated_slave &dev, std::uint32_t base, std::uint32_t size);
+
+ virtual void tick() noexcept final override;
+ virtual void tick_falling() noexcept final override;
+
+ virtual bool read(std::uint32_t addr, std::uint32_t &data) final override;
+
+ virtual bool write
+ (
+ std::uint32_t addr, std::uint32_t data, unsigned byte_enable = 0b1111
+ ) final override;
+
+ private:
+ verilated_slave &dev;
+ bool latch;
+ std::uint32_t latch_readdata;
+ };
+}
+
+#endif
diff --git a/tb/sim_slave.sv b/tb/sim_slave.sv
new file mode 100644
index 0000000..1598701
--- /dev/null
+++ b/tb/sim_slave.sv
@@ -0,0 +1,28 @@
+module sim_slave
+(
+ input logic clk,
+
+ input logic waitrequest,
+ input logic[31:0] readdata,
+ output logic[31:0] address,
+ writedata,
+ output logic read,
+ write
+);
+
+ logic[31:0] avl_address /*verilator public_flat_rw @(negedge clk)*/;
+ logic avl_read /*verilator public_flat_rw @(negedge clk)*/;
+ logic avl_write /*verilator public_flat_rw @(negedge clk)*/;
+ logic[31:0] avl_readdata /*verilator public*/;
+ logic[31:0] avl_writedata /*verilator public_flat_rw @(negedge clk)*/;
+ logic avl_waitrequest /*verilator public*/;
+
+ assign read = avl_read;
+ assign write = avl_write;
+ assign address = avl_address;
+ assign writedata = avl_writedata;
+
+ assign avl_readdata = readdata;
+ assign avl_waitrequest = waitrequest;
+
+endmodule
diff --git a/tb/top/conspiracion.cpp b/tb/top/conspiracion.cpp
index e28fcfc..00a672e 100644
--- a/tb/top/conspiracion.cpp
+++ b/tb/top/conspiracion.cpp
@@ -17,6 +17,7 @@
#include "Vconspiracion_arm810.h"
#include "Vconspiracion_conspiracion.h"
#include "Vconspiracion_platform.h"
+#include "Vconspiracion_sim_slave.h"
#include "Vconspiracion_vga_domain.h"
#include "Vconspiracion_core.h"
#include "Vconspiracion_core_control.h"
@@ -44,6 +45,7 @@
#include "../jtag_uart.hpp"
#include "../interval_timer.hpp"
#include "../null.hpp"
+#include "../sim_slave.hpp"
#include "../window.hpp"
#include "../vga.hpp"
@@ -331,6 +333,12 @@ int main(int argc, char **argv)
*plat.vga, 0x3800'0000, 25'175'000, 50'000'000
);
+ sim_slave dbg_0(*plat.smp_dbg_0, 0x3010'0000, 32);
+ sim_slave dbg_1(*plat.smp_dbg_1, 0x3011'0000, 32);
+ sim_slave dbg_2(*plat.smp_dbg_2, 0x3012'0000, 32);
+ sim_slave dbg_3(*plat.smp_dbg_3, 0x3013'0000, 32);
+ sim_slave smp_ctrl(*plat.smp_sim, 0x3014'0000, 4);
+
interconnect<Vconspiracion_platform> avl(plat);
//interconnect<Vconspiracion_vga_domain> avl_vga(plat->vga);
@@ -346,24 +354,23 @@ int main(int argc, char **argv)
avl.attach(hps_ddr3);
avl.attach(timer);
avl.attach(ttyJ0);
+ avl.attach(dbg_0);
+ avl.attach(dbg_1);
+ avl.attach(dbg_2);
+ avl.attach(dbg_3);
+ avl.attach(smp_ctrl);
avl.attach_intc(intc);
- for(auto &slave : consts)
- {
+ for (auto &slave : consts)
avl.attach(slave);
- }
- if(enable_fast_video)
- {
+ if (enable_fast_video)
avl.attach(vga);
- } else if(enable_accurate_video)
- {
+ else if(enable_accurate_video) {
avl.attach(vram);
//avl_vga.attach(vram_window);
} else
- {
avl.attach(vram_null);
- }
FILE *img_file = std::fopen(image->c_str(), "rb");
if(!img_file)
@@ -464,11 +471,12 @@ int main(int argc, char **argv)
core->step__VforceVal = 1;
}
- cores[0]->halt__VforceEn = start_halted;
top.rst_n = 0;
cycle();
top.rst_n = 1;
+ cores[0]->halt__VforceEn = static_cast<bool>(start_halted);
+
auto do_reg_dump = [&]()
{
std::fputs("=== dump-regs ===\n", ctrl);
@@ -506,8 +514,8 @@ int main(int argc, char **argv)
if (!ok || (ok >> 29))
return ok;
- unsigned tag = (addr >> 11) & ((1 << 16) - 1);
- unsigned index = (addr >> 2) & ((1 << 9) - 1);
+ unsigned tag = (addr >> 14) & ((1 << 13) - 1);
+ unsigned index = (addr >> 2) & ((1 << 12) - 1);
for (std::size_t i = 0; i < sizeof caches / sizeof caches[0]; ++i) {
const auto *cache = caches[i];
@@ -632,14 +640,16 @@ int main(int argc, char **argv)
unsigned i = 0;
auto loop_accurate = [&]()
{
+ bool exit_loop = false;
+
do {
cycle();
- maybe_halt();
- for (const auto *core : cores)
- if (core->halted)
- break;
- } while (!failed && (*cycles == 0 || ++i < *cycles));
+ if (maybe_halt())
+ for (const auto *core : cores)
+ if (core->halted)
+ exit_loop = true;
+ } while (!exit_loop && !failed && (*cycles == 0 || ++i < *cycles));
};
const bool slow_path = *cycles > 0 || enable_accurate_video || enable_trace;