Get reset sequence to work
This commit is contained in:
@@ -4,11 +4,35 @@ from cocotb.handle import Immediate
|
|||||||
from cocotb.clock import Clock
|
from cocotb.clock import Clock
|
||||||
from cocotb.triggers import Timer, RisingEdge
|
from cocotb.triggers import Timer, RisingEdge
|
||||||
|
|
||||||
|
from collections import defaultdict
|
||||||
|
|
||||||
CLK_PERIOD = 5
|
CLK_PERIOD = 5
|
||||||
|
|
||||||
|
memory = defaultdict(int)
|
||||||
|
|
||||||
|
def write_dword(addr: int, data: int):
|
||||||
|
memory[addr + 0] = (data >> 0) & 0xff
|
||||||
|
memory[addr + 1] = (data >> 8) & 0xff
|
||||||
|
memory[addr + 2] = (data >> 16) & 0xff
|
||||||
|
memory[addr + 3] = (data >> 24) & 0xff
|
||||||
|
|
||||||
|
async def handle_memory(dut):
|
||||||
|
while True:
|
||||||
|
await RisingEdge(dut.clk)
|
||||||
|
addr = int(dut.AB.value)
|
||||||
|
we = bool(dut.WE.value)
|
||||||
|
|
||||||
|
dut.DI.value = memory[addr]
|
||||||
|
|
||||||
|
if we:
|
||||||
|
memory[addr] = int(dut.DO.value)
|
||||||
|
|
||||||
@cocotb.test
|
@cocotb.test
|
||||||
async def test_absolute(dut):
|
async def test_absolute(dut):
|
||||||
cocotb.start_soon(Clock(dut.clk, CLK_PERIOD, unit="ns").start())
|
cocotb.start_soon(Clock(dut.clk, CLK_PERIOD, unit="ns").start())
|
||||||
|
cocotb.start_soon(handle_memory(dut))
|
||||||
|
|
||||||
|
write_dword(0xfffffff4, 0x12345678)
|
||||||
|
|
||||||
dut.RDY.value = Immediate(1)
|
dut.RDY.value = Immediate(1)
|
||||||
|
|
||||||
@@ -17,4 +41,28 @@ async def test_absolute(dut):
|
|||||||
await RisingEdge(dut.clk)
|
await RisingEdge(dut.clk)
|
||||||
dut.reset.value = 0
|
dut.reset.value = 0
|
||||||
|
|
||||||
await Timer(1, "us")
|
expected_cpu_outputs = [
|
||||||
|
(0x00000100, True, (int(dut.PC.value) >> 24) & 0xff), # High addr
|
||||||
|
(0x000001ff, True, (int(dut.PC.value) >> 16) & 0xff), # Mid high addr
|
||||||
|
(0x000001fe, True, (int(dut.PC.value) >> 8) & 0xff), # Mid low addr
|
||||||
|
(0x000001fd, True, (int(dut.PC.value) >> 0) & 0xff), # Low addr
|
||||||
|
(0x000001fc, True, int(dut.P.value)), # Status
|
||||||
|
(0xfffffff4, False, int(dut.regfile.value)), # read vector byte 0
|
||||||
|
(0xfffffff5, False, int(dut.regfile.value)), # read vector byte 1
|
||||||
|
(0xfffffff6, False, int(dut.regfile.value)), # read vector byte 2
|
||||||
|
(0xfffffff7, False, int(dut.regfile.value)), # read vector byte 3
|
||||||
|
(0x12345678, False, int(dut.regfile.value)), # Load PC with vector
|
||||||
|
(0x12345678, False, int(dut.regfile.value)), # Read first instruction
|
||||||
|
]
|
||||||
|
|
||||||
|
for expected_output in expected_cpu_outputs:
|
||||||
|
await RisingEdge(dut.clk)
|
||||||
|
|
||||||
|
expected_addr, expected_we, expected_do = expected_output
|
||||||
|
dut_addr = int(dut.AB.value)
|
||||||
|
dut_we = bool(dut.WE.value)
|
||||||
|
dut_do = int(dut.DO.value)
|
||||||
|
|
||||||
|
assert dut_addr == expected_addr
|
||||||
|
assert dut_we == expected_we
|
||||||
|
assert dut_do == expected_do
|
||||||
|
|||||||
@@ -69,6 +69,8 @@ output reg SYNC; // AB is first cycle of the intruction
|
|||||||
reg [31:0] PC; // Program Counter
|
reg [31:0] PC; // Program Counter
|
||||||
reg [31:0] ABR; // Address Bus Register
|
reg [31:0] ABR; // Address Bus Register
|
||||||
wire [7:0] ADD; // Adder Hold Register (registered in ALU)
|
wire [7:0] ADD; // Adder Hold Register (registered in ALU)
|
||||||
|
reg [7:0] alu_sr_0; // ALU output shift register 0
|
||||||
|
reg [7:0] alu_sr_1; // ALU output shift register 1
|
||||||
|
|
||||||
reg [7:0] DIHOLD; // Hold for Data In
|
reg [7:0] DIHOLD; // Hold for Data In
|
||||||
reg DIHOLD_valid; //
|
reg DIHOLD_valid; //
|
||||||
@@ -262,7 +264,9 @@ parameter
|
|||||||
JMPIX2 = 6'd53, // JMP (,X)- Wait for ALU (only if needed)
|
JMPIX2 = 6'd53, // JMP (,X)- Wait for ALU (only if needed)
|
||||||
WAI = 6'd54, // WAI - Wait for interrupt, then go to decode
|
WAI = 6'd54, // WAI - Wait for interrupt, then go to decode
|
||||||
BRK4 = 6'd55, // TODO
|
BRK4 = 6'd55, // TODO
|
||||||
BRK5 = 6'd56; // TODO
|
BRK5 = 6'd56, // TODO
|
||||||
|
JMP2 = 6'd57, // TODO
|
||||||
|
JMP3 = 6'd58; // TODO
|
||||||
|
|
||||||
`ifdef SIM
|
`ifdef SIM
|
||||||
|
|
||||||
@@ -324,6 +328,8 @@ always @*
|
|||||||
BRA2: statename = "BRA2";
|
BRA2: statename = "BRA2";
|
||||||
JMP0: statename = "JMP0";
|
JMP0: statename = "JMP0";
|
||||||
JMP1: statename = "JMP1";
|
JMP1: statename = "JMP1";
|
||||||
|
JMP2: statename = "JMP2";
|
||||||
|
JMP3: statename = "JMP3";
|
||||||
JMPI0: statename = "JMPI0";
|
JMPI0: statename = "JMPI0";
|
||||||
JMPI1: statename = "JMPI1";
|
JMPI1: statename = "JMPI1";
|
||||||
JMPIX0: statename = "JMPIX0";
|
JMPIX0: statename = "JMPIX0";
|
||||||
@@ -352,19 +358,19 @@ always @*
|
|||||||
PC_temp = PC;
|
PC_temp = PC;
|
||||||
|
|
||||||
|
|
||||||
JMP1,
|
JMP3,
|
||||||
JMPI1,
|
JMPI1,
|
||||||
JMPIX1,
|
JMPIX1,
|
||||||
JSR3,
|
JSR3,
|
||||||
RTS3,
|
RTS3,
|
||||||
RTI4: PC_temp = { DIMUX, ADD };
|
RTI4: PC_temp = { DIMUX, ADD, alu_sr_0, alu_sr_1};
|
||||||
|
|
||||||
BRA1: PC_temp = { ABR[15:8], ADD };
|
BRA1: PC_temp = { ABR[15:8], ADD };
|
||||||
|
|
||||||
JMPIX2,
|
JMPIX2,
|
||||||
BRA2: PC_temp = { ADD, PC[7:0] }; // TODO
|
BRA2: PC_temp = { ADD, PC[7:0] }; // TODO
|
||||||
|
|
||||||
BRK2: PC_temp = res ? 32'hFFFFFFF4 :
|
BRK4: PC_temp = res ? 32'hFFFFFFF4 :
|
||||||
NMI_edge ? 32'hFFFFFFF8 : 32'hFFFFFFFC;
|
NMI_edge ? 32'hFFFFFFF8 : 32'hFFFFFFFC;
|
||||||
|
|
||||||
default: PC_temp = PC;
|
default: PC_temp = PC;
|
||||||
@@ -389,7 +395,9 @@ always @*
|
|||||||
BRA2,
|
BRA2,
|
||||||
BRK5,
|
BRK5,
|
||||||
JMPI1,
|
JMPI1,
|
||||||
|
JMP0,
|
||||||
JMP1,
|
JMP1,
|
||||||
|
JMP2,
|
||||||
RTI4,
|
RTI4,
|
||||||
RTS3: PC_inc = 1;
|
RTS3: PC_inc = 1;
|
||||||
|
|
||||||
@@ -421,10 +429,10 @@ always @*
|
|||||||
ABSX1,
|
ABSX1,
|
||||||
INDX3,
|
INDX3,
|
||||||
INDY2,
|
INDY2,
|
||||||
JMP1,
|
JMP3,
|
||||||
JMPI1,
|
JMPI1,
|
||||||
RTI4,
|
RTI4,
|
||||||
ABS1: AB = { DIMUX, ADD };
|
ABS1: AB = { DIMUX, ADD, alu_sr_0, alu_sr_1};
|
||||||
|
|
||||||
BRA2,
|
BRA2,
|
||||||
INDY3,
|
INDY3,
|
||||||
@@ -667,6 +675,11 @@ ALU ALU( .clk(clk),
|
|||||||
.HC(HC),
|
.HC(HC),
|
||||||
.RDY(RDY) );
|
.RDY(RDY) );
|
||||||
|
|
||||||
|
always @(posedge clk) begin
|
||||||
|
alu_sr_0 <= ADD;
|
||||||
|
alu_sr_1 <= alu_sr_0;
|
||||||
|
end
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Select current ALU operation
|
* Select current ALU operation
|
||||||
*/
|
*/
|
||||||
@@ -687,6 +700,8 @@ always @*
|
|||||||
BRK0,
|
BRK0,
|
||||||
BRK1,
|
BRK1,
|
||||||
BRK2,
|
BRK2,
|
||||||
|
BRK3,
|
||||||
|
BRK4,
|
||||||
JSR0,
|
JSR0,
|
||||||
JSR1: alu_op = OP_SUB;
|
JSR1: alu_op = OP_SUB;
|
||||||
|
|
||||||
@@ -723,6 +738,8 @@ always @*
|
|||||||
RTI2,
|
RTI2,
|
||||||
BRK1,
|
BRK1,
|
||||||
BRK2,
|
BRK2,
|
||||||
|
BRK3,
|
||||||
|
BRK4,
|
||||||
INDX1: AI = ADD;
|
INDX1: AI = ADD;
|
||||||
|
|
||||||
REG,
|
REG,
|
||||||
@@ -1074,7 +1091,9 @@ always @(posedge clk or posedge reset)
|
|||||||
BRA2 : state <= DECODE;
|
BRA2 : state <= DECODE;
|
||||||
|
|
||||||
JMP0 : state <= JMP1;
|
JMP0 : state <= JMP1;
|
||||||
JMP1 : state <= DECODE;
|
JMP1 : state <= JMP2;
|
||||||
|
JMP2 : state <= JMP3;
|
||||||
|
JMP3 : state <= DECODE;
|
||||||
|
|
||||||
JMPI0 : state <= JMPI1;
|
JMPI0 : state <= JMPI1;
|
||||||
JMPI1 : state <= JMP0;
|
JMPI1 : state <= JMP0;
|
||||||
@@ -1106,7 +1125,7 @@ always @(posedge clk or posedge reset)
|
|||||||
PUSH1,
|
PUSH1,
|
||||||
PULL2,
|
PULL2,
|
||||||
RTI4,
|
RTI4,
|
||||||
JMP1,
|
JMP3,
|
||||||
BRA2 : SYNC <= 1'b1;
|
BRA2 : SYNC <= 1'b1;
|
||||||
default: SYNC <= 1'b0;
|
default: SYNC <= 1'b0;
|
||||||
endcase
|
endcase
|
||||||
|
|||||||
Reference in New Issue
Block a user