Compare commits

..

No commits in common. 'master' and 'less-fpga-init' have entirely different histories.

@ -103,8 +103,14 @@ sudo dnf install fusesoc


``` ```
fusesoc init fusesoc init
fusesoc fetch uart16550 ```
fusesoc library add microwatt /path/to/microwatt
- Create a working directory and point FuseSoC at microwatt:

```
mkdir microwatt-fusesoc
cd microwatt-fusesoc
fusesoc library add microwatt /path/to/microwatt/
``` ```


- Build using FuseSoC. For hello world (Replace nexys_video with your FPGA board such as --target=arty_a7-100): - Build using FuseSoC. For hello world (Replace nexys_video with your FPGA board such as --target=arty_a7-100):
@ -122,68 +128,6 @@ You should then be able to see output via the serial port of the board (/dev/tty
fusesoc run --target=nexys_video microwatt fusesoc run --target=nexys_video microwatt
``` ```


## Linux on Microwatt

Mainline Linux supports Microwatt as of v5.14. The Arty A7 is the best tested
platform, but it's also been tested on the OrangeCrab and ButterStick.

1. Use buildroot to create a userspace

A small change is required to glibc in order to support the VMX/AltiVec-less
Microwatt, as float128 support is mandiatory and for this in GCC requires
VSX/AltiVec. This change is included in Joel's buildroot fork, along with a
defconfig:
```
git clone -b microwatt https://github.com/shenki/buildroot
cd buildroot
make ppc64le_microwatt_defconfig
make
```

The output is `output/images/rootfs.cpio`.

2. Build the Linux kernel
```
git clone https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
cd linux
make ARCH=powerpc microwatt_defconfig
make ARCH=powerpc CROSS_COMPILE=powerpc64le-linux-gnu- \
CONFIG_INITRAMFS_SOURCE=/buildroot/output/images/rootfs.cpio -j`nproc`
```

The output is `arch/powerpc/boot/dtbImage.microwatt.elf`.

3. Build gateware using FuseSoC

First configure FuseSoC as above.
```
fusesoc run --build --target=arty_a7-100 microwatt --no_bram --memory_size=0
```

The output is `build/microwatt_0/arty_a7-100-vivado/microwatt_0.bit`.

4. Program the flash

This operation will overwrite the contents of your flash.

For the Arty A7 A100, set `FLASH_ADDRESS` to `0x400000` and pass `-f a100`.

For the Arty A7 A35, set `FLASH_ADDRESS` to `0x300000` and pass `-f a35`.
```
microwatt/openocd/flash-arty -f a100 build/microwatt_0/arty_a7-100-vivado/microwatt_0.bit
microwatt/openocd/flash-arty -f a100 dtbImage.microwatt.elf -t bin -a $FLASH_ADDRESS
```

5. Connect to the second USB TTY device exposed by the FPGA

```
minicom -D /dev/ttyUSB1
```

The gateware has firmware that will look at `FLASH_ADDRESS` and attempt to
parse an ELF there, loading it to the address specified in the ELF header
and jumping to it.

## Testing ## Testing


- A simple test suite containing random execution test cases and a couple of - A simple test suite containing random execution test cases and a couple of

@ -117,6 +117,7 @@ architecture behave of core is
signal complete: instr_tag_t; signal complete: instr_tag_t;
signal terminate: std_ulogic; signal terminate: std_ulogic;
signal core_rst: std_ulogic; signal core_rst: std_ulogic;
signal icache_inv: std_ulogic;
signal do_interrupt: std_ulogic; signal do_interrupt: std_ulogic;


-- Delayed/Latched resets and alt_reset -- Delayed/Latched resets and alt_reset

@ -154,7 +154,6 @@ begin
stopping <= '0'; stopping <= '0';
terminated <= '0'; terminated <= '0';
log_trigger_delay <= 0; log_trigger_delay <= 0;
gspr_index <= (others => '0');
else else
if do_log_trigger = '1' or log_trigger_delay /= 0 then if do_log_trigger = '1' or log_trigger_delay /= 0 then
if log_trigger_delay = 255 then if log_trigger_delay = 255 then

@ -1121,6 +1121,7 @@ begin
rams: for i in 0 to NUM_WAYS-1 generate rams: for i in 0 to NUM_WAYS-1 generate
signal do_read : std_ulogic; signal do_read : std_ulogic;
signal rd_addr : std_ulogic_vector(ROW_BITS-1 downto 0); signal rd_addr : std_ulogic_vector(ROW_BITS-1 downto 0);
signal do_write : std_ulogic;
signal wr_addr : std_ulogic_vector(ROW_BITS-1 downto 0); signal wr_addr : std_ulogic_vector(ROW_BITS-1 downto 0);
signal wr_data : std_ulogic_vector(wishbone_data_bits-1 downto 0); signal wr_data : std_ulogic_vector(wishbone_data_bits-1 downto 0);
signal wr_sel : std_ulogic_vector(ROW_SIZE-1 downto 0); signal wr_sel : std_ulogic_vector(ROW_SIZE-1 downto 0);

@ -42,8 +42,6 @@ begin
quot <= (others => '0'); quot <= (others => '0');
running <= '0'; running <= '0';
count <= "0000000"; count <= "0000000";
is_32bit <= '0';
overflow <= '0';
elsif d_in.valid = '1' then elsif d_in.valid = '1' then
if d_in.is_extended = '1' then if d_in.is_extended = '1' then
dend <= '0' & d_in.dividend & x"0000000000000000"; dend <= '0' & d_in.dividend & x"0000000000000000";

@ -113,6 +113,8 @@ architecture behaviour of execute1 is
signal misc_result: std_ulogic_vector(63 downto 0); signal misc_result: std_ulogic_vector(63 downto 0);
signal muldiv_result: std_ulogic_vector(63 downto 0); signal muldiv_result: std_ulogic_vector(63 downto 0);
signal spr_result: std_ulogic_vector(63 downto 0); signal spr_result: std_ulogic_vector(63 downto 0);
signal result_mux_sel: std_ulogic_vector(2 downto 0);
signal sub_mux_sel: std_ulogic_vector(2 downto 0);
signal next_nia : std_ulogic_vector(63 downto 0); signal next_nia : std_ulogic_vector(63 downto 0);
signal current: Decode2ToExecute1Type; signal current: Decode2ToExecute1Type;



@ -16,7 +16,7 @@ entity fpu is
clk : in std_ulogic; clk : in std_ulogic;
rst : in std_ulogic; rst : in std_ulogic;


e_in : in Execute1ToFPUType; e_in : in Execute1toFPUType;
e_out : out FPUToExecute1Type; e_out : out FPUToExecute1Type;


w_out : out FPUToWritebackType w_out : out FPUToWritebackType
@ -549,10 +549,6 @@ begin
r.do_intr <= '0'; r.do_intr <= '0';
r.fpscr <= (others => '0'); r.fpscr <= (others => '0');
r.writing_back <= '0'; r.writing_back <= '0';
r.dest_fpr <= (others =>'0');
r.cr_mask <= (others =>'0');
r.cr_result <= (others =>'0');
r.instr_tag.valid <= '0';
else else
assert not (r.state /= IDLE and e_in.valid = '1') severity failure; assert not (r.state /= IDLE and e_in.valid = '1') severity failure;
r <= rin; r <= rin;

@ -60,25 +60,11 @@ _start:


.global boot_entry .global boot_entry
boot_entry: boot_entry:
LOAD_IMM64(%r10,__bss_start)
LOAD_IMM64(%r11,__bss_end)
subf %r11,%r10,%r11
addi %r11,%r11,63
srdi. %r11,%r11,6
beq 2f
mtctr %r11
1: dcbz 0,%r10
addi %r10,%r10,64
bdnz 1b

/* setup stack */ /* setup stack */
2: LOAD_IMM64(%r1,__stack_top) LOAD_IMM64(%r1, STACK_TOP - 0x100)
li %r0,0
stdu %r0,-32(%r1)
LOAD_IMM64(%r12, main) LOAD_IMM64(%r12, main)
mtctr %r12 mtctr %r12,
bctrl bctrl
attn // terminate on exit
b . b .


#define EXCEPTION(nr) \ #define EXCEPTION(nr) \

Binary file not shown.

Binary file not shown.

@ -35,24 +35,24 @@ a64b5a7d14004a39
a602487d05009f42 a602487d05009f42
a64b5a7d14004a39 a64b5a7d14004a39
2402004ca64b7b7d 2402004ca64b7b7d
3d40000048000004 3c20000048000004
794a07c6614a0000
614a1900654a0000
616b00003d600000
656b0000796b07c6
7d6a5850616b1980
796bd183396b003f
7d6903a641820014
394a00407c0057ec
3c2000004200fff8
782107c660210000 782107c660210000
6021398064210000 60211f0064210000
f801ffe138000000 618c00003d800000
3d8000007c1243a6 658c0000798c07c6
798c07c6618c0000 7d8903a6618c1014
618c1000658c0000 480000004e800421
4e8004217d8903a6 0000000000000000
4800000000000200 0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000 0000000000000000
0000000000000000 0000000000000000
0000000000000000 0000000000000000
@ -510,150 +510,150 @@ f801ffe138000000
0000000000000000 0000000000000000
0000000000000000 0000000000000000
0000000000000000 0000000000000000
384298003c400001 e8010010ebc1fff0
fbe1fff87c0802a6 7c0803a6ebe1fff8
f821ffd1f8010010 3c4000014e800020
60000000480001ed 7c0802a638429800
3862800060000000 f8010010fbe1fff8
6000000048000155 480001edf821ffd1
6000000048000049 6000000060000000
5463063e7c7f1b78 4800015538628000
480000b957ff063e 4800004960000000
2c1f000d60000000 7c7f1b7860000000
3860000a4082ffe0 57ff063e5463063e
60000000480000a5 60000000480000b9
4082ffe02c1f000d
480000a53860000a
4bffffd060000000
0100000000000000
3c40000100000180
6000000038429800
6000000089228090
2c09000039428088
e92a000041820030
7c0004ac39290014
712900017d204eaa
e86a00004182ffec
7c601eaa7c0004ac
4e8000205463063e
39290010e92a0000
7d204eea7c0004ac
4082ffec71290001
38630008e86a0000
7c601eea7c0004ac
000000004bffffd0 000000004bffffd0
0000018001000000 0000000000000000
384298003c400001 384298003c400001
8922810860000000 8922809060000000
3942810060000000 3942808860000000
418200302c090000 4182002c2c090000
39290014e92a0000 39290014e92a0000
7d204eaa7c0004ac 7d204eaa7c0004ac
4182ffec71290001 4182ffec71290020
7c0004ace86a0000 7c0004ace92a0000
5463063e7c601eaa 4e8000207c604faa
e92a00004e800020 39290010e92a0000
7c0004ac39290010 7d204eea7c0004ac
712900017d204eea 4082ffec71290008
e86a00004082ffec e94a00005469063e
7c0004ac38630008 7d2057ea7c0004ac
4bffffd07c601eea 000000004e800020
0000000000000000
3c40000100000000
6000000038429800
6000000089228108
2c09000039428100
e92a00004182002c
7c0004ac39290014
712900207d204eaa
e92a00004182ffec
7c604faa7c0004ac
e92a00004e800020
7c0004ac39290010
712900087d204eea
5469063e4082ffec
7c0004ace94a0000
4e8000207d2057ea
0000000000000000 0000000000000000
3c40000100000000 384298003c400001
7c0802a638429800 fbe1fff87c0802a6
fbc1fff0fbe1fff8 3be3fffffbc1fff0
f80100103be3ffff f821ffd1f8010010
8fdf0001f821ffd1 2c3e00008fdf0001
408200102c3e0000 3821003040820010
3860000038210030 4bfffe4438600000
281e000a480001e8 4082000c281e000a
3860000d4082000c 4bffff453860000d
7fc3f3784bffff45 4bffff3d7fc3f378
4bffffd04bffff3d 000000004bffffd0
0100000000000000 0000028001000000
7c691b7800000280 386000007c691b78
7d4918ae38600000 2c0a00007d4918ae
4d8200202c0a0000 386300014d820020
4bfffff038630001 000000004bfffff0
0000000000000000 0000000000000000
3c40000100000000 384298003c400001
3d40c00038429800 614a00203d40c000
794a0020614a0020 7c0004ac794a0020
7d4056ea7c0004ac 3d20c0007d4056ea
794a06003d20c000 61290008794a0600
7929002061290008
7d204eea7c0004ac
4182001871290020
612900403d20c000
7c0004ac79290020 7c0004ac79290020
7929f8047d204eea 712900207d204eea
79290fc33d00c000 3d20c00041820018
7908002061082000 7929002061290040
f902810060000000 7d204eea7c0004ac
610820003d00001c 3d00c0007929f804
418200847d4a4392 6108200079290fc3
3920000160000000 6000000079080020
3d00c00099228108 3d00001cf9028088
3920ff806108200c 7d4a439261082000
7c0004ac79080020 6000000041820084
e92281007d2047aa 9922809039200001
7d404faa7c0004ac 6108200c3d00c000
794ac202e9228100 790800203920ff80
7c0004ac39290004 7d2047aa7c0004ac
e92281007d404faa 7c0004ace9228088
3929000c39400003 e92280887d404faa
39290004794ac202
7d404faa7c0004ac 7d404faa7c0004ac
39290010e9228100 39400003e9228088
7c0004ac3929000c
e92280887d404faa
7c0004ac39290010
e92280887d404faa
3929000839400007
7d404faa7c0004ac 7d404faa7c0004ac
39400007e9228100 600000004e800020
7c0004ac39290008 99228090394affff
4e8000207d404faa 612920183d20c000
394affff60000000 7c0004ac79290020
3d20c00099228108 4e8000207d404fea
7929002061292018
7d404fea7c0004ac
000000004e800020
0000000000000000 0000000000000000
384298003c400001 3c40000100000000
8922810860000000 6000000038429800
600000002c090000 2c24000089228090
41820024e9228100 600000002f890000
78840e282c230000 419e0030e9228088
6084000141820008 3940000241820024
7c0004ac39290004 418200082c230000
4e8000207c804faa 39290004614a0001
418200082c240000 7d404faa7c0004ac
394000004e800020
418200084bffffe0
3929002060630002 3929002060630002
7c604fea7c0004ac 7c604fea7c0004ac
000000004e800020 000000004e800020
0000000000000000 0000000000000000
e8010010ebc1fff0 0000000000000010
7c0803a6ebe1fff8 0141780400527a01
000000104e800020 0000001800010c1b
00527a0100000000 fffffc4800000018
00010c1b01417804 300e460000000070
0000001800000018 000000019f7e4111
00000070fffffc40 0000000000000010
9f7e4111300e4600 0141780400527a01
0000001000000001 0000001000010c1b
00527a0100000000 fffffc8800000018
00010c1b01417804 0000000000000084
0000001800000010 0000002c00000010
00000084fffffc80 00000080fffffcf8
0000001000000000 0000002800000000
fffffcf00000002c fffffd6400000040
0000000000000080 4109450000000060
0000004000000028 300e43029e019f00
00000060fffffd5c 42000e0a447e4111
9e019f0041094500 0000000b4106dedf
447e4111300e4302 0000006c00000010
4106dedf42000e0a 00000028fffffd98
000000100000000b
fffffd900000006c
0000000000000028
0000008000000010
0000012cfffffda4
0000001000000000 0000001000000000
fffffebc00000094 fffffdac00000080
0000000000000068 000000000000012c
0000000000000000 0000009400000010
00000074fffffec4
0000000000000000 0000000000000000
0000000000000000 0000000000000000
0000000000000000 0000000000000000

@ -1,27 +1,13 @@
SECTIONS SECTIONS
{ {
. = 0;
_start = .; _start = .;
. = 0;
.head : { .head : {
KEEP(*(.head)) KEEP(*(.head))
} }
. = 0x1000; . = 0x1000;
.text : { *(.text) *(.text.*) *(.rodata) *(.rodata.*) } .text : { *(.text) }
. = 0x1800; . = 0x1800;
.data : { *(.data) *(.data.*) *(.got) *(.toc) } .data : { *(.data) }
. = ALIGN(0x80); .bss : { *(.bss) }
__bss_start = .;
.bss : {
*(.dynsbss)
*(.sbss)
*(.scommon)
*(.dynbss)
*(.bss)
*(.common)
*(.bss.*)
}
. = ALIGN(0x80);
__bss_end = .;
. = . + 0x2000;
__stack_top = .;
} }

@ -555,11 +555,7 @@ begin
-- I prefer not to do just yet as it would force fetch2 to know about -- I prefer not to do just yet as it would force fetch2 to know about
-- some of the cache geometry information. -- some of the cache geometry information.
-- --
if r.hit_valid = '1' then i_out.insn <= read_insn_word(r.hit_nia, cache_out(r.hit_way));
i_out.insn <= read_insn_word(r.hit_nia, cache_out(r.hit_way));
else
i_out.insn <= (others => '0');
end if;
i_out.valid <= r.hit_valid; i_out.valid <= r.hit_valid;
i_out.nia <= r.hit_nia; i_out.nia <= r.hit_nia;
i_out.stop_mark <= r.hit_smark; i_out.stop_mark <= r.hit_smark;
@ -824,7 +820,4 @@ begin
end process; end process;
log_out <= log_data; log_out <= log_data;
end generate; end generate;

events <= ev;

end; end;

@ -74,9 +74,6 @@ begin
i_out.req <= '0'; i_out.req <= '0';
i_out.nia <= (others => '0'); i_out.nia <= (others => '0');
i_out.stop_mark <= '0'; i_out.stop_mark <= '0';
i_out.priv_mode <= '1';
i_out.virt_mode <= '0';
i_out.big_endian <= '0';


m_out.tlbld <= '0'; m_out.tlbld <= '0';
m_out.tlbie <= '0'; m_out.tlbie <= '0';

@ -275,27 +275,10 @@ begin
if rising_edge(clk) then if rising_edge(clk) then
if rst = '1' then if rst = '1' then
r1.req.valid <= '0'; r1.req.valid <= '0';
r1.req.tlbie <= '0';
r1.req.is_slbia <= '0';
r1.req.instr_fault <= '0';
r1.req.load <= '0';
r1.req.priv_mode <= '0';
r1.req.sprn <= (others => '0');
r1.req.xerc <= xerc_init;

r2.req.valid <= '0'; r2.req.valid <= '0';
r2.req.tlbie <= '0';
r2.req.is_slbia <= '0';
r2.req.instr_fault <= '0';
r2.req.load <= '0';
r2.req.priv_mode <= '0';
r2.req.sprn <= (others => '0');
r2.req.xerc <= xerc_init;

r2.wait_dc <= '0'; r2.wait_dc <= '0';
r2.wait_mmu <= '0'; r2.wait_mmu <= '0';
r2.one_cycle <= '0'; r2.one_cycle <= '0';

r3.dar <= (others => '0'); r3.dar <= (others => '0');
r3.dsisr <= (others => '0'); r3.dsisr <= (others => '0');
r3.state <= IDLE; r3.state <= IDLE;
@ -303,8 +286,6 @@ begin
r3.interrupt <= '0'; r3.interrupt <= '0';
r3.stage1_en <= '1'; r3.stage1_en <= '1';
r3.convert_lfs <= '0'; r3.convert_lfs <= '0';
r3.events.load_complete <= '0';
r3.events.store_complete <= '0';
flushing <= '0'; flushing <= '0';
else else
r1 <= r1in; r1 <= r1in;

Loading…
Cancel
Save