Skip to content

Commit

Permalink
Add Memory class
Browse files Browse the repository at this point in the history
  • Loading branch information
Argmaster committed Oct 29, 2024
1 parent 9c78458 commit d158add
Show file tree
Hide file tree
Showing 13 changed files with 614 additions and 257 deletions.
273 changes: 273 additions & 0 deletions src/Bytom.Hardware.Tests/Devices/MemoryTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,273 @@

using System.Collections.Concurrent;

namespace Bytom.Hardware.Tests
{
public class MemoryTests
{
public class DebugMemory : Memory
{
public DebugMemory(
uint capacity_bytes,
uint write_latency_cycles,
uint read_latency_cycles,
uint bandwidth_bytes
) : base(
capacity_bytes: capacity_bytes,
write_latency_cycles: write_latency_cycles,
read_latency_cycles: read_latency_cycles,
bandwidth_bytes: bandwidth_bytes,
new Clock(1000)
)
{ }

public override void powerOnInit()
{ }
}

public static Memory createDebugMemory(uint capacity = 128, uint bandwidth_bytes = 1)
{
return new DebugMemory(
capacity_bytes: capacity,
write_latency_cycles: 1,
read_latency_cycles: 1,
bandwidth_bytes: bandwidth_bytes
);
}

public static Memory createMemory(uint capacity = 128, uint bandwidth_bytes = 1)
{
return new Memory(
capacity_bytes: capacity,
write_latency_cycles: 1,
read_latency_cycles: 1,
bandwidth_bytes: bandwidth_bytes,
new Clock(1000)
);
}

[Test]
public void TestPushIoPowerOff()
{
var memory = createMemory();
Assert.Throws<InvalidOperationException>(
() => memory!.pushIoMessage(new WriteMessage(Address.zero, 1))
);
}

[Test]
public void TestPowerOn()
{
var memory = createMemory();
memory!.powerOn(null);
Assert.That(memory!.getPowerStatus(), Is.EqualTo(PowerStatus.ON));
}

[Test]
public void TestManualPowerCycle()
{
var memory = createMemory();
memory!.powerOn(null);
Assert.That(memory!.getPowerStatus(), Is.EqualTo(PowerStatus.ON));
memory!.powerOff();
Assert.That(memory!.getPowerStatus(), Is.EqualTo(PowerStatus.OFF));
Assert.That(memory!.thread!.IsAlive, Is.False);
}

[Test]
public void TestDisposePowerOff()
{
using (var memory = createMemory())
{
Assert.That(memory!.getPowerStatus(), Is.EqualTo(PowerStatus.OFF));
}
}

[Test]
public void TestAutoPowerOff()
{
Thread? thread_handle;
using (var memory = createMemory())
{
memory!.powerOn(null);
thread_handle = memory.thread;
Assert.That(memory!.getPowerStatus(), Is.EqualTo(PowerStatus.ON));
}
Assert.That(thread_handle!.IsAlive, Is.False);
}

[Test]
public void TestWriteScheduleIo()
{
var capacity = 128u;
var memory = createDebugMemory(capacity);

memory!.powerOn(null);
memory!.address_range = new AddressRange(new Address(0), capacity);
scheduleWriteIo(capacity, memory);

Assert.That(memory.queue.io_queue.Count, Is.EqualTo(capacity));
}

private static void scheduleWriteIo(uint capacity, Memory memory)
{
for (var i = 0; i < capacity; i++)
{
memory!.pushIoMessage(new WriteMessage(new Address(i), 1));
}
}

[Test]
public void TestWriteStartRunningIo()
{
var capacity = 128u;
var memory = createDebugMemory(capacity);

memory!.powerOn(null);
memory!.address_range = new AddressRange(new Address(0), capacity);
scheduleWriteIo(capacity, memory);

Assert.That(memory.queue.io_queue.Count, Is.EqualTo(capacity));

memory!.tick();
Assert.That(memory.queue.io_queue.Count, Is.EqualTo(capacity - 1));
Assert.That(memory.queue.tasks_running.Count, Is.EqualTo(1));
}

[Test]
public void TestWriteManualTickAll()
{
var capacity = 128u;
var memory = createDebugMemory(capacity);

memory!.powerOn(null);
memory!.address_range = new AddressRange(new Address(0), capacity);
scheduleWriteIo(capacity, memory);

Assert.That(memory.queue.io_queue.Count, Is.EqualTo(capacity));

for (var i = 0; i < capacity * 2; i++)
{
memory!.tick();
}
Assert.That(memory.queue.io_queue.Count, Is.EqualTo(0));
Assert.That(memory.queue.tasks_running.Count, Is.EqualTo(0));

for (var i = 0; i < capacity; i++)
{
Assert.That(memory.memory[i], Is.EqualTo(1));
}
}

[Test]
public void TestWriteRunAuto()
{
var capacity = 128u;
var memory = createDebugMemory(capacity);

memory!.powerOn(null);
memory!.address_range = new AddressRange(new Address(0), capacity);
scheduleWriteIo(capacity, memory);

memory!.startWorkerThread();

Thread.Sleep(2_000);
Assert.That(memory!.queue.isDone(), Is.True);

memory!.powerOff();

Assert.That(memory!.getPowerStatus(), Is.EqualTo(PowerStatus.OFF));
Assert.That(memory!.thread!.IsAlive, Is.False);

Assert.That(memory.queue.io_queue.Count, Is.EqualTo(0));
Assert.That(memory.queue.tasks_running.Count, Is.EqualTo(0));

for (var i = 0; i < capacity; i++)
{
Assert.That(memory.memory[i], Is.EqualTo(1));
}
}

[Test]
public void TestReadScheduleIo()
{
var capacity = 128u;
var memory = createDebugMemory(capacity);

memory!.powerOn(null);
memory!.address_range = new AddressRange(new Address(0), capacity);
var writeBackBuffer = new ConcurrentQueue<WriteMessage>();

for (var i = 0; i < capacity; i++)
{
memory!.pushIoMessage(new ReadMessage(new Address(i), writeBackBuffer));
}

Assert.That(memory.queue.io_queue.Count, Is.EqualTo(capacity));
Assert.That(memory.queue.tasks_running.Count, Is.EqualTo(0));
Assert.That(writeBackBuffer.Count, Is.EqualTo(0));
}

[Test]
public void TestReadManualIo()
{
var capacity = 128u;
var memory = createDebugMemory(capacity);

memory!.powerOn(null);
memory!.address_range = new AddressRange(new Address(0), capacity);
var writeBackBuffer = new ConcurrentQueue<WriteMessage>();

for (var i = 0; i < capacity; i++)
{
memory!.pushIoMessage(new ReadMessage(new Address(i), writeBackBuffer));
}
for (var i = 0; i < capacity * 2; i++)
{
memory!.tick();
}

Assert.That(memory.queue.io_queue.Count, Is.EqualTo(0));
Assert.That(memory.queue.tasks_running.Count, Is.EqualTo(0));
Assert.That(writeBackBuffer.Count, Is.EqualTo(capacity));

for (var i = 0; i < capacity; i++)
{
Assert.That(writeBackBuffer.TryDequeue(out var message), Is.True);
Assert.That(message!.data, Is.EqualTo(0));
}
}

[Test]
public void TestReadAutoIo()
{
var capacity = 128u;
var memory = createDebugMemory(capacity);

memory!.powerOn(null);
memory!.address_range = new AddressRange(new Address(0), capacity);
var writeBackBuffer = new ConcurrentQueue<WriteMessage>();

for (var i = 0; i < capacity; i++)
{
memory!.pushIoMessage(new ReadMessage(new Address(i), writeBackBuffer));
}

memory!.startWorkerThread();

Thread.Sleep(2_000);
Assert.That(memory!.queue.isDone(), Is.True);

Assert.That(memory.queue.io_queue.Count, Is.EqualTo(0));
Assert.That(writeBackBuffer.Count, Is.EqualTo(capacity));

for (var i = 0; i < capacity; i++)
{
Assert.That(writeBackBuffer.TryDequeue(out var message), Is.True);
Assert.That(message!.data, Is.EqualTo(0));
}

memory!.powerOff();
}
}
}
8 changes: 7 additions & 1 deletion src/Bytom.Hardware.Tests/MotherboardTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,13 @@ public class MotherboardTests
[SetUp]
public void Setup()
{
ram = new RAM(256, 500, 0, 0);
ram = new RAM(
capacity_bytes: 256,
clock_speed_hz: 500,
read_latency_cycles: 0,
write_latency_cycles: 0,
bandwidth_bytes: 1
);
controller = new MemoryController([ram]);
core = new Core(0, 500);
cpu = new Package([core], 128);
Expand Down
57 changes: 0 additions & 57 deletions src/Bytom.Hardware/BiosRom.cs

This file was deleted.

4 changes: 2 additions & 2 deletions src/Bytom.Hardware/CPU/MicoOp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public override IEnumerable execute(Core core)

for (int i = 0; i < register_size; i++)
{
core.GetMemoryController().pushRead(new ReadMessage(address_value + i, writeBackQueue));
core.GetMemoryController().pushIoMessage(new ReadMessage(address_value + i, writeBackQueue));
}
var bytes_read = 0;

Expand Down Expand Up @@ -70,7 +70,7 @@ public override IEnumerable execute(Core core)

for (int i = 0; i < register_size; i++)
{
core.GetMemoryController().pushWrite(new WriteMessage(address_value + i, buffer[i]));
core.GetMemoryController().pushIoMessage(new WriteMessage(address_value + i, buffer[i]));
}
yield break;
}
Expand Down
Loading

0 comments on commit d158add

Please sign in to comment.