fsm must run in 'slow' domain. alu must be combinatorial.

This commit is contained in:
Bastian Löher
2022-12-05 10:44:03 +01:00
parent 4e74cd693d
commit 25e30c4675
2 changed files with 45 additions and 26 deletions

View File

@@ -15,29 +15,33 @@ def proc():
clk = yield soc.slow_clk
if prev_clk == 0 and prev_clk != clk:
state = (yield soc.state)
if state == 0:
print("---- FETCH -----------------------")
print(" pc={}".format((yield soc.pc)))
print(" instr={:#032b}".format((yield soc.instr)))
if state == 2:
print("-- NEW CYCLE -----------------------")
print(" F: LEDS = {:05b}".format((yield soc.leds)))
print(" F: pc={}".format((yield soc.pc)))
print(" F: instr={:#032b}".format((yield soc.instr)))
if (yield soc.isALUreg):
print(" ALUreg rd={} rs1={} rs2={} funct3={}".format(
print(" ALUreg rd={} rs1={} rs2={} funct3={}".format(
(yield soc.rdId), (yield soc.rs1Id), (yield soc.rs2Id),
(yield soc.funct3)))
if (yield soc.isALUimm):
print(" ALUimm rd={} rs1={} imm={} funct3={}".format(
print(" ALUimm rd={} rs1={} imm={} funct3={}".format(
(yield soc.rdId), (yield soc.rs1Id), (yield soc.Iimm),
(yield soc.funct3)))
if (yield soc.isLoad):
print(" LOAD")
print(" LOAD")
if (yield soc.isStore):
print(" STORE")
print(" STORE")
if (yield soc.isSystem):
print(" SYSTEM")
print(" SYSTEM")
break
if state == 2:
print("---- EXECUTE ---------------------")
print(" LEDS = {:05b}".format((yield soc.leds)))
print(" Writeback x{} = {:032b}".format((yield soc.rdId),
if state == 4:
print(" R: LEDS = {:05b}".format((yield soc.leds)))
print(" R: rs1={}".format((yield soc.rs1)))
print(" R: rs2={}".format((yield soc.rs2)))
if state == 1:
print(" E: LEDS = {:05b}".format((yield soc.leds)))
print(" E: Writeback x{} = {:032b}".format((yield soc.rdId),
(yield soc.writeBackData)))
yield
prev_clk = clk

View File

@@ -29,36 +29,47 @@ class SOC(Elaboratable):
# ......|....|....|..|....|......|
# add x1, x0, x0
# rs2 rs1 add rd ALUREG
# -> x1 = 0
0b00000000000000000000000010110011,
# addi x1, x1, 1
# imm rs1 add rd ALUIMM
# -> x1 = 1
0b00000000000100001000000010010011,
# addi x1, x1, 1
# imm rs1 add rd ALUIMM
# -> x1 = 2
0b00000000000100001000000010010011,
# addi x1, x1, 1
# imm rs1 add rd ALUIMM
# -> x1 = 3
0b00000000000100001000000010010011,
# addi x1, x1, 1
# imm rs1 add rd ALUIMM
# -> x1 = 4
0b00000000000100001000000010010011,
# add x2, x1, x0
# rs2 rs1 add rd ALUREG
# -> x2 = 4
0b00000000000000001000000100110011,
# add x2, x1, x0
# add x3, x1, x2
# rs2 rs1 add rd ALUREG
# -> x3 = 8
0b00000000001000001000000110110011,
# srli x3, x3, 3
# shamt rs1 sr rd ALUIMM
# -> x3 = 1
0b00000000001100011101000110010011,
# slli x3, x3, 31
# shamt rs1 sl rd ALUIMM
# -> x3 = 0x80000000
0b00000001111100011001000110010011,
# srai x3, x3, 5
# shamt rs1 sr rd ALUIMM
# -> x3 = 0xfc000000
0b01000000010100011101000110010011,
# srli x1, x3, 26
# shamt rs1 sr rd ALUIMM
# -> x1 = 0x3f
0b00000001101000011101000010010011,
0b00000000000100000000000001110011 # S ebreak
@@ -71,10 +82,10 @@ class SOC(Elaboratable):
instr = Signal(32, reset=0b0110011)
# Instruction memory initialised with above 'sequence'
mem = Array([Signal(32, reset=x) for x in sequence])
mem = Array([Signal(32, reset=x, name="mem") for x in sequence])
# Register bank
regs = Array([Signal(32) for x in range(32)])
regs = Array([Signal(32, name="x"+str(x)) for x in range(32)])
rs1 = Signal(32)
rs2 = Signal(32)
@@ -118,28 +129,28 @@ class SOC(Elaboratable):
with m.Switch(funct3) as alu:
with m.Case(0b000):
m.d.slow += aluOut.eq(Mux(funct7[5] & instr[5],
m.d.comb += aluOut.eq(Mux(funct7[5] & instr[5],
(aluIn1 - aluIn2), (aluIn1 + aluIn2)))
with m.Case(0b001):
m.d.slow += aluOut.eq(aluIn1 << shamt)
m.d.comb += aluOut.eq(aluIn1 << shamt)
with m.Case(0b010):
m.d.slow += aluOut.eq(aluIn1.as_signed() < aluIn2.as_signed())
m.d.comb += aluOut.eq(aluIn1.as_signed() < aluIn2.as_signed())
with m.Case(0b011):
m.d.slow += aluOut.eq(aluIn1 < aluIn2)
m.d.comb += aluOut.eq(aluIn1 < aluIn2)
with m.Case(0b100):
m.d.slow += aluOut.eq(aluIn1 ^ aluIn2)
m.d.comb += aluOut.eq(aluIn1 ^ aluIn2)
with m.Case(0b101):
m.d.slow += aluOut.eq(Mux(
m.d.comb += aluOut.eq(Mux(
funct7[5],
(aluIn1.as_signed() >> shamt), # arithmetic right shift
(aluIn1.as_unsigned() >> shamt))) # logical right shift
with m.Case(0b110):
m.d.slow += aluOut.eq(aluIn1 | aluIn2)
m.d.comb += aluOut.eq(aluIn1 | aluIn2)
with m.Case(0b111):
m.d.slow += aluOut.eq(aluIn1 & aluIn2)
m.d.comb += aluOut.eq(aluIn1 & aluIn2)
# Main state machine
with m.FSM(reset="FETCH_INSTR") as fsm:
with m.FSM(reset="FETCH_INSTR", domain="slow") as fsm:
# Assign important signals to LEDS
m.d.comb += self.leds.eq(Mux(isSystem, 31, (1 << fsm.state)))
with m.State("FETCH_INSTR"):
@@ -187,7 +198,11 @@ class SOC(Elaboratable):
export(Iimm, "Iimm")
export(funct3, "funct3")
export(rdId, "rdId")
export(rs1, "rs1")
export(rs2, "rs2")
export(writeBackData, "writeBackData")
export(fsm.state, "state")
export(writeBackEn, "writeBackEn")
export(aluOut, "aluOut")
export((1 << fsm.state), "state")
return m