This adds an explicit multiplexer feeding v.e.write_data in execute1,
with the select lines determined in the previous cycle based on the
insn_type. Similarly, for multiply and divide instructions, there is
now an explicit multiplexer.
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
This does the addition of the instruction NIA and the branch offset
after the register at the output of execute1 rather than before.
The propagation through the adder was showing up as a critical path
on the A7-100. Performance is unaffected and now it makes timing.
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
This does the addition of NIA plus the branch offset from the
instruction after a clock edge, in order to ease timing, as the path
from the icache RAM through the adder in decode1 to the NIA register
in fetch1 was showing up as a critical path.
This adds one extra cycle of latency when redirecting fetch because of
a predicted-taken branch.
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
This makes timing easier and also means that store floating-point
single precision instructions no longer need to take an extra cycle.
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
This makes it simpler to work out when to deliver a FPU unavailable
interrupt. This also means we can get rid of the OP_FPLOAD and
OP_FPSTORE insn_type values.
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
Lq and stq are tested in both BE and LE modes (though only 64-bit
mode) by the 'modes' test.
Lqarx and stqcx. are tested by the 'reservation' test in LE mode mode
(64-bit).
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
This implements the lq, stq, lqarx and stqcx. instructions.
These instructions all access two consecutive GPRs; for example the
"lq %r6,0(%r3)" instruction will load the doubleword at the address
in R3 into R7 and the doubleword at address R3 + 8 into R6. To cope
with having two GPR sources or destinations, the instruction gets
repeated at the decode2 stage, that is, for each lq/stq/lqarx/stqcx.
coming in from decode1, two instructions get sent out to execute1.
For these instructions, the RS or RT register gets modified on one
of the iterations by setting the LSB of the register number. In LE
mode, the first iteration uses RS|1 or RT|1 and the second iteration
uses RS or RT. In BE mode, this is done the other way around. In
order for decode2 to know what endianness is currently in use, we
pass the big_endian flag down from icache through decode1 to decode2.
This is always in sync with what execute1 is using because only rfid
or an interrupt can change MSR[LE], and those operations all cause
a flush and redirect.
There is now an extra column in the decode tables in decode1 to
indicate whether the instruction needs to be repeated. Decode1 also
enforces the rule that lq with RT = RT and lqarx with RA = RT or
RB = RT are illegal.
Decode2 now passes a 'repeat' flag and a 'second' flag to execute1,
and execute1 passes them on to loadstore1. The 'repeat' flag is set
for both iterations of a repeated instruction, and 'second' is set
on the second iteration. Execute1 does not take asynchronous or
trace interrupts on the second iteration of a repeated instruction.
Loadstore1 uses 'next_addr' for the second iteration of a repeated
load/store so that we access the second doubleword of the memory
operand. Thus loadstore1 accesses the doublewords in increasing
memory order. For 16-byte loads this means that the first iteration
writes GPR RT|1. It is possible that RA = RT|1 (this is a legal
but non-preferred form), meaning that if the memory operand was
misaligned, the first iteration would overwrite RA but then the
second iteration might take a page fault, leading to corrupted state.
To avoid that possibility, 16-byte loads in LE mode take an
alignment interrupt if the operand is not 16-byte aligned. (This
is the case anyway for lqarx, and we enforce it for lq as well.)
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
This compares the address being fetched with the contents of a
register that can be set via DMI, and if they match, stops the
logging. Since this works on the address being fetched rather than
executed, it is subject to false positives.
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
Instead of using the mask generator in the rounding process, this uses
simpler logic to add in a 1 at the appropriate position (bit 2 or bit
31, depending on precision) and mask off the low-order bits. Since
there are only two positions at which the masking and incrementing
need to be done, we don't need the full generality of the mask
generator. This reduces the amount of logic and improves timing.
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
At present there is a state transition in the handling of the fmadd
instructions where the next state depends on the sign bit of the
multiplier result. This creates a critical path which doesn't make
timing on the A7-100. To fix this, we make the state transition
independent of the sign of the multiplier result, which improves
timing, but means we take one more cycle to do a fmadd-family
instruction in some cases.
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
This adds, as comments, lines which would if uncommented define
properties which associate the pins of the headers on the Arty A7
board with FPGA pins. It also adds properties for LEDs 1--3, also
commented out for now.
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
This deletes some commentary that is now out of date and replaces it
with a simple statement about the XER common bits being forwarded from
the output of execute1 to the input.
The comment being deleted talked about a hazard if an instruction that
modifies XER[SO] is immediately followed by a store conditional. That
is no longer a problem because the operands for loadstore1 are sent
from execute1 (and therefore have the forwarded value) rather than
decode2. This was in fact fixed in 5422007f83 ("Plumb loadstore1
input from execute1 not decode2", 2020-01-14).
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
We don't care what the values of TB and DECR are after reset, but we
don't want the X state to propagate to other parts of the chip.
Signed-off-by: Anton Blanchard <anton@linux.ibm.com>
This makes it easier to parse the records in verilog because they
are getting flattened into an array of bits by ghdl/yosys.
Signed-off-by: Anton Blanchard <anton@linux.ibm.com>
The ability to stop the core using the debug interface has been broken
since commit bb4332b7e6b5 ("Remove fetch2 pipeline stage"), which
removed a statement that cleared the valid bit on instructions when
their stop_mark was 1.
Fix this by clearing r.req coming out of fetch1 when r.stop_mark = 1.
This has the effect of making i_out.valid be 0 from the icache. We
also fix a bug in icache.vhdl where it was not honouring i_in.req when
use_previous = 1.
It turns out that the logic in fetch1.vhdl to handle stopping and
restarting was not correct, with the effect that stopping the core
would leave NIA pointing to the last instruction executed, not the
next instruction to be executed. In fact the state machine is
unnecessary and the whole thing can be simplified enormously - we
need to increment NIA whenever stop_in = 0 in the previous cycle.
Fixes: bb4332b7e6b5 ("Remove fetch2 pipeline stage")
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
The tools complain about uart1_irq not being driven and not having a
default when HAS_UART1 is false. This sets it to 0 in that case.
Fixes: 7575b1e0c2 ("uart: Import and hook up opencore 16550 compatible UART")
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
request is never initialized and we leak X state control signals to other
parts of the core (eg dmi_wr). Add a reset.
Signed-off-by: Anton Blanchard <anton@linux.ibm.com>
If BOOT_CLOCKS is false we currently get stuck in the flash
state machine. This patch from Ben fixes it.
Also fix an x state issue I see in icarus verilog where we need
to reset auto_state.
Signed-off-by: Anton Blanchard <anton@linux.ibm.com>
Some of the bits in the FPU buses end up as z state. Yosys
flags them, so we may as well clean it up.
Signed-off-by: Anton Blanchard <anton@linux.ibm.com>
Our flash controller fails when simulating with iverilog. Looking
closer, both wb_stash and auto_last_addr are X state, and things
fall apart after they get used.
Initialise them both fixes the iverilog issue.
Signed-off-by: Anton Blanchard <anton@linux.ibm.com>
Our Makefiles need some work, but for now create an FPGA target:
make FPGA_TARGET=verilator microwatt-verilator
ghdl and yosys can use containers using PODMAN=1 or DOCKER=1
options.
Signed-off-by: Anton Blanchard <anton@linux.ibm.com>
yosys and verilator did not like us passing in the verilog and
exporting it again. Pass the source directly to verilator instead.
Signed-off-by: Anton Blanchard <anton@linux.ibm.com>
When building with yosys we assume hello_world fits in 8kB. There's
enough free space that we can adjust the linker script to make it fit.
Signed-off-by: Anton Blanchard <anton@linux.ibm.com>