Peripherals/Memory: Added support for the litedram DDR memory controller, created a new memory map and updated all relevant code and files including the addition of rudimentary wait state support for the cpu (BIU)
This commit is contained in:
parent
f1dc9d8a59
commit
63ea29e399
2
.gitignore
vendored
2
.gitignore
vendored
@ -13,8 +13,10 @@ abc.history
|
||||
system/synth_ecp5_out.config
|
||||
boot_code/*.bin
|
||||
boot_code/*.txt
|
||||
boot_code/*.stxt
|
||||
system/boot_code.bin
|
||||
system/boot_code.txt
|
||||
system/obj_dir/
|
||||
system/simplified_ucode.txt
|
||||
tools/*svg
|
||||
system/external_ip/litedram_core_ecp5_phy.v
|
||||
|
6
Makefile
6
Makefile
@ -21,7 +21,7 @@ VERILATOR_BIN=system/obj_dir/Vsystem
|
||||
BOOT_CODE=boot_code/brainfuck_mandelbrot.txt
|
||||
GTKWSAVE=./gtkwave_savefile.gtkw
|
||||
MICROCODE=system/ucode.txt
|
||||
BOOTABLES=boot_code/brainfuck_compiled.txt boot_code/brainfuck_interpreted.txt boot_code/pipeline_ideal.txt boot_code/fibonacci.txt boot_code/gnome_sort.txt boot_code/cache_fill_and_empty.txt ${BOOT_CODE} boot_code/colored_led.txt
|
||||
BOOTABLES=boot_code/brainfuck_compiled.txt boot_code/brainfuck_interpreted.txt boot_code/pipeline_ideal.txt boot_code/fibonacci.txt boot_code/gnome_sort.txt boot_code/cache_fill_and_empty.txt ${BOOT_CODE} boot_code/colored_led.txt boot_code/bios.stxt
|
||||
|
||||
NO_ASM=1
|
||||
include common.mk
|
||||
@ -29,7 +29,7 @@ include common.mk
|
||||
.PHONY: ${BOOTABLES}
|
||||
.PHONY: ${subst .txt,.bin,${BOOTABLES}}
|
||||
|
||||
${BOOTABLES} ${subst .txt,.bin,${BOOTABLES}} :
|
||||
${BOOTABLES} ${subst .stxt,.bin,${subst .txt,.bin,${BOOTABLES}}} :
|
||||
${Q}make ${MAKEOPTS} -C boot_code $(subst boot_code/,,$@)
|
||||
|
||||
boot_code/%.txt:
|
||||
@ -48,5 +48,5 @@ clean:
|
||||
${Q}make ${MAKEOPTS} -C system clean
|
||||
${Q}make ${MAKEOPTS} -C boot_code clean
|
||||
|
||||
upload: boot_code/brainfuck_compiled.txt
|
||||
upload: boot_code/bios.stxt
|
||||
make -C system upload
|
||||
|
@ -48,6 +48,12 @@ Additionally, for ECP5 FPGAs:
|
||||
* prjtrellis : 1.4 ( database commit 4dda149b9e4f1753ebc8b011ece2fe794be1281a )
|
||||
* nextpnr : 0.6
|
||||
|
||||
Additionally, if you need a DRAM/DDR controller, the project supports litedram:
|
||||
|
||||
* Litedram : 2023.08
|
||||
* Migen : 0.9.2
|
||||
* Litex : 2023.08
|
||||
|
||||
Additionally, for FPGAs using the [foboot](https://github.com/im-tomu/foboot) bootloader
|
||||
|
||||
* dfu-util : 0.11
|
||||
|
@ -1,5 +1,5 @@
|
||||
SOURCE=brainfuck_interpreted.asm brainfuck_compiled.asm brainfuck_mandelbrot.asm pipeline_ideal.asm fibonacci.asm gnome_sort.asm cache_fill_and_empty.asm colored_led.asm
|
||||
BINARIES=$(subst .asm,.txt,${SOURCE})
|
||||
SOURCE=brainfuck_interpreted.asm brainfuck_compiled.asm brainfuck_mandelbrot.asm pipeline_ideal.asm fibonacci.asm gnome_sort.asm cache_fill_and_empty.asm colored_led.asm bios.asm
|
||||
BINARIES=$(subst .asm,.txt,${SOURCE}) $(subst .asm,.stxt,${SOURCE})
|
||||
BUILD_FILES=${BINARIES}
|
||||
BUILD_FILES+=$(subst .asm,.memdump,${SOURCE})
|
||||
BUILD_FILES+=$(subst .asm,.fst,${SOURCE})
|
||||
|
395
boot_code/bios.asm
Normal file
395
boot_code/bios.asm
Normal file
@ -0,0 +1,395 @@
|
||||
.org 0xF800
|
||||
mov sp,#STACK
|
||||
mov bx,#initdram_txt
|
||||
call print
|
||||
|
||||
WAIT_PLL:
|
||||
inw #0x20
|
||||
test al,#0x04
|
||||
jz WAIT_PLL
|
||||
;;; DO ALL INIT STUFF ;;;
|
||||
|
||||
;////sdram_software_control_on///
|
||||
MOV BX,#0x0000
|
||||
MOV AX,#0x000E
|
||||
call sdram_dfii_control_write
|
||||
;/////////////////////////////////
|
||||
|
||||
MOV BX,#0x0000
|
||||
MOV AX,#0x0000
|
||||
CALL ddrctrl_init_done_write
|
||||
|
||||
mov bx,#0x0000
|
||||
mov ax,#0x0000
|
||||
call ddrctrl_init_error_write
|
||||
|
||||
mov bx,#0x0000
|
||||
mov ax,#0x000C
|
||||
call sdram_dfii_control_write
|
||||
|
||||
MOV DL,#0xF0
|
||||
DELAY11:
|
||||
MOV AX,#0xF000
|
||||
DELAY1:
|
||||
INC AX
|
||||
JNZ DELAY1
|
||||
INC DL
|
||||
JNZ DELAY11
|
||||
|
||||
MOV BX,#0x0000
|
||||
MOV AX,#0x0000
|
||||
call sdram_dfii_pi0_address_write
|
||||
|
||||
mov bx,#0x0000
|
||||
mov ax,#0x0000
|
||||
call sdram_dfii_pi0_baddress_write
|
||||
|
||||
mov bx,#0x0000
|
||||
mov ax,#0x000E
|
||||
call sdram_dfii_control_write
|
||||
|
||||
MOV DL,#0xF0
|
||||
DELAY21:
|
||||
MOV AX,#0xF000
|
||||
DELAY2:
|
||||
INC AX
|
||||
JNZ DELAY2
|
||||
INC DL
|
||||
JNZ DELAY21
|
||||
|
||||
MOV BX,#0x0000
|
||||
MOV AX,#0x0200
|
||||
call sdram_dfii_pi0_address_write
|
||||
mov bx,#0x0000
|
||||
mov ax,#0x0002
|
||||
call sdram_dfii_pi0_baddress_write
|
||||
mov bx,#0x0000
|
||||
mov ax,#0x000F
|
||||
call command_p0
|
||||
|
||||
|
||||
MOV BX,#0x0000
|
||||
MOV AX,#0x0000
|
||||
call sdram_dfii_pi0_address_write
|
||||
mov bx,#0x0000
|
||||
mov ax,#0x0003
|
||||
call sdram_dfii_pi0_baddress_write
|
||||
mov bx,#0x0000
|
||||
mov ax,#0x000F
|
||||
call command_p0
|
||||
|
||||
|
||||
MOV BX,#0x0000
|
||||
MOV AX,#0x0006
|
||||
call sdram_dfii_pi0_address_write
|
||||
mov bx,#0x0000
|
||||
mov ax,#0x0001
|
||||
call sdram_dfii_pi0_baddress_write
|
||||
mov bx,#0x0000
|
||||
mov ax,#0x000F
|
||||
call command_p0
|
||||
|
||||
|
||||
MOV BX,#0x0000
|
||||
MOV AX,#0x0320
|
||||
call sdram_dfii_pi0_address_write
|
||||
mov bx,#0x0000
|
||||
mov ax,#0x0000
|
||||
call sdram_dfii_pi0_baddress_write
|
||||
mov bx,#0x0000
|
||||
mov ax,#0x000F
|
||||
call command_p0
|
||||
|
||||
MOV DL,#0xF0
|
||||
DELAY31:
|
||||
MOV AX,#0xF000
|
||||
DELAY3:
|
||||
INC AX
|
||||
JNZ DELAY3
|
||||
INC DL
|
||||
JNZ DELAY31
|
||||
|
||||
MOV BX,#0x0000
|
||||
MOV AX,#0x0400
|
||||
call sdram_dfii_pi0_address_write
|
||||
mov bx,#0x0000
|
||||
mov ax,#0x0000
|
||||
call sdram_dfii_pi0_baddress_write
|
||||
mov bx,#0x0000
|
||||
mov ax,#0x0003
|
||||
call command_p0
|
||||
|
||||
|
||||
|
||||
|
||||
;////sdram_software_control_off///
|
||||
MOV BX,#0x0000
|
||||
MOV AX,#0x0001
|
||||
call sdram_dfii_control_write
|
||||
;////////////////////////////////
|
||||
|
||||
;Signify end of init
|
||||
MOV BX,#0x0000
|
||||
MOV AX,#0x0001
|
||||
CALL ddrctrl_init_done_write
|
||||
|
||||
;;;;;;;;;; PROBABLY NOT NECESSARY
|
||||
MOV DL,#0xF0
|
||||
DELAY41:
|
||||
MOV AX,#0xF000
|
||||
DELAY4:
|
||||
INC AX
|
||||
JNZ DELAY4
|
||||
INC DL
|
||||
JNZ DELAY41
|
||||
|
||||
|
||||
;;; CHECK ;;;
|
||||
inw #0x20
|
||||
test al,#0x01
|
||||
jz failram
|
||||
mov bx,#OK_txt
|
||||
call print
|
||||
JMP FINISHED_DDR
|
||||
failram:
|
||||
mov bx,#FAIL_txt
|
||||
call print
|
||||
mov bx,#NOT_RDY_txt
|
||||
call print
|
||||
|
||||
inw #0x20
|
||||
test al,#0x02
|
||||
jz skip_err
|
||||
mov bx,#ERR_ASRT_txt
|
||||
call print
|
||||
skip_err:
|
||||
|
||||
inw #0x20
|
||||
test al,#0x04
|
||||
jnz skip_pll
|
||||
mov bx,#PLL_ERR_txt
|
||||
call print
|
||||
skip_pll:
|
||||
hlt
|
||||
|
||||
FINISHED_DDR:
|
||||
|
||||
MOV DI,#0x2000
|
||||
MOV AX,#0xAAAA
|
||||
MOV [DI],AX
|
||||
MOV [DI],AX
|
||||
MOV [DI],AX
|
||||
MOV [DI],AX
|
||||
MOV [DI],AX
|
||||
MOV [DI],AX
|
||||
MOV [DI],AX
|
||||
MOV [DI],AX
|
||||
MOV [DI],AX
|
||||
MOV [DI],AX
|
||||
MOV [DI],AX
|
||||
MOV AX,#0x6666
|
||||
MOV AX,[DI]
|
||||
CMP AX,#0xAAAA
|
||||
JNZ FAILED
|
||||
MOV BX,#MEMTEST_PASS
|
||||
CALL print
|
||||
|
||||
MOV AL,#0x48
|
||||
MOV [DI],AX
|
||||
MOV AL,#0x00
|
||||
MOV AX,[DI]
|
||||
out byte #0xA5
|
||||
|
||||
MOV DI,#0x3000
|
||||
MOV AL,#0x65
|
||||
MOV [DI],AX
|
||||
MOV AL,#0x00
|
||||
MOV AX,[DI]
|
||||
out byte #0xA5
|
||||
|
||||
MOV DI,#0x4000
|
||||
MOV AL,#0x6c
|
||||
MOV [DI],AX
|
||||
MOV AL,#0x00
|
||||
MOV AX,[DI]
|
||||
out byte #0xA5
|
||||
|
||||
MOV DI,#0x5000
|
||||
MOV AL,#0x6c
|
||||
MOV [DI],AX
|
||||
MOV AL,#0x00
|
||||
MOV AX,[DI]
|
||||
out byte #0xA5
|
||||
|
||||
MOV DI,#0x6000
|
||||
MOV AL,#0x6f
|
||||
MOV [DI],AX
|
||||
MOV AL,#0x00
|
||||
MOV AX,[DI]
|
||||
out byte #0xA5
|
||||
|
||||
HLT
|
||||
FAILED:
|
||||
MOV BX,#MEMTEST_FAIL
|
||||
CALL print
|
||||
|
||||
MOV DL,#0xF0
|
||||
DELAY51:
|
||||
MOV AX,#0x5000
|
||||
DELAY5:
|
||||
INC AX
|
||||
JNZ DELAY5
|
||||
INC DL
|
||||
JNZ DELAY51
|
||||
|
||||
MOV DI,#0x2000
|
||||
MOV AX,#0xAAAA
|
||||
MOV [DI],AX
|
||||
MOV [DI],AX
|
||||
MOV [DI],AX
|
||||
MOV [DI],AX
|
||||
MOV [DI],AX
|
||||
MOV [DI],AX
|
||||
MOV [DI],AX
|
||||
MOV [DI],AX
|
||||
MOV [DI],AX
|
||||
MOV [DI],AX
|
||||
MOV [DI],AX
|
||||
MOV AX,#0x0000
|
||||
MOV AX,[DI]
|
||||
CMP AL,#0xAA
|
||||
JNZ FAILED2
|
||||
MOV BX,#MEMTEST_PASS
|
||||
CALL print
|
||||
HLT
|
||||
FAILED2:
|
||||
MOV BX,#MEMTEST_FAIL
|
||||
CALL print
|
||||
MOV AX,[DI]
|
||||
CMP AL,#0xAA
|
||||
JNZ FAILED3
|
||||
MOV BX,#MEMTEST_PASS
|
||||
CALL print
|
||||
HLT
|
||||
FAILED3:
|
||||
MOV BX,#MEMTEST_FAIL
|
||||
CALL print
|
||||
HLT
|
||||
|
||||
|
||||
;;; HELPER FUNCTION
|
||||
command_p0:
|
||||
call WISHBONE_SET_DATA
|
||||
MOV AX,#0x0401 ;ORIG=0x1804L
|
||||
CALL WISHBONE_SET_ADDRESS
|
||||
CALL DO_WRITE_TRANSACTION
|
||||
MOV AX,#0x0001
|
||||
MOV BX,#0x0000
|
||||
call WISHBONE_SET_DATA
|
||||
MOV AX,#0x0402 ;ORIG=0x1808L
|
||||
CALL WISHBONE_SET_ADDRESS
|
||||
CALL DO_WRITE_TRANSACTION
|
||||
ret
|
||||
|
||||
#AX: Lower 16 bits data
|
||||
#BX: Upper 16 bits data
|
||||
sdram_dfii_pi0_address_write:
|
||||
call WISHBONE_SET_DATA
|
||||
MOV AX,#0x0403 ;ORIG=0x180cL
|
||||
CALL WISHBONE_SET_ADDRESS
|
||||
CALL DO_WRITE_TRANSACTION
|
||||
ret
|
||||
|
||||
sdram_dfii_pi0_baddress_write:
|
||||
call WISHBONE_SET_DATA
|
||||
MOV AX,#0x0404 ;ORIG=0x1810L
|
||||
CALL WISHBONE_SET_ADDRESS
|
||||
CALL DO_WRITE_TRANSACTION
|
||||
ret
|
||||
|
||||
sdram_dfii_control_write:
|
||||
call WISHBONE_SET_DATA
|
||||
MOV AX,#0x0400 ;ORIG=0x1800L
|
||||
CALL WISHBONE_SET_ADDRESS
|
||||
CALL DO_WRITE_TRANSACTION
|
||||
ret
|
||||
|
||||
ddrctrl_init_done_write:
|
||||
call WISHBONE_SET_DATA
|
||||
MOV AX,#0x0000 ;ORIG=0x0L
|
||||
CALL WISHBONE_SET_ADDRESS
|
||||
CALL DO_WRITE_TRANSACTION
|
||||
ret
|
||||
|
||||
ddrctrl_init_error_write:
|
||||
call WISHBONE_SET_DATA
|
||||
MOV AX,#0x0001 ;ORIG=0x4L
|
||||
CALL WISHBONE_SET_ADDRESS
|
||||
CALL DO_WRITE_TRANSACTION
|
||||
ret
|
||||
;
|
||||
DO_WRITE_TRANSACTION:
|
||||
mov ax,#0x01
|
||||
outw #0x46
|
||||
mov bl,#0x01
|
||||
WB_WRITE_LOOP:
|
||||
inc bl
|
||||
jz WB_WRITE_TIMEOUT
|
||||
inw #0x44
|
||||
test al,#0x01
|
||||
jz WB_WRITE_LOOP
|
||||
test al,#0x04
|
||||
jnz WB_WRITE_ERR
|
||||
ret
|
||||
WB_WRITE_TIMEOUT:
|
||||
mov bx,#WISHBONE_TIMEOUT_txt
|
||||
call print
|
||||
hlt
|
||||
WB_WRITE_ERR:
|
||||
mov bx,#WISHBONE_ERROR_txt
|
||||
call print
|
||||
hlt
|
||||
|
||||
#AX: address
|
||||
WISHBONE_SET_ADDRESS:
|
||||
outw #0x44
|
||||
ret
|
||||
|
||||
#AX: Lower 16bits
|
||||
#BX: Upper 16bits
|
||||
WISHBONE_SET_DATA:
|
||||
outw #0x40
|
||||
MOV AX,BX
|
||||
outw #0x42
|
||||
ret
|
||||
|
||||
print:
|
||||
mov al,[bx]
|
||||
cmp al,#0
|
||||
je print_exit
|
||||
out byte #0xA5
|
||||
inc bx
|
||||
jmp print
|
||||
print_exit:
|
||||
ret
|
||||
|
||||
initdram_txt: .ASCII 'Init LiteDram: \0'
|
||||
OK_txt: .ASCII 'OK\n\0'
|
||||
PLL_ERR_txt: .ASCII 'PLL_ERR \0' ; PLL_ERR: pll_lock is not asserted
|
||||
ERR_ASRT_txt: .ASCII 'ERR_ASRT \0' ; ERR_ASRT: init_error is asserted
|
||||
NOT_RDY_txt: .ASCII 'NOT_RDY \0' ; NOT READY: init_done is not asserted
|
||||
FAIL_txt: .ASCII 'FAIL\n\0'
|
||||
WISHBONE_TIMEOUT_txt: .ASCII 'FAIL\nWISHBONE TIMEOUT\0'
|
||||
WISHBONE_ERROR_txt: .ASCII 'FAIL\nWISHBONE ERROR\0'
|
||||
MEMTEST_PASS: .ASCII 'MEMTEST PASSED\n\0'
|
||||
MEMTEST_FAIL: .ASCII 'MEMTEST FAILED\n\0'
|
||||
.BLKB 18 ; Using the text as stack space for the compiled program
|
||||
STACK: ; brainfuck_mandelbrot depends on stack being at the end
|
||||
|
||||
.ORG 0xFFF0
|
||||
MOV AX,#0xF800
|
||||
JMP AX
|
||||
|
||||
|
||||
.ORG 0xFFFF
|
||||
DB 0x00 ;Make sure a full 64KiB image
|
@ -1,15 +1,22 @@
|
||||
; Interrupt table and routines
|
||||
INCLUDE dos_layer.asm
|
||||
|
||||
org 0x100
|
||||
INCLUDE brainfuck_compiler_v1.asm
|
||||
output_program:
|
||||
|
||||
org 0xF800
|
||||
mov sp,#SMALL_STACK
|
||||
call INIT_INT_VECT_TABLE
|
||||
INCLUDE brainfuck_compiler_v1.asm
|
||||
SMALL_STACK:
|
||||
|
||||
INCLUDE dos_layer.asm
|
||||
prog:
|
||||
INCLUDE hello_9086.bf.asm
|
||||
|
||||
|
||||
output_program:
|
||||
|
||||
.ORG 0xFFF0
|
||||
MOV AX,#0x0100
|
||||
MOV AX,#0xF800
|
||||
JMP AX
|
||||
|
||||
.ORG 0xFFFF
|
||||
DB 0x00 ;Make sure a full 64KiB image
|
||||
|
@ -17,6 +17,8 @@
|
||||
; You should have received a copy of the GNU General Public License
|
||||
; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
; 0x0000-0x0100 int vector 0x0100-0x0700 data 0x0700-0xC000 program data
|
||||
|
||||
mov sp,#STACK
|
||||
mov bx,#bootup_msg
|
||||
mov ah,#0x02
|
||||
@ -39,7 +41,7 @@ jmp print2
|
||||
exit:
|
||||
|
||||
MOV SI,#prog
|
||||
MOV DI,#output_program
|
||||
MOV DI,#0x0700
|
||||
;CL: write concat CH: move concat
|
||||
MOV CX,#0
|
||||
JMP COMPILE ; Moving some functions above the main switch to make shot jumps work
|
||||
@ -148,8 +150,9 @@ jne print3
|
||||
|
||||
MOV AL,#0xF4 ; hlt
|
||||
MOV [DI],AL
|
||||
MOV BX,#DATA
|
||||
MOV AX,#output_program
|
||||
; From 0x100 its free but i'll do 0x200 in case it start writing earlier
|
||||
MOV BX,#0x0200
|
||||
MOV AX,#0x0700
|
||||
JMP AX
|
||||
|
||||
;;;;;;;;; . ;;;;;;;;;
|
||||
@ -250,18 +253,19 @@ MOV AL,#0x43 ; inc %bx
|
||||
STOSB
|
||||
JMP MOVES_FLUSHED
|
||||
|
||||
|
||||
MOVES_ONE_LEFT:
|
||||
MOV AL,#0x4b ; dec %bx
|
||||
STOSB
|
||||
JMP MOVES_FLUSHED
|
||||
|
||||
|
||||
MOVES_FLUSHED:
|
||||
MOV CH,#0
|
||||
RET
|
||||
|
||||
bootup_msg: .ASCII 'Native 8086 brainfuck compiler v1\n'
|
||||
compiling: .ASCII 'Compiling...\0'
|
||||
compiled: .ASCII '\rCompiled! \n'
|
||||
DATA: .BLKB 560
|
||||
.BLKB 200
|
||||
STACK:
|
||||
compiling: .ASCII 'Compiling...\0'
|
||||
bootup_msg: .ASCII 'Native 8086 brainfuck compiler v1\n'
|
||||
.BLKB 6 ; Using the text as stack space for the compiled program
|
||||
STACK: ; brainfuck_mandelbrot depends on stack being at the end
|
||||
|
@ -1,16 +1,16 @@
|
||||
; Interrupt table and routines
|
||||
INCLUDE dos_layer.asm
|
||||
|
||||
ORG 0x100
|
||||
ORG 0xF000
|
||||
mov sp,#STACK
|
||||
call INIT_INT_VECT_TABLE
|
||||
INCLUDE brainfuck_interpreter_v0.asm
|
||||
|
||||
.BLKB 200
|
||||
STACK:
|
||||
INCLUDE dos_layer.asm
|
||||
|
||||
prog:
|
||||
INCLUDE hello_9086.bf.asm
|
||||
|
||||
.ORG 0xFFF0
|
||||
MOV AX,#0x0100
|
||||
MOV AX,#0xF000
|
||||
JMP AX
|
||||
|
@ -1,14 +1,22 @@
|
||||
; Interrupt table and routines
|
||||
INCLUDE dos_layer.asm
|
||||
;I got this down to 11428 bytes
|
||||
|
||||
.ORG 0x100
|
||||
org 0x100
|
||||
output_program:
|
||||
|
||||
org 0xD000
|
||||
mov sp,#SMALL_STACK
|
||||
call INIT_INT_VECT_TABLE
|
||||
INCLUDE brainfuck_compiler_v1.asm
|
||||
SMALL_STACK:;Stack of compiler is at the end of file
|
||||
|
||||
INCLUDE dos_layer.asm
|
||||
prog:
|
||||
INCLUDE mandelbrot.bf.asm
|
||||
|
||||
output_program:
|
||||
|
||||
.ORG 0xFFF0
|
||||
MOV AX,#0x0100
|
||||
MOV AX,#0xD000
|
||||
JMP AX
|
||||
|
||||
.ORG 0xFFFF
|
||||
DB 0x00 ;Make sure a full 64KiB image
|
||||
|
@ -1,6 +1,4 @@
|
||||
INCLUDE dos_layer.asm
|
||||
|
||||
.org 0x100
|
||||
.org 0xE000
|
||||
mov sp,#STACK
|
||||
|
||||
MAIN_LOOP:
|
||||
@ -19,13 +17,14 @@ out byte #0xB0
|
||||
MOV SI,#RESERVED
|
||||
MOV DI,#RESERVED
|
||||
MOV AL,#0x68 ; 'h'
|
||||
STOSB
|
||||
MOV AL,#0x00
|
||||
MOV AL,[SI]
|
||||
#STOSB
|
||||
#MOV AL,#0x00
|
||||
#MOV AL,[SI]
|
||||
|
||||
MOV AH,#0x02
|
||||
MOV DL,AL
|
||||
INT #0x21
|
||||
#MOV AH,#0x02
|
||||
#MOV DL,AL
|
||||
#INT #0x21
|
||||
out byte #0xA5
|
||||
|
||||
MOV AL,#0x65
|
||||
out byte #0xA5
|
||||
@ -49,13 +48,18 @@ JNZ DELAY21
|
||||
MOV AL,#0x00
|
||||
out byte #0xB0
|
||||
|
||||
MOV AX,#0x0100
|
||||
MOV AX,#0xE000
|
||||
JMP AX
|
||||
|
||||
RESERVED: DB 0x48 ; 'H'
|
||||
.BLKB 200
|
||||
.BLKB 100
|
||||
STACK:
|
||||
|
||||
#INCLUDE dos_layer.asm
|
||||
|
||||
.ORG 0xFFF0
|
||||
MOV AX,#0x0100
|
||||
MOV AX,#0xE000
|
||||
JMP AX
|
||||
|
||||
.ORG 0xFFFF
|
||||
DB 0x00 ;Make sure a full 64KiB image
|
||||
|
@ -1,7 +1,3 @@
|
||||
.ORG 0x84 ; INT 21
|
||||
DW 0xFFFF ; Code Segment
|
||||
DW PRINT_INT_HANDLE ; Program Counter
|
||||
|
||||
PRINT_INT_HANDLE:
|
||||
push AX
|
||||
CMP AH,#0x02
|
||||
@ -14,3 +10,15 @@ MOV AL,DL
|
||||
out byte #0xA5
|
||||
POP AX
|
||||
iret
|
||||
|
||||
INIT_INT_VECT_TABLE:
|
||||
push AX
|
||||
push DI
|
||||
MOV DI,#0x0084
|
||||
MOV AX,#0xFFFF
|
||||
STOSW
|
||||
MOV AX,#PRINT_INT_HANDLE
|
||||
STOSW
|
||||
POP DI
|
||||
POP AX
|
||||
RET
|
||||
|
@ -1,8 +1,8 @@
|
||||
INCLUDE dos_layer.asm
|
||||
|
||||
|
||||
org 0x100
|
||||
org 0xF000
|
||||
mov sp,#STACK
|
||||
call INIT_INT_VECT_TABLE
|
||||
|
||||
MOV AX,#0x1
|
||||
MOV BX,#0x1
|
||||
@ -26,6 +26,7 @@ MOV DL,#0x0a
|
||||
INT #0x21
|
||||
|
||||
hlt
|
||||
INCLUDE dos_layer.asm
|
||||
|
||||
|
||||
.BLKB 200
|
||||
@ -33,6 +34,6 @@ STACK:
|
||||
INCLUDE helpers.asm
|
||||
|
||||
.ORG 0xFFF0
|
||||
MOV AX,#0x0100
|
||||
MOV AX,#0xF000
|
||||
JMP AX
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
INCLUDE dos_layer.asm
|
||||
|
||||
.org 0x100
|
||||
.org 0xF000
|
||||
mov sp,#STACK
|
||||
MOV SI,#DATA
|
||||
call INIT_INT_VECT_TABLE
|
||||
|
||||
GNOME_SORT:
|
||||
CMP SI,#DATA+23
|
||||
@ -37,6 +37,7 @@ MOV DL,#0x0a
|
||||
INT #0x21
|
||||
|
||||
hlt
|
||||
INCLUDE dos_layer.asm
|
||||
|
||||
DATA: DB 0x51, 0x17, 0x37, 0x5d, 0x06, 0x3f, 0x51, 0x8b
|
||||
DB 0xa5, 0x33, 0x54, 0xdf, 0xae, 0xee, 0x3a, 0x18
|
||||
@ -48,6 +49,8 @@ STACK:
|
||||
INCLUDE helpers.asm
|
||||
|
||||
.ORG 0xFFF0
|
||||
MOV AX,#0x0100
|
||||
MOV AX,#0xF000
|
||||
JMP AX
|
||||
|
||||
.ORG 0xFFFF
|
||||
DB 0x00 ;Make sure a full 64KiB image
|
||||
|
@ -1,4 +1,4 @@
|
||||
org 0x100
|
||||
org 0xF000
|
||||
inc ax
|
||||
inc bx
|
||||
inc ax
|
||||
@ -102,5 +102,5 @@ inc bx
|
||||
hlt
|
||||
|
||||
.ORG 0xFFF0
|
||||
MOV AX,#0x0100
|
||||
MOV AX,#0xF000
|
||||
JMP AX
|
||||
|
12
common.mk
12
common.mk
@ -39,7 +39,9 @@ ifeq "${QUIET}" "1"
|
||||
QUIET_DFU_SUFFIX = @echo ' DFU-SUFFIX '$@;
|
||||
QUIET_DFU_UTIL = @echo ' DFU-UTIL '$<;
|
||||
|
||||
QUIET_CLEAN = @printf ' CLEAN %s\n' $1;
|
||||
QUIET_DOWNLOAD = @echo ' DOWNLOAD '$@;
|
||||
|
||||
QUIET_CLEAN = @echo ' CLEAN '$1;
|
||||
QUIET_VERILATOR_RUN = @printf ' %s %s\n' $1 $2;
|
||||
Q = @
|
||||
MAKEOPTS=--no-print-directory
|
||||
@ -54,6 +56,13 @@ run: $(subst .txt,.run,${BOOT_CODE})
|
||||
wave: $(subst .txt,.wave,${BOOT_CODE})
|
||||
disas: $(subst .txt,.disas,${BOOT_CODE})
|
||||
|
||||
# Assembling code
|
||||
%.stxt: %.bin
|
||||
${Q}dd if=/dev/zero bs=1 count=2048 of="$(subst .bin,.stage,$<)" status=none
|
||||
${Q}dd if="$<" bs=1 skip=63488 of="$(subst .bin,.stage,$<)" conv=notrunc,nocreat status=none
|
||||
${Q}xxd -ps -c 2 "$(subst .bin,.stage,$<)" > "$@"
|
||||
${Q}rm "$(subst .bin,.stage,$<)"
|
||||
|
||||
# Assembling code
|
||||
%.txt:%.bin
|
||||
${Q}dd if=/dev/zero bs=1 count=65536 of="$(subst .bin,.stage,$<)" status=none
|
||||
@ -61,6 +70,7 @@ disas: $(subst .txt,.disas,${BOOT_CODE})
|
||||
${Q}xxd -ps -c 2 "$(subst .bin,.stage,$<)" > "$@"
|
||||
${Q}rm "$(subst .bin,.stage,$<)"
|
||||
|
||||
|
||||
ifeq "${NO_ASM}" "0"
|
||||
%.bin:%.asm
|
||||
${QUIET_AS}
|
||||
|
@ -46,14 +46,14 @@ VERILATOR_OPTS += -x-assign fast --x-initial fast
|
||||
# COMPILING
|
||||
${SYSTEM_VVP} : ${TOP_LEVEL_SOURCE} ${SOURCES} ${INCLUDES} ${EVENT_SIM_TESTBENCH}
|
||||
${QUIET_IVERILOG}
|
||||
${Q}iverilog -g2012 -DBUILTIN_RAM=32768 -D CALCULATE_IPC -D OUTPUT_JSON_STATISTICS -o "$@" ${TOP_LEVEL_SOURCE} ${SOURCES} ${EVENT_SIM_TESTBENCH}
|
||||
${Q}iverilog -g2012 -D CALCULATE_IPC -D OUTPUT_JSON_STATISTICS -o "$@" ${TOP_LEVEL_SOURCE} ${SOURCES} ${EVENT_SIM_TESTBENCH}
|
||||
|
||||
${VERILATOR_BIN}: ${VERILATOR_BIN}.mk
|
||||
${Q}make ${MAKEOPTS} OPT_FAST="-O2 -march=native -mtune=native" -C obj_dir -f ../verilator_makefile Vsystem
|
||||
|
||||
${VERILATOR_BIN}.mk: ${VERILATOR_TESTBENCH} ${TOP_LEVEL_SOURCE} ${SOURCES} ${INCLUDES}
|
||||
${QUIET_VERILATOR}
|
||||
${Q}verilator -DBUILTIN_RAM=32768 -UNOT_FULL -DCALCULATE_IPC -DOUTPUT_JSON_STATISTICS ${VERILATOR_OPTS} $^
|
||||
${Q}verilator -DCALCULATE_IPC -DOUTPUT_JSON_STATISTICS ${VERILATOR_OPTS} $^
|
||||
|
||||
include fpga_config/${FPGA_BOARD}/config.mk
|
||||
|
||||
@ -69,22 +69,23 @@ endif
|
||||
ECP5_TARGETS=synth_ecp5.json synth_ecp5_out.config synth_ecp5.bit synth_ecp5.dfu synth_pnr_report.json
|
||||
ECP5_TARGETS+=abc.history # created from yosys
|
||||
|
||||
EXTRA_SYNTHESIS_SOURCES=peripherals/I2C_driver.v peripherals/ascii_to_HD44780_driver.v peripherals/pcf8574_for_HD44780.v
|
||||
EXTRA_SYNTHESIS_SOURCES=peripherals/I2C_driver.v peripherals/ascii_to_HD44780_driver.v peripherals/pcf8574_for_HD44780.v peripherals/Wishbone_IO_driver.v peripherals/Wishbone_memory_driver.v
|
||||
EXTERNAL_IP_SOURCES=external_ip/litedram_core_ecp5_phy.v
|
||||
|
||||
simplified_ucode.txt:ucode.txt
|
||||
${Q}tr 'x' '0' < $^ | sed 's@//.*@@' | grep ^@ |sort | sed 's/.* .//;s/ $$//' | tr -d _ > $@
|
||||
|
||||
#TODO: we are relying on yosys to trim the input program txt file and hope its enough for the whole program...
|
||||
synth_ecp5.json: ${SOURCES} ${TOP_LEVEL_SOURCE} fpga_config/${FPGA_BOARD}/fpga_top.v ${EXTRA_SYNTHESIS_SOURCES} ${INCLUDES} ../boot_code/brainfuck_compiled.txt simplified_ucode.txt
|
||||
synth_ecp5.json: ${SOURCES} fpga_config/${FPGA_BOARD}/fpga_top.v ${EXTRA_SYNTHESIS_SOURCES} ${EXTERNAL_IP_SOURCES} ${INCLUDES} ../boot_code/bios.stxt simplified_ucode.txt
|
||||
${QUIET_YOSYS}
|
||||
${Q} yosys -q -D BUILTIN_RAM=2048 -D NOT_FULL -p 'read -sv '"${SOURCES} ${TOP_LEVEL_SOURCE} fpga_config/${FPGA_BOARD}/fpga_top.v ${EXTRA_SYNTHESIS_SOURCES} ; synth_ecp5 -json $@ -abc9 -top fpga_top"
|
||||
${Q} yosys -q -p 'read_verilog -defer -noautowire -sv '"${SOURCES} fpga_config/${FPGA_BOARD}/fpga_top.v ${EXTRA_SYNTHESIS_SOURCES} ${EXTERNAL_IP_SOURCES}; attrmap -tocase keep -imap keep="true" keep=1 -imap keep="false" keep=0 -remove keep=0; synth_ecp5 -json $@ -abc9 -top fpga_top"
|
||||
|
||||
RANDOM :::= $(shell seq 1 200|sort -R|head -n1)
|
||||
|
||||
synth_ecp5_out.config:synth_ecp5.json
|
||||
${QUIET_NEXTPNR}
|
||||
${Q}printf '\e[1;30mNotice: nextpnr rng seed is : %s\e[0m\n' "${RANDOM}"
|
||||
${Q} nextpnr-ecp5 --seed ${RANDOM} --Werror -q --json $< --textcfg $@.1 ${NEXTPNR_ECP5_DEV} --package ${ECP5_PACKAGE} --lpf fpga_config/${FPGA_BOARD}/pin_constraint.pcf --report=synth_pnr_report.json
|
||||
${Q} nextpnr-ecp5 --threads 5 --timing-allow-fail --seed ${RANDOM} --Werror -q --json $< --textcfg $@.1 ${NEXTPNR_ECP5_DEV} --package ${ECP5_PACKAGE} --speed 8 --lpf fpga_config/${FPGA_BOARD}/pin_constraint.pcf --report=synth_pnr_report.json
|
||||
${Q}../tools/parse_nextpnr_stats.sh --brief synth_pnr_report.json
|
||||
${Q}mv "$@.1" "$@"
|
||||
|
||||
@ -103,8 +104,15 @@ upload_orangecrab:synth_ecp5.dfu
|
||||
${QUIET_DFU_UTIL}
|
||||
${Q}stdbuf -o0 dfu-util --download "$<" |stdbuf -o0 tr '\n' '\a' | stdbuf -o0 tr '\r' '\n' | grep Download --line-buffered | stdbuf -o0 tr '\n' '\r' |stdbuf -o0 tr '\a' '\n'
|
||||
|
||||
NEXTPNR_SEED=186
|
||||
|
||||
nextpnr-gui: synth_ecp5.json
|
||||
${Q} nextpnr-ecp5 --json $< ${NEXTPNR_ECP5_DEV} --package ${ECP5_PACKAGE} --lpf fpga_config/${FPGA_BOARD}/pin_constraint.pcf --gui
|
||||
${QUIET_NEXTPNR}
|
||||
${Q} nextpnr-ecp5 --seed ${NEXTPNR_SEED} --json $< ${NEXTPNR_ECP5_DEV} --package ${ECP5_PACKAGE} --speed 8 --lpf fpga_config/${FPGA_BOARD}/pin_constraint.pcf --gui
|
||||
|
||||
external_ip/litedram_core_ecp5_phy.v:
|
||||
${QUIET_DOWNLOAD}
|
||||
${Q}../tools/gen_litedram.sh "$@"
|
||||
|
||||
upload: upload_orangecrab
|
||||
|
||||
|
13
system/biu.v
13
system/biu.v
@ -46,6 +46,7 @@ module BIU (
|
||||
/**************** OUTSIDE WORLD ****************/
|
||||
/* */ ,output wire [19:0] external_address_bus
|
||||
/* */ ,input [15:0] external_data_bus_read,output [15:0] external_data_bus_write,output reg read, output reg write,output reg BHE,output reg IOMEM
|
||||
/* */ ,input wait_state
|
||||
|
||||
/**************** OUTPUT TO DE ****************/
|
||||
/* */ ,output reg [31:0] INSTRUCTION, output reg VALID_INSTRUCTION, output reg [15:0] INSTRUCTION_LOCATION
|
||||
@ -105,7 +106,7 @@ always @(posedge clock) begin
|
||||
FIFO_end <= `L1_CACHE_SIZE'b0;
|
||||
end else if ( jump_req ) begin
|
||||
FIFO_start <= FIFO_end ;
|
||||
INSTRUCTION_ADDRESS <= { 4'b0 , ADDRESS_INPUT };
|
||||
INSTRUCTION_ADDRESS <= { 4'hF , ADDRESS_INPUT };
|
||||
INSTRUCTION_LOCATION <= ADDRESS_INPUT;
|
||||
func <= 1;
|
||||
if (biu_state==`BIU_READ)
|
||||
@ -115,6 +116,8 @@ always @(posedge clock) begin
|
||||
FIFO_start <= FIFO_start + {{`L1_CACHE_SIZE-3{1'b0}},Isize};
|
||||
/* verilator lint_on BLKSEQ */
|
||||
INSTRUCTION_LOCATION <= INSTRUCTION_LOCATION + {13'd0,Isize};
|
||||
end else if (wait_state==1)begin
|
||||
// nothing...
|
||||
end else begin
|
||||
case(biu_state)
|
||||
`BIU_HALT: begin
|
||||
@ -122,14 +125,14 @@ always @(posedge clock) begin
|
||||
`BIU_NEXT_ACTION: begin /* decide if we can read, if we are full or if we need to do something else */
|
||||
if (write_request) begin
|
||||
func<=0;
|
||||
DATA_ADDRESS <= { 4'b0 , ADDRESS_INPUT };
|
||||
DATA_ADDRESS <= { 4'hF , ADDRESS_INPUT };
|
||||
IOMEM <= MEM_OR_IO;
|
||||
biu_state <= (Wbit==0) ? `BIU_PUT_BYTE : (ADDRESS_INPUT[0:0]?`BIU_PUT_UNALIGNED_16BIT_DATA:`BIU_PUT_ALIGNED_16BIT_DATA) ;
|
||||
INSTRUCTION_ADDRESS <= {4'b0,INSTRUCTION_LOCATION} ;
|
||||
INSTRUCTION_ADDRESS <= {4'hF,INSTRUCTION_LOCATION} ;
|
||||
FIFO_end<=FIFO_start;
|
||||
end else if ( read_request ) begin
|
||||
func<=0;
|
||||
DATA_ADDRESS <= { 4'b0 , ADDRESS_INPUT };
|
||||
DATA_ADDRESS <= { 4'hF , ADDRESS_INPUT };
|
||||
IOMEM <= MEM_OR_IO;
|
||||
read <= 0;
|
||||
BHE <= 0;
|
||||
@ -275,7 +278,7 @@ always @(posedge clock) begin
|
||||
FIFO_end <= `L1_CACHE_SIZE'b0;
|
||||
/* verilator lint_on BLKSEQ */
|
||||
biu_state <= `BIU_NEXT_ACTION;
|
||||
INSTRUCTION_ADDRESS <= 20'h0FFF0;
|
||||
INSTRUCTION_ADDRESS <= 20'hFFFF0;
|
||||
INSTRUCTION_LOCATION <= 16'hFFF0;
|
||||
VALID_DATA <= 0;
|
||||
sane<=1;
|
||||
|
@ -1,8 +1,4 @@
|
||||
.ORG 0x84 ; INT 21
|
||||
DW 0xFFFF ; Code Segment
|
||||
DW PRINT_INT_HANDLE ; Program Counter
|
||||
|
||||
.ORG 0x0100
|
||||
.ORG 0xFF00
|
||||
start:
|
||||
MOV SP,#STACK
|
||||
MOV AX,#0x0000
|
||||
@ -26,20 +22,14 @@ dec cx
|
||||
cmp CX,#0x00
|
||||
MOV CH,#0x9A
|
||||
inw #0x20
|
||||
CMP AL,#0xCD
|
||||
CMP AX,#0xABCD
|
||||
jz WAZZ
|
||||
mov al,#'0
|
||||
out byte #0xA5
|
||||
hlt
|
||||
WAZZ:
|
||||
CMP AH,#0xAB
|
||||
jz WAZZ2
|
||||
mov al,#'0
|
||||
out byte #0xA5
|
||||
hlt
|
||||
WAZZ2:
|
||||
mov al,#'1
|
||||
outb #0xA5
|
||||
out byte #0xA5
|
||||
hlt
|
||||
TEST_:
|
||||
ADD AX,#0xDEAD
|
||||
@ -57,5 +47,5 @@ iret
|
||||
STACK:
|
||||
|
||||
.ORG 0xFFF0
|
||||
MOV AX,#0x0100
|
||||
MOV AX,#0xFF00
|
||||
JMP AX
|
||||
|
@ -46,15 +46,6 @@
|
||||
* . : ... */
|
||||
`define L1_CACHE_SIZE 4
|
||||
|
||||
//// These are usually set at build time
|
||||
//
|
||||
// /* This is the "virtual" synthesised ram, so for example on an FPGA
|
||||
// * This would be made inside the fabric of the fpga. */
|
||||
// `define BUILTIN_RAM 512
|
||||
// ////// ATTENTION: PLEASE IF BUILTIN_RAM DOESN'T COVER THE ENTIRE (CURRENTLY)
|
||||
// // 16 BIT RANGE, I.E. ISN'T 32768, PLEASE SET THE FOLLOWING FLAG
|
||||
// `define NOT_FULL
|
||||
|
||||
|
||||
/********** Internal **********/
|
||||
`ifdef SYNTHESIS
|
||||
|
@ -18,10 +18,12 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
`include "error_header.v"
|
||||
`ifdef OUTPUT_JSON_STATISTICS
|
||||
`include "config.v"
|
||||
`endif
|
||||
|
||||
module fpga_top(
|
||||
input clk48,
|
||||
|
||||
input user_button,
|
||||
// output reset_n,
|
||||
|
||||
@ -29,23 +31,68 @@ module fpga_top(
|
||||
output rgb_led0_g,
|
||||
output rgb_led0_b,
|
||||
|
||||
output wire [15:0] ddram_a, // [15:13] are unused in litex as well, they just also route them through a trellis block
|
||||
output wire [2:0] ddram_ba,
|
||||
output wire ddram_cas_n,
|
||||
output wire ddram_cke,
|
||||
output wire ddram_clk_p,
|
||||
output wire ddram_cs_n,
|
||||
output wire [1:0] ddram_dm,
|
||||
input wire [15:0] ddram_dq,
|
||||
input wire [1:0] ddram_dqs_p,
|
||||
output wire [1:0] ddram_gnd,
|
||||
output wire ddram_odt,
|
||||
output wire ddram_ras_n,
|
||||
output wire ddram_reset_n,
|
||||
output wire [5:0] ddram_vccio,
|
||||
output wire ddram_we_n,
|
||||
|
||||
inout gpio_0,/*sda*/
|
||||
output gpio_1 /*scl*/
|
||||
);
|
||||
|
||||
assign ddram_a[15:13] = 3'b0;
|
||||
assign ddram_vccio = 6'd63;
|
||||
assign ddram_gnd = 2'd0;
|
||||
|
||||
wire HALT;
|
||||
wire [`ERROR_BITS-1:0]ERROR;
|
||||
wire [19:0] address_bus;
|
||||
wire [15:0] data_bus_read,data_bus_write;
|
||||
wire rd,wr,BHE,IOMEM;
|
||||
|
||||
wire CPU_SPEED=clk48;
|
||||
|
||||
system system(
|
||||
/* MISC */ CPU_SPEED,reset
|
||||
/* MEMORY / IO */ ,address_bus,data_bus_read,data_bus_write,BHE,rd,wr,IOMEM,HALT,ERROR
|
||||
wire CPU_SPEED;
|
||||
|
||||
processor p(
|
||||
.clock(CPU_SPEED),
|
||||
.reset(reset),
|
||||
.HALT(HALT),
|
||||
.ERROR(ERROR),
|
||||
.external_address_bus(address_bus),
|
||||
.external_data_bus_read(data_bus_read),
|
||||
.external_data_bus_write(data_bus_write),
|
||||
.wait_state(wait_state),
|
||||
.read(rd),
|
||||
.write(wr),
|
||||
.BHE(BHE),
|
||||
.IOMEM(IOMEM)
|
||||
`ifdef CALCULATE_IPC
|
||||
/* STATISTICS */ ,.new_instruction(new_instruction)
|
||||
`endif
|
||||
`ifdef OUTPUT_JSON_STATISTICS
|
||||
/* */ ,.L1_SIZE_STAT(L1_SIZE_STAT), .VALID_INSTRUCTION_STAT(VALID_INSTRUCTION_STAT), .jump_req_debug(jump_req_debug)
|
||||
`endif
|
||||
);
|
||||
|
||||
`ifdef CALCULATE_IPC
|
||||
wire new_instruction;
|
||||
`endif
|
||||
`ifdef OUTPUT_JSON_STATISTICS
|
||||
wire [`L1_CACHE_SIZE-1:0]L1_SIZE_STAT;
|
||||
wire VALID_INSTRUCTION_STAT;
|
||||
wire jump_req_debug;
|
||||
`endif
|
||||
reg [2:0]rgb_led_color;
|
||||
assign rgb_led0_r=rgb_led_color[0];
|
||||
assign rgb_led0_g=rgb_led_color[1];
|
||||
@ -80,7 +127,7 @@ reg [1:0] state=0;
|
||||
|
||||
always @(posedge counter[15]) begin
|
||||
if(user_button==0)
|
||||
state=2'b00;
|
||||
state<=2'b00;
|
||||
case (state)
|
||||
2'b00:begin
|
||||
reset<=0;
|
||||
@ -95,7 +142,6 @@ always @(posedge counter[15]) begin
|
||||
endcase
|
||||
end
|
||||
|
||||
|
||||
//------------------------------------------//
|
||||
// Cache to allow the slow display to have a
|
||||
// chance to keep up with the relentless CPU
|
||||
@ -135,6 +181,189 @@ end
|
||||
|
||||
wire I2C_SPEED=counter[7];
|
||||
|
||||
|
||||
wire [15:0]boot_rom_data_bus_read;
|
||||
wire [15:0]boot_rom_data_bus_write;
|
||||
|
||||
assign boot_rom_data_bus_write=data_bus_write;
|
||||
|
||||
wire boot_rom_cs_n;
|
||||
|
||||
doublemem #( .RAM_SIZE_IN_BYTES(2048) ) boot_rom
|
||||
( address_bus[10:0],boot_rom_data_bus_read,boot_rom_data_bus_write,rd,wr,BHE,boot_rom_cs_n,CPU_SPEED );
|
||||
|
||||
/// Memory Map
|
||||
|
||||
assign data_bus_read = ( IOMEM == 1 ) ? data_bus_read_IO : data_bus_read_MEM ;
|
||||
wire [15:0] data_bus_read_IO = ( address_bus[7:1] == 7'h10 ) ? LITEDRAM_STATUS_REGISTER : Wishbone_driver_data_bus_read;
|
||||
|
||||
|
||||
assign boot_rom_cs_n = !((IOMEM==0)&&(address_bus[15:12]==4'hF));
|
||||
|
||||
wire [15:0] data_bus_read_MEM = (address_bus[15:12]==4'hF)?boot_rom_data_bus_read:data_bus_read_DDR3;
|
||||
|
||||
wire DDR3_ram_cs = (IOMEM==0)&&(address_bus[15:12]!=4'hF);
|
||||
//
|
||||
// 0x20 | DDR STATUS BYTE1 |
|
||||
// 0x21 | DDR STATUS BYTE1 |
|
||||
// | |
|
||||
// - | -- |
|
||||
// | |
|
||||
// 0x30 | WISHBONE |
|
||||
// .. | .. |
|
||||
// 0x3F | WISHBONE |
|
||||
//
|
||||
assign wishbone_cs=!((IOMEM==1)&&(address_bus[7:4] == 4'h4));
|
||||
|
||||
/// DDR3 Controller
|
||||
|
||||
wire ddr3_init_done,ddr3_init_error,ddr3_pll_locked;
|
||||
|
||||
wire [31:0] ddr3_read_data;
|
||||
wire [31:0] ddr3_write_data;
|
||||
|
||||
reg [15:0]DDR3_data_bus_read;
|
||||
|
||||
assign ddr3_write_data={16'd0,data_bus_write};
|
||||
|
||||
wire [15:0]Wishbone_driver_data_bus_read;
|
||||
wire [15:0]Wishbone_driver_data_bus_write=data_bus_write;
|
||||
|
||||
wire wishbone_cs;
|
||||
|
||||
Wishbone_IO_driver Wishbone_IO_driver(
|
||||
///// GENERAL //////
|
||||
.clock(CPU_SPEED),
|
||||
.reset_n(reset),
|
||||
|
||||
////// CPU INTERFACE ///////
|
||||
.address(address_bus[3:1]),
|
||||
.data_bus_in(Wishbone_driver_data_bus_write),
|
||||
.data_bus_out(Wishbone_driver_data_bus_read),
|
||||
.read_n(rd),
|
||||
.write_n(wr),
|
||||
.chip_select_n(wishbone_cs),
|
||||
|
||||
////// WISHBONE INTERFACE /////
|
||||
.wb_ctrl_ack(wb_ctrl_ack),
|
||||
.wb_ctrl_adr(wb_ctrl_adr),
|
||||
.wb_ctrl_cyc(wb_ctrl_cyc),
|
||||
.wb_ctrl_err(wb_ctrl_err),
|
||||
.wb_ctrl_sel(wb_ctrl_sel),
|
||||
.wb_ctrl_stb(wb_ctrl_stb),
|
||||
.wb_ctrl_we(wb_ctrl_we),
|
||||
.wb_ctrl_bte(wb_ctrl_bte),
|
||||
.wb_ctrl_cti(wb_ctrl_cti),
|
||||
.wb_ctrl_dat_r(wb_ctrl_dat_r),
|
||||
.wb_ctrl_dat_w(wb_ctrl_dat_w)
|
||||
);
|
||||
|
||||
|
||||
wire [15:0] LITEDRAM_STATUS_REGISTER = { 13'd0, ddr3_pll_locked ,ddr3_init_error, ddr3_init_done };
|
||||
wire [15:0] data_bus_read_DDR3;
|
||||
|
||||
Wishbone_memory_driver Wishbone_memory_driver(
|
||||
///// GENERAL //////
|
||||
.clock(CPU_SPEED),
|
||||
.reset_n(reset),
|
||||
|
||||
////// CPU INTERFACE ///////
|
||||
.address(address_bus),
|
||||
.data_bus_in(data_bus_write),
|
||||
.data_bus_out(data_bus_read_DDR3),
|
||||
.wait_state(wait_state),
|
||||
.read_n(rd),
|
||||
.write_n(wr),
|
||||
.chip_select_n(DDR3_ram_cs&&ddr3_init_done),
|
||||
|
||||
////// WISHBONE INTERFACE /////
|
||||
.wb_mem_ack(wb_mem_ack),
|
||||
.wb_mem_adr(wb_mem_adr),
|
||||
.wb_mem_cyc(wb_mem_cyc),
|
||||
.wb_mem_err(wb_mem_err),
|
||||
.wb_mem_sel(wb_mem_sel),
|
||||
.wb_mem_stb(wb_mem_stb),
|
||||
.wb_mem_we(wb_mem_we),
|
||||
.wb_mem_data_r(wb_mem_data_r),
|
||||
.wb_mem_data_w(wb_mem_data_w)
|
||||
);
|
||||
|
||||
wire wait_state;
|
||||
|
||||
wire wb_ctrl_ack;
|
||||
wire [29:0] wb_ctrl_adr;
|
||||
wire [1:0] wb_ctrl_bte;
|
||||
wire [2:0] wb_ctrl_cti;
|
||||
wire wb_ctrl_cyc;
|
||||
wire [31:0] wb_ctrl_dat_r;
|
||||
wire [31:0] wb_ctrl_dat_w;
|
||||
wire wb_ctrl_err;
|
||||
wire [3:0] wb_ctrl_sel;
|
||||
wire wb_ctrl_stb;
|
||||
wire wb_ctrl_we;
|
||||
|
||||
wire wb_mem_ack;
|
||||
wire [24:0] wb_mem_adr;
|
||||
wire wb_mem_cyc;
|
||||
wire [31:0] wb_mem_data_r;
|
||||
wire [31:0] wb_mem_data_w;
|
||||
wire wb_mem_err;
|
||||
wire [3:0] wb_mem_sel;
|
||||
wire wb_mem_stb;
|
||||
wire wb_mem_we;
|
||||
|
||||
litedram_core DDR3_RAM_DRIVER(
|
||||
////// GENERAL ///////
|
||||
.clk(clk48),
|
||||
.user_clk(CPU_SPEED),
|
||||
.rst(!reset),
|
||||
|
||||
////// DDR3 INTERFACE //////
|
||||
.ddram_a(ddram_a[12:0]), //also ignored on the litedram core
|
||||
.ddram_ba(ddram_ba),
|
||||
.ddram_cas_n(ddram_cas_n),
|
||||
.ddram_cke(ddram_cke),
|
||||
.ddram_clk_n(1'b0), // goes nowhere ...
|
||||
.ddram_clk_p(ddram_clk_p),
|
||||
.ddram_cs_n(ddram_cs_n),
|
||||
.ddram_dm(ddram_dm),
|
||||
.ddram_dq(ddram_dq),
|
||||
.ddram_dqs_n(2'b00), // goes nowhere ...
|
||||
.ddram_dqs_p(ddram_dqs_p),
|
||||
.ddram_odt(ddram_odt),
|
||||
.ddram_ras_n(ddram_ras_n),
|
||||
.ddram_reset_n(ddram_reset_n),
|
||||
.ddram_we_n(ddram_we_n),
|
||||
|
||||
/////// SYSTEM MEMORY INTERFACE ////////////////
|
||||
.init_done(ddr3_init_done),
|
||||
.init_error(ddr3_init_error),
|
||||
.user_port_wishbone_0_ack(wb_mem_ack),
|
||||
.user_port_wishbone_0_adr(wb_mem_adr),
|
||||
.user_port_wishbone_0_cyc(wb_mem_cyc),
|
||||
.user_port_wishbone_0_dat_r(wb_mem_data_r),
|
||||
.user_port_wishbone_0_dat_w(wb_mem_data_w),
|
||||
.user_port_wishbone_0_err(wb_mem_err),
|
||||
.user_port_wishbone_0_sel(wb_mem_sel),
|
||||
.user_port_wishbone_0_stb(wb_mem_stb),
|
||||
.user_port_wishbone_0_we(wb_mem_we),
|
||||
.pll_locked(ddr3_pll_locked),
|
||||
//output wire user_rst,
|
||||
|
||||
/////// WISHBONE CONTROL INTERFACE ///////////
|
||||
.wb_ctrl_ack(wb_ctrl_ack),
|
||||
.wb_ctrl_adr(wb_ctrl_adr),
|
||||
.wb_ctrl_cyc(wb_ctrl_cyc),
|
||||
.wb_ctrl_err(wb_ctrl_err),
|
||||
.wb_ctrl_sel(wb_ctrl_sel),
|
||||
.wb_ctrl_stb(wb_ctrl_stb),
|
||||
.wb_ctrl_we(wb_ctrl_we),
|
||||
.wb_ctrl_bte(wb_ctrl_bte),
|
||||
.wb_ctrl_cti(wb_ctrl_cti),
|
||||
.wb_ctrl_dat_r(wb_ctrl_dat_r),
|
||||
.wb_ctrl_dat_w(wb_ctrl_dat_w)
|
||||
);
|
||||
|
||||
// Display driver
|
||||
|
||||
wire ascii_data_ready;
|
||||
|
@ -19,10 +19,24 @@
|
||||
|
||||
/* This warning is because we don't use the full address bus. */
|
||||
/* verilator lint_off UNUSEDSIGNAL */
|
||||
module doublemem(input [19:0] address,output [15:0] cpu_read_data ,input [15:0] cpu_write_data,input rd,input wr,input BHE,input cs,input clock);
|
||||
module doublemem
|
||||
#(
|
||||
parameter RAM_SIZE_IN_BYTES,
|
||||
parameter ADDRESS_WIDTH=$clog2(RAM_SIZE_IN_BYTES)
|
||||
)
|
||||
( input [ ADDRESS_WIDTH-1 : 0 ] address,
|
||||
output [15:0] cpu_read_data,
|
||||
input [15:0] cpu_write_data,
|
||||
input rd,
|
||||
input wr,
|
||||
input BHE,
|
||||
input cs,
|
||||
input clock
|
||||
);
|
||||
/* verilator lint_on UNUSEDSIGNAL */
|
||||
|
||||
reg [15:0] memory [0:`BUILTIN_RAM];
|
||||
reg [15:0] memory [0:(RAM_SIZE_IN_BYTES/2)-1];
|
||||
|
||||
|
||||
initial begin
|
||||
`ifndef YOSYS
|
||||
@ -31,39 +45,26 @@ initial begin
|
||||
$display("No boot code specified. Please add +BOOT_CODE=<path> to your vvp args");
|
||||
$finish;
|
||||
end
|
||||
$readmemh(boot_code, memory,0,`BUILTIN_RAM-1);
|
||||
$readmemh(boot_code, memory,0,32767);
|
||||
`else
|
||||
//TODO: don't have it hard coded
|
||||
$readmemh("../boot_code/brainfuck_compiled.txt", memory,0,`BUILTIN_RAM-1);
|
||||
`endif
|
||||
|
||||
`ifdef NOT_FULL
|
||||
jump_mem[0]=16'hB800;
|
||||
jump_mem[1]=16'h01ff;
|
||||
jump_mem[2]=16'hE000;
|
||||
$readmemh("../boot_code/bios.stxt", memory,0,(RAM_SIZE_IN_BYTES/2)-1); // 2KiB
|
||||
`endif
|
||||
end
|
||||
|
||||
`ifndef NOT_FULL
|
||||
assign cpu_read_data[7:0] = !address[0:0] & !rd & !cs ? memory[address[16:1]][15:8] : 8'hz;
|
||||
|
||||
assign cpu_read_data[15:8] = !BHE & !rd & !cs ? memory[address[16:1]][7:0] : 8'hz;
|
||||
`else
|
||||
|
||||
reg[15:0] jump_mem [0:4'h7];
|
||||
assign cpu_read_data[7:0] = !address[0:0] & !rd & !cs ? memory[address[ADDRESS_WIDTH-1:1]][15:8] : 8'hz;
|
||||
|
||||
assign cpu_read_data[7:0] = !address[0:0] & !rd & !cs ? (address[15:4]==12'b111111111111 ? jump_mem[address[3:1]][15:8]:memory[address[16:1]][15:8]) : 8'hz;
|
||||
assign cpu_read_data[15:8] = !BHE & !rd & !cs ? memory[address[ADDRESS_WIDTH-1:1]][ 7:0] : 8'hz;
|
||||
|
||||
assign cpu_read_data[15:8] = !BHE & !rd & !cs ? (address[15:4]==12'b111111111111 ? jump_mem[address[3:1]][7:0]:memory[address[16:1]][7:0]) : 8'hz;
|
||||
|
||||
`endif
|
||||
|
||||
always @(posedge clock) begin
|
||||
if( cs == 0 && wr == 0) begin
|
||||
if(BHE==0)
|
||||
memory[address[16:1]][7:0]<=cpu_write_data[15:8];
|
||||
memory[address[ADDRESS_WIDTH-1:1]][7:0]<=cpu_write_data[15:8];
|
||||
if(address[0]==0)
|
||||
memory[address[16:1]][15:8]<=cpu_write_data[7:0];
|
||||
memory[address[ADDRESS_WIDTH-1:1]][15:8]<=cpu_write_data[7:0];
|
||||
end
|
||||
end
|
||||
|
||||
|
127
system/peripherals/Wishbone_IO_driver.v
Normal file
127
system/peripherals/Wishbone_IO_driver.v
Normal file
@ -0,0 +1,127 @@
|
||||
/* Wishbone_driver.v - Implements a classic wishbone master
|
||||
|
||||
This file is part of the 9086 project.
|
||||
|
||||
Copyright (c) 2023 Efthymios Kritikos
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
module Wishbone_IO_driver (
|
||||
input wire clock,
|
||||
input wire reset_n,
|
||||
|
||||
input wire [2:0] address,
|
||||
input wire [15:0] data_bus_in,
|
||||
output reg [15:0] data_bus_out,
|
||||
input read_n,
|
||||
input write_n,
|
||||
input chip_select_n,
|
||||
|
||||
input wire wb_ctrl_ack,
|
||||
output wire [29:0] wb_ctrl_adr,
|
||||
output wire [1:0] wb_ctrl_bte,
|
||||
output wire [2:0] wb_ctrl_cti,
|
||||
output wire wb_ctrl_cyc,
|
||||
input wire [31:0] wb_ctrl_dat_r,
|
||||
output wire [31:0] wb_ctrl_dat_w,
|
||||
input wire wb_ctrl_err,
|
||||
output wire [3:0] wb_ctrl_sel,
|
||||
output wire wb_ctrl_stb,
|
||||
output wire wb_ctrl_we
|
||||
);
|
||||
|
||||
reg [13:0]WISHBONE_ADDR=14'd0;
|
||||
reg WISHBONE_ACTIVE_CYCLE=1'b0;
|
||||
wire WISHBONE_ERROR_IN;
|
||||
reg [3:0]WISHBONE_SELECT=4'd0;
|
||||
reg WISHBONE_VALID_TRANSFER=1'b0;
|
||||
reg WISHBONE_WRITE=1'b1;
|
||||
wire WISHBONE_ACK_IN;
|
||||
reg [31:0]WISHBONE_DATA_READ=32'd0;
|
||||
wire [31:0]WISHBONE_DATA_WRITE;
|
||||
|
||||
assign WISHBONE_ACK_IN=wb_ctrl_ack;
|
||||
assign wb_ctrl_adr={16'd0,WISHBONE_ADDR};
|
||||
assign WISHBONE_ERROR_IN=wb_ctrl_err;
|
||||
assign wb_ctrl_sel=WISHBONE_SELECT;
|
||||
assign wb_ctrl_stb=WISHBONE_VALID_TRANSFER;
|
||||
assign wb_ctrl_cyc=WISHBONE_ACTIVE_CYCLE;
|
||||
assign wb_ctrl_we=WISHBONE_WRITE;
|
||||
assign wb_ctrl_bte=2'b00; // Burst Type Extension 00:Linear burst
|
||||
assign wb_ctrl_cti=3'b000; // Cycle Type Idenfier 000:Classic cycle
|
||||
assign WISHBONE_DATA_WRITE=wb_ctrl_dat_r;
|
||||
assign wb_ctrl_dat_w=WISHBONE_DATA_READ;
|
||||
|
||||
reg [31:0]WISHBONE_READ_BUFFER;
|
||||
|
||||
reg [1:0]just_transacted;
|
||||
|
||||
reg [1:0]WISHBONE_STATUS;
|
||||
|
||||
wire CYCLE_END=(WISHBONE_ACK_IN==1'b1);//||WISHBONE_ERROR_IN==1'b1);
|
||||
|
||||
always @( posedge clock )begin
|
||||
if(reset_n==0)begin
|
||||
just_transacted<=2'b0;
|
||||
end
|
||||
if(just_transacted==2'd1&&CYCLE_END==1'b1)begin
|
||||
WISHBONE_READ_BUFFER<=WISHBONE_DATA_WRITE;
|
||||
end
|
||||
if(chip_select_n==0 && write_n==0 )begin
|
||||
case (address)
|
||||
3'h0: WISHBONE_DATA_READ[15:0] <=data_bus_in;
|
||||
3'h1: WISHBONE_DATA_READ[31:16]<=data_bus_in;
|
||||
3'h2: WISHBONE_ADDR[13:0]<=data_bus_in[13:0];
|
||||
3'h3: begin end
|
||||
default: begin end
|
||||
endcase
|
||||
|
||||
case (address)
|
||||
3'h3: begin
|
||||
WISHBONE_ACTIVE_CYCLE<=1;
|
||||
WISHBONE_VALID_TRANSFER<=1;
|
||||
WISHBONE_SELECT<=4'hF;
|
||||
end
|
||||
default: begin end
|
||||
endcase
|
||||
if(address==3'h3)begin
|
||||
WISHBONE_WRITE<=1'b1;//data_bus_in[0:0];
|
||||
if(data_bus_in[0:0]==1'b1)begin //write req
|
||||
just_transacted<=2'd2;
|
||||
end else begin
|
||||
just_transacted<=2'd1;
|
||||
end
|
||||
end
|
||||
end else if(just_transacted!=2'd0&&CYCLE_END==1'b1)begin // In the unlikely senario that the CPU wants to write without having checked for the previous write
|
||||
WISHBONE_STATUS[0:0]<=WISHBONE_ACK_IN;
|
||||
WISHBONE_STATUS[1:1]<=WISHBONE_ERROR_IN;
|
||||
WISHBONE_ACTIVE_CYCLE<=0;
|
||||
WISHBONE_VALID_TRANSFER<=0;
|
||||
just_transacted<=2'b0;
|
||||
end
|
||||
|
||||
if ( chip_select_n==0 && read_n==0 )begin
|
||||
case (address)
|
||||
/* verilator lint_off BLKSEQ */
|
||||
/* Makes icarus verilog work as expected, not too sure if it helps real hardware yet*/
|
||||
3'h0: data_bus_out = WISHBONE_READ_BUFFER[15:0];
|
||||
3'h1: data_bus_out = WISHBONE_READ_BUFFER[31:16];
|
||||
3'h2: data_bus_out = {13'd0,WISHBONE_STATUS,just_transacted==2'd0||CYCLE_END==1'b1}; //1:NOT BUSY 0:BUSY
|
||||
default: data_bus_out = 16'h0;
|
||||
/* verilator lint_on BLKSEQ */
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
149
system/peripherals/Wishbone_memory_driver.v
Normal file
149
system/peripherals/Wishbone_memory_driver.v
Normal file
@ -0,0 +1,149 @@
|
||||
/* Wishbone_driver.v - Implements a classic wishbone master that maps directly in memory space
|
||||
|
||||
This file is part of the 9086 project.
|
||||
|
||||
Copyright (c) 2023 Efthymios Kritikos
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
module Wishbone_memory_driver (
|
||||
input wire clock,
|
||||
input wire reset_n,
|
||||
|
||||
input wire [19:0] address,
|
||||
input wire [15:0] data_bus_in,
|
||||
output reg [15:0] data_bus_out,
|
||||
output reg wait_state,
|
||||
input read_n,
|
||||
input write_n,
|
||||
input chip_select_n,
|
||||
|
||||
input wire wb_mem_ack,
|
||||
output wire [24:0] wb_mem_adr,
|
||||
output wire wb_mem_cyc,
|
||||
/* verilator lint_off UNUSEDSIGNAL */
|
||||
// I don't yet use the upper word
|
||||
input wire [31:0] wb_mem_data_r,
|
||||
/* verilator lint_on UNUSEDSIGNAL */
|
||||
output wire [31:0] wb_mem_data_w,
|
||||
input wire wb_mem_err,
|
||||
output wire [3:0] wb_mem_sel,
|
||||
output wire wb_mem_stb,
|
||||
output wire wb_mem_we
|
||||
);
|
||||
|
||||
reg WISHBONE_ACTIVE_CYCLE=1'b0;
|
||||
/* verilator lint_off UNUSEDSIGNAL */
|
||||
wire WISHBONE_ERROR_IN;
|
||||
/* verilator lint_on UNUSEDSIGNAL */
|
||||
reg [3:0]WISHBONE_SELECT=4'd0;
|
||||
reg WISHBONE_VALID_TRANSFER=1'b0;
|
||||
reg WISHBONE_WRITE=1'b1;
|
||||
wire WISHBONE_ACK_IN;
|
||||
reg [31:0]WISHBONE_DATA_READ=32'd0;
|
||||
wire [15:0]WISHBONE_DATA_WRITE;
|
||||
|
||||
assign WISHBONE_ACK_IN=wb_mem_ack;
|
||||
assign wb_mem_adr={5'd0,address};
|
||||
assign WISHBONE_ERROR_IN=wb_mem_err;
|
||||
assign wb_mem_sel=WISHBONE_SELECT;
|
||||
assign wb_mem_stb=WISHBONE_VALID_TRANSFER;
|
||||
assign wb_mem_cyc=WISHBONE_ACTIVE_CYCLE;
|
||||
assign wb_mem_we=WISHBONE_WRITE;
|
||||
assign WISHBONE_DATA_WRITE=wb_mem_data_r[15:0];
|
||||
assign wb_mem_data_w=WISHBONE_DATA_READ;
|
||||
|
||||
wire CYCLE_END=(WISHBONE_ACK_IN==1'b1);//||WISHBONE_ERROR_IN==1'b1);
|
||||
|
||||
reg [3:0] state;
|
||||
|
||||
always @(*) begin
|
||||
wait_state=0;
|
||||
if(reset_n==1) begin
|
||||
case(state)
|
||||
4'd0:begin
|
||||
if( chip_select_n && ((!read_n)||(!write_n)) )begin
|
||||
wait_state=1;
|
||||
end else begin
|
||||
wait_state=0;
|
||||
end
|
||||
end
|
||||
4'd1:begin
|
||||
wait_state=1;
|
||||
end
|
||||
4'd2:begin
|
||||
wait_state=1;
|
||||
end
|
||||
4'd3:begin
|
||||
wait_state=1;
|
||||
end
|
||||
4'd4:begin
|
||||
wait_state=0;
|
||||
end
|
||||
default:begin
|
||||
end
|
||||
endcase
|
||||
end else begin
|
||||
wait_state=0;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clock)begin
|
||||
if(reset_n==0)
|
||||
state<=0;
|
||||
else begin
|
||||
case(state)
|
||||
4'd0:begin
|
||||
if( chip_select_n && ((!read_n)||(!write_n)) )begin
|
||||
state<=4'd1;
|
||||
end
|
||||
end
|
||||
4'd1:begin
|
||||
WISHBONE_ACTIVE_CYCLE<=1;
|
||||
WISHBONE_VALID_TRANSFER<=1;
|
||||
WISHBONE_SELECT<=4'hF;
|
||||
WISHBONE_WRITE<=read_n;
|
||||
if(read_n)begin
|
||||
state<=4'd2;
|
||||
WISHBONE_DATA_READ<={16'h0,data_bus_in};
|
||||
end else
|
||||
state<=4'd3;
|
||||
end
|
||||
4'd2:begin
|
||||
if(CYCLE_END==1'b1)begin
|
||||
state<=4'd4;
|
||||
WISHBONE_ACTIVE_CYCLE<=0;
|
||||
WISHBONE_VALID_TRANSFER<=0;
|
||||
end
|
||||
end
|
||||
4'd3:begin
|
||||
if(CYCLE_END==1'b1)begin
|
||||
data_bus_out<=WISHBONE_DATA_WRITE[15:0];
|
||||
state<=4'd4;
|
||||
WISHBONE_ACTIVE_CYCLE<=0;
|
||||
WISHBONE_VALID_TRANSFER<=0;
|
||||
end
|
||||
end
|
||||
4'd4:begin
|
||||
if(read_n&&write_n)
|
||||
state<=4'd0;
|
||||
end
|
||||
default:begin
|
||||
state<=4'd0;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
@ -32,7 +32,7 @@
|
||||
module processor (
|
||||
|
||||
/* MISC */ input clock, input reset, output wire HALT,output [`ERROR_BITS-1:0] ERROR
|
||||
/* MEMORY / IO */ ,output [19:0] external_address_bus, input [15:0] external_data_bus_read, output [15:0] external_data_bus_write,output read, output write,output BHE,output IOMEM
|
||||
/* MEMORY / IO */ ,output [19:0] external_address_bus, input [15:0] external_data_bus_read, output [15:0] external_data_bus_write, input wait_state, output read, output write,output BHE,output IOMEM
|
||||
|
||||
`ifdef CALCULATE_IPC
|
||||
/* STATISTICS */ ,output wire new_instruction
|
||||
@ -111,6 +111,7 @@ BIU BIU(
|
||||
/**************** OUTSIDE WORLD ****************/
|
||||
/* */ ,external_address_bus
|
||||
/* */ ,external_data_bus_read,external_data_bus_write,read,write,BHE,IOMEM
|
||||
/* */ ,wait_state
|
||||
|
||||
/**************** OUTPUT TO DE ****************/
|
||||
/* */ ,IF2DE_INSTRUCTION,VALID_INSTRUCTION,INSTRUCTION_LOCATION
|
||||
|
@ -37,10 +37,11 @@ wire [15:0]data_bus_read_CPU,data_bus_write_CPU;
|
||||
|
||||
assign data_bus_read_CPU=(IOMEM==0)?data_bus_read_RAM:data_bus_IO;
|
||||
assign data_bus_write=data_bus_write_CPU;
|
||||
wire wait_state=1'b0;
|
||||
|
||||
processor p(
|
||||
/* MISC */ clock,reset,HALT,ERROR
|
||||
/* MEMORY / IO */ ,address_bus,data_bus_read_CPU,data_bus_write_CPU,rd,wr,BHE,IOMEM
|
||||
/* MEMORY / IO */ ,address_bus,data_bus_read_CPU,data_bus_write_CPU,wait_state,rd,wr,BHE,IOMEM
|
||||
`ifdef CALCULATE_IPC
|
||||
/* STATISTICS */ ,new_instruction
|
||||
`endif
|
||||
@ -51,7 +52,7 @@ processor p(
|
||||
|
||||
wire [15:0] data_bus_read_RAM;
|
||||
|
||||
doublemem sysmem(address_bus,data_bus_read_RAM,data_bus_write_CPU,rd,wr,BHE,IOMEM,clock);
|
||||
doublemem #(.RAM_SIZE_IN_BYTES(65536)) sysmem(address_bus[15:0],data_bus_read_RAM,data_bus_write_CPU,rd,wr,BHE,IOMEM,clock);
|
||||
|
||||
`ifdef OUTPUT_JSON_STATISTICS
|
||||
string stats_name,version,commit;
|
||||
|
92
tools/gen_litedram.sh
Executable file
92
tools/gen_litedram.sh
Executable file
@ -0,0 +1,92 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
SOURCE_CODE_URL=https://github.com/enjoy-digital/litedram/archive/refs/tags/2023.08.tar.gz
|
||||
SOURCE_MD5_SUM=afc2208c08e60994d126c445574960da
|
||||
|
||||
if [ "$#" = 0 ] || echo "$1" | grep '^-' > /dev/null
|
||||
then
|
||||
echo This scripts generates a verilog file from the Migen project litedram
|
||||
echo It is currently hardcoded for the ECP5 PHY
|
||||
echo The provided file system/external_ip/litedram_core_ecp5_phy.v is the output of this program *BUT MODIFIED*
|
||||
echo
|
||||
echo Usage:
|
||||
echo \ \ \ "$0" \<output verilog file\>
|
||||
|
||||
if ! [ "$#" = 0 ]
|
||||
then
|
||||
if ! [ "$1" = "--help" ] && ! [ "$1" = "-h" ]
|
||||
then
|
||||
exit 1
|
||||
else
|
||||
exit 0
|
||||
fi
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
TEMP_DIR=$(mktemp -d)
|
||||
trap 'rm -rf -- "$TEMP_DIR"' EXIT
|
||||
CUR_DIR=$(pwd)
|
||||
|
||||
if echo "$1" | grep '^/' > /dev/null
|
||||
then
|
||||
OUT_FILE=$1
|
||||
else
|
||||
OUT_FILE="${CUR_DIR}/$1"
|
||||
fi
|
||||
|
||||
cd "$TEMP_DIR"
|
||||
#echo Downloading source code...
|
||||
|
||||
wget --output-document=source.tar.gz --quiet "$SOURCE_CODE_URL"
|
||||
|
||||
if [ "$(md5sum source.tar.gz)" != "${SOURCE_MD5_SUM} source.tar.gz" ]
|
||||
then
|
||||
#echo source doesn\'t match md5 sum
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#echo extracting the source...
|
||||
tar xvf source.tar.gz > source_dir
|
||||
|
||||
SOURCE_DIR=$(head -n 1 source_dir)
|
||||
rm source_dir
|
||||
|
||||
#echo patching the source...
|
||||
|
||||
#Generate the following text by running this: (diff -Naur /dev/null examples/orangecrab_9086.yml | gzip -9 | base64 | tr -d '\n';echo)
|
||||
echo H4sIAAAAAAACA61US2+bQBA+179ihC+JMA4Pg4mlSo7sOLFaJ5bjHKqqQguMYxRg6QJ2UJX/3lkwUeKop3oOy2pmvm/niaZpcBHi7iIt4/iLqZuWZpiaboJhj6zhaGD13aFOYthDUOWlo6oq4AtLshjzCy5Y+oSBYL53qbtOv0rekVhguCNzONKtvnM5HNqubtoHkvEYNL2ng2r0LAPG4476p6MCdOEGUxQsBu2/RfIplFkUoDKi6/fZtf2omfZMcxc3pmtPlB69N1veXEHj1a8RQVZKdxLljqdITh+kC5PlIxRVhnCGL7DDFxHlwa4HOQo6JeS85kkwkV7EpUynK+szz3R1taiJOmoTauLle5YpQIi1KOnlJp4k9EKMWSUNJLqMeg5ljsAg5nvYsbhEKDiwHY9CEMhCiHGHcZQ+NdRdWN7+OEFF36qah4IlXsLDMsamWMpiPTC+OYOF4chMu/BQp9e45MA3UGwRfM5ECFzAw702nS8Wn8i81Cc+s3dUqrsy8VFIFr8qEJ4EL7P8HZiG8LmBAhj/Bku397BsWx1aTarrydKmRlGlmgTWssUEqgeEtG0pZwJ/l5gGFZyklFGalYUXxM/ehojrcAYuOnWTpQmCmAfPsHl79efkfrW6nqx/NYlU+UcwgDOQcNmCKi8w+URwRq2RGPgKB/T5EWmURkchgdmSzsl2TNmWZsIFwummTE6+X242KGgBsmJLkRhO77A8UtGOVcCThKUhNM5tNI+0kbDkosjhFNHQwgkvk3QUR/2zIuU+yrc+rbyny+08aEnfbn5rb3a5NoWsYN4+Cut8LPNgeK2/8nzt/AU14UE3kwUAAA== | base64 -d | gzip -d > 00-add_orangecrab_config.patch
|
||||
|
||||
cd "$SOURCE_DIR"
|
||||
|
||||
patch -s -p0 < ../00-add_orangecrab_config.patch > /dev/null
|
||||
|
||||
|
||||
#echo building the file...
|
||||
|
||||
if ! ./setup.py build > "$TEMP_DIR/build_log" 2> "$TEMP_DIR/build_log"
|
||||
then
|
||||
echo ERROR: Failed to run setup.py
|
||||
cat "$TEMP_DIR/build_log"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd build/lib/litedram/
|
||||
|
||||
if ! python3 gen.py ../../../examples/orangecrab_9086.yml --no-compile-software > "$TEMP_DIR/build_log" 2> "$TEMP_DIR/build_log"
|
||||
then
|
||||
echo ERROR: Failed to run gen.py
|
||||
cat "$TEMP_DIR/build_log"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#echo patching source file...
|
||||
|
||||
#This is just for some yosys warnings...
|
||||
echo H4sIAAAAAAACA82T326CMBTG73mKc7XBECnKAHUkvMeyNEdatZE/hiLEzPnsa5nL4pYh3izrTduc3/d9Jyet4ziw3IuMuWuseYsVdzNRc1ZhTtOy4uMGJmQydTzPmYRAgrkfzEk4noYzEgZh5INN1DJs2waX8cYt9lkG3yWRUo1nj5FPvMALzpIkASci/nQUgt3tASSJASilWBfw+tmFboKylaA7j7YVwxpH8LNGzrU3iC+roqh5tcKU01bXF/8igOYot30pHaCjzFNfGG25tTCcvw4EzFo8SEjMBwuWfC0KA/S6UKabspRqyxltMBNMwlMM0T0jiyHwM3nRvHlBLbHY5phuRMHJFwt3YJpXwB0eshIZFVJfleK39BaLWh+k1dmehhpXKLXgNIxOUVrWDbyauuKP/V1jWotG/WFlbRzhholUHBnEcb+7hj6GMti3rRR51bijVM+Weljv0yEXHY0EAAA= | base64 -d | gzip -d | patch -s -p0
|
||||
|
||||
cp build/gateware/litedram_core.v "$OUT_FILE"
|
||||
|
||||
#echo File built correctly!
|
Loading…
Reference in New Issue
Block a user