Author SHA1 Message Date
jens aacb0c448b This commit was manufactured by cvs2svn to create tag 'JCPU_R4'.
git-svn-id: http://moon:8086/svn/vhdl/tags/JCPU_R4@559 cc03376c-175c-47c8-b038-4cd826a8556b
2009-10-28 23:25:03 +00:00
93 changed files with 20267 additions and 4016 deletions
+56
View File
@@ -0,0 +1,56 @@
; -------------------------------------------------
; PROJECT "dctest"
; -------------------------------------------------
include "../../../jasm/cregs.inc.jsm"
; -------------------------------------------------
xmem
org 4
konst: dc 0x01, 0x12,"A"
gap1: db 16
mesg: dc "Hallo", 13,0x0A, 0
name: dc "Jens",0
msg1: dc "Welcome to JASM CPU",0
msg2: dc "Ready",0
msg3: dc "Testing",0
msg4: dc "Passed",0
msg5: dc "Error",0
crlf: dc 0x0D, 0x0A
org 0x00
shit: db 4
cmem 0
org 8
cram1: db 16
cram2: db 6
cram3: db 4
cmem 1
cram4: db 8
cram5: db 8
org 0x20
cram6: db 8
cram7: db 4
reg_revision: equ 0x00
reg_testid: equ 0x01
; -------------------------------------------------
code
org 0x000
reset: jmp start
; -------------------------------------------------
org 0x001
int_vec: jmp isr
; -------------------------------------------------
org 0x010
start: jmp start
; -------------------------------------------------
isr: reti
+212
View File
@@ -0,0 +1,212 @@
# ----------------------------------------------------------------------
# Project: JCPU, a portable 8-bit RISC CPU written in VHDL
# This file: The ROM file for upload to target over JTAG
#
# Copyright (C) 2007 J. Ahrensfeld
#
# 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/>.
#
# For questions and ideas, please contact the author at jens@jayfield.org
#
# ---------------------------------------------------------------------
# ---------------------------------------------------------------------
# For Chipscope 9.1
# ---------------------------------------------------------------------
# Source JTAG/TCL frame work
cd $env(CHIPSCOPE)\\bin\\nt
source csejtag.tcl
namespace import ::chipscope::*
# Platform USB Cable
set PLATFORM_USB_CABLE_ARGS [list "port=USB2" "frequency=6000000"]
# frequency="24000000 | 12000000 | 6000000 | 3000000 | 1500000 | 750000"
# Create session
set handle [::chipscope::csejtag_session create 0]
# Open JTAG and lock
set open_result [::chipscope::csejtag_target open $handle $CSEJTAG_TARGET_PLATFORMUSB 0 $PLATFORM_USB_CABLE_ARGS]
set lock_result [::chipscope::csejtag_target lock $handle 1000]
set devlist [::chipscope::csejtag_tap autodetect_chain $handle $CSEJTAG_SCAN_DEFAULT]
# Get Device ID
set devtype "Virtex-4SX"
set devid 2
set irlength [::chipscope::csejtag_tap get_irlength $handle $devid]
set idcode [::chipscope::csejtag_tap get_device_idcode $handle $devid]
set CSE_OP $CSEJTAG_SHIFT_READWRITE
set CSE_ES $CSEJTAG_RUN_TEST_IDLE
# Write Program
# JASM_ROM_INSERT_HERE
# Assembled from dctest.jsm
# ---------------------------------------------------------------
# Shift the USER2 Instruction (b1111000010) into the Instruction Register of FPGA
# User 1
set result [::chipscope::csejtag_tap shift_device_ir $handle $devid $CSE_OP $CSE_ES 0 $irlength "3C2"]
# 0x000: JMP 0x010
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "00030010"
# 0x001: JMP 0x011
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "00130011"
# 0x002:
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "00200000"
# 0x003:
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "00300000"
# 0x004:
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "00400000"
# 0x005:
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "00500000"
# 0x006:
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "00600000"
# 0x007:
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "00700000"
# 0x008:
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "00800000"
# 0x009:
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "00900000"
# 0x00A:
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "00A00000"
# 0x00B:
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "00B00000"
# 0x00C:
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "00C00000"
# 0x00D:
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "00D00000"
# 0x00E:
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "00E00000"
# 0x00F:
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "00F00000"
# 0x010: JMP 0x010
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "01030010"
# 0x011: RETI
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0113F000"
# Assembled from dctest.jsm
# ---------------------------------------------------------------
# Shift the USER2 Instruction (b1111000011) into the Instruction Register of FPGA
# User 2
set result [::chipscope::csejtag_tap shift_device_ir $handle $devid $CSE_OP $CSE_ES 0 $irlength "3C3"]
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "0000"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "0100"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "0200"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "0300"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "0401"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "0512"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "0641"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "0700"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "0800"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "0900"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "0A00"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "0B00"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "0C00"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "0D00"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "0E00"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "0F00"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "1000"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "1100"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "1200"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "1300"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "1400"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "1500"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "1600"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "1748"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "1861"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "196C"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "1A6C"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "1B6F"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "1C0D"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "1D0A"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "1E00"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "1F4A"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "2065"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "216E"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "2273"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "2300"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "2457"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "2565"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "266C"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "2763"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "286F"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "296D"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "2A65"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "2B20"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "2C74"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "2D6F"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "2E20"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "2F4A"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "3041"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "3153"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "324D"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "3320"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "3443"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "3550"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "3655"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "3700"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "3852"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "3965"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "3A61"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "3B64"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "3C79"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "3D00"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "3E54"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "3F65"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "4073"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "4174"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "4269"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "436E"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "4467"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "4500"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "4650"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "4761"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "4873"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "4973"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "4A65"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "4B64"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "4C00"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "4D45"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "4E72"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "4F72"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "506F"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "5172"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "5200"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "530D"
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "540A"
::chipscope::csejtag_target unlock $handle
::chipscope::csejtag_target close $handle
::chipscope::csejtag_session destroy $handle
exit
+858
View File
@@ -0,0 +1,858 @@
; -------------------------------------------------
; PROJECT "itest"
; -------------------------------------------------
include "../../../jasm/cregs.inc.jsm"
; -------------------------------------------------
xmem
msg: dc "Hallo", 0
xram: db 256
cmem 0
cram: db 256
reg_revision: equ 0x00
reg_testid: equ 0x01
; -------------------------------------------------
code
org 0x000
reset: jmp start
; -------------------------------------------------
org 0x001
int_vec: jmp isr
; -------------------------------------------------
org 0x010
start: call init
cin R0, (cpu_revision)
xout (reg_revision), R0
; Test 0
call test0
; Test 1
mov R0, 1
xout (reg_testid), R0
call test1
; Test 2
mov R0, 2
xout (reg_testid), R0
call test2
; Test 3
mov R0, 3
xout (reg_testid), R0
call test3
; Test 4
mov R0, 4
xout (reg_testid), R0
call test4
; Test 5
mov R0, 5
xout (reg_testid), R0
call test5
; Test 6
mov R0, 6
xout (reg_testid), R0
call test6
; Test 7
mov R0, 7
xout (reg_testid), R0
call test7
; Test 8
mov R0, 8
xout (reg_testid), R0
call test8
; Test 9
mov R0, 9
xout (reg_testid), R0
call test9
; Test 10
mov R0, 10
xout (reg_testid), R0
call test10
; Test 11
mov R0, 11
xout (reg_testid), R0
call test11
; Test 12
mov R0, 12
xout (reg_testid), R0
call test12
; End of test
mov R0, 0xFF
xout (reg_testid), R0
jmp ok
; -------------------------------------------------
init: mov R0, 0
mov R1, 0
mov R2, 0
mov R3, 0
mov R4, 0
mov R5, 0
mov R6, 0
mov R7, 0
mov R8, 0
mov R9, 0
mov R10, 0
mov R11, 0
mov R12, 0
mov R13, 0
mov R14, 0
mov R15, 0
ret
; -------------------------------------------------
; MOV|R|K
; MOV|R|R
test0: mov R0, 0x10
cmp R0, 0x10
jne error
add R0, 1
mov R1, R0
cmp R1, 0x11
jne error
add R1, 1
mov R2, R1
cmp R2, 0x12
jne error
add R2, 1
mov R3, R2
cmp R3, 0x13
jne error
add R3, 1
mov R4, R3
cmp R4, 0x14
jne error
add R4, 1
mov R5, R4
cmp R5, 0x15
jne error
add R5, 1
mov R6, R5
cmp R6, 0x16
jne error
add R6, 1
mov R7, R6
cmp R7, 0x17
jne error
add R7, 1
mov R8, R7
cmp R8, 0x18
jne error
add R8, 1
mov R9, R8
cmp R9, 0x19
jne error
add R9, 1
mov R10, R9
cmp R10, 0x1A
jne error
add R10, 1
mov R11, R10
cmp R11, 0x1B
jne error
add R11, 1
mov R12, R11
cmp R12, 0x1C
jne error
add R12, 1
mov R13, R12
cmp R13, 0x1D
jne error
add R13, 1
mov R14, R13
cmp R14, 0x1E
jne error
add R14, 1
mov R15, R14
cmp R15, 0x1F
jne error
add R15, 1
ret
; -------------------------------------------------
; Instruction test
; TST|R
; CMP|R|K
; JNZ|K
; JC|K
; JNE|K
; JLT|K
; JGT|K
; JLE|K
; JGE|K
; JMP|K
test1: mov R0, 0 ; R0 <= 0
tst R0
jnz error
jc error
cmp R0, 0
jne error
jlt error
jgt error
jle t1_ok10
jmp error
t1_ok10: jeq t1_ok20
jmp error
t1_ok20: jge t1_ok30
jmp error
t1_ok30: cmp R0, 0x55
jeq error
jlt t1_ok40
jmp error
t1_ok40: jle t1_ok50
jmp error
t1_ok50: jge error
jgt error
mov R0, 0x55 ; R0 <= 0xAA
tst R0
jz error
jc error
cmp R0, 0xAA
jeq error
jne t1_ok60
jmp error
t1_ok60: jlt t1_ok70
jmp error
t1_ok70: jle t1_ok80
jmp error
t1_ok80: jgt error
cmp R0, 0x55
jeq t1_ok90
jmp error
t1_ok90: jne error
jlt error
jle t1_ok100
jmp error
t1_ok100: jgt error
jge t1_ok110
jmp error
t1_ok110: mov R0, 0xAA ; R0 <= 0x55
tst R0
jz error
jc error
cmp R0, 0x55
jeq error
jne t1_ok120
jmp error
t1_ok120: jgt t1_ok130
jmp error
t1_ok130: jge t1_ok140
jmp error
t1_ok140: jlt error
jle error
ret
; -------------------------------------------------
; ADD|R|K
; ADDC|R|K
; ToDo: ADD|R|R
; ToDo: ADDC|R|R
; CMP|R|R
test2: mov R0, 0
mov R1, 0
mov R2, R0
mov R3, R1
t2_loop: add R0, 0x01
addc R1, 0x00
add R2, 1
cmp R2, 0
jne t2_L1
add R3, 1
cmp R3, 0x02
t2_L1: jne t2_loop
cmp R0, R2
jne error
cmp R1, R3
jne error
mov R0, 0
ret
; -------------------------------------------------
; SUB|R|K
; SUBC|R|K
; ToDo: SUB|R|R
; ToDo: SUBC|R|R
; CMP|R|R
test3: mov R0, 0x00
mov R1, 0x03
mov R2, R0
mov R3, R1
t3_loop: sub R0, 0x01
subc R1, 0x00
sub R2, 1
cmp R2, 0xFF
jne t3_L1
sub R3, 1
cmp R3, 0x00
t3_L1: jne t3_loop
cmp R0, R2
jne error
cmp R1, R3
jne error
mov R0, 0
ret
; -------------------------------------------------
; SUB|K|R
; SUB|R|R
; SUBC|R|R
; SUBC|K|R
; CMP|R|R
test4: mov R0, 0x03
mov R1, 0x05
sub 0x05, R0
sub R1, 0x03
cmp R0, R1
jne error
mov R0, 0x03
mov R1, 0x05
sub R0, R1
subc 0, R0
cmp R0, 0x01
jne error
add R0, 0
subc R1, R0
cmp R1, 0x04
jne error
mov R0, 0
ret
; -------------------------------------------------
; MOVC|R|Ri
; MOVC|R|Ki
; MOVC|Ri|R
; MOVC|Ri|K
; MOVC|Ki|R
test5: mov R0, 1
movc (cram+0x5A), R0
dec R0
movc (cram+0), R0
movc R1, (cram+0x5A)
movc (R1), 0xA5
movc R0, (R1)
movc R1, (R1)
add R1, 0xFF-0xA5
movc R0, (R1)
t5_loop1: movc (R0), R0
movc R2, (R0)
cmp R2, R0
jne error
movc (R2), R1
movc R2, (R2)
cmp R2, R1
jne error
dec R1
inc R0
jnz t5_loop1
ret
; -------------------------------------------------
; MOVX|R|Ri
; MOVX|R|Ki
; MOVX|Ri|R
; MOVX|Ri|K
; MOVX|Ki|R
test6: mov R0, 1
movx (xram+0x5A), R0
dec R0
movx (xram+0), R0
movx R1, (xram+0x5A)
movx (R1), 0xA5
movx R0, (R1)
movx R1, (R1)
add R1, 0xFF-0xA5
movx R0, (R1)
t6_loop1: movx (R0), R0
movx R2, (R0)
cmp R2, R0
jne error
movx (R2), R1
movx R2, (R2)
cmp R2, R1
jne error
dec R1
inc R0
jnz t6_loop1
ret
; -------------------------------------------------
; PUSH|R
; POP|R
test7: mov R0, 0xAA
mov R1, 0
t7_loop1: push R0
inc R0
dec R1
jnz t7_loop1
t7_loop2: pop R0
dec R1
jnz t7_loop2
cmp R0, 0xAA
jne error
ret
; -------------------------------------------------
; JMP|K
; CALL|K
; RET
test8: mov R0, 0x55
push R0
mov R0, 0
mov R1, 0xFF
call t8_rec
pop R0
cmp R0, 0x55
jne error
; Stack manipulations 1
mov R0, return1'high
mov R1, return1'low
cout (cpu_stack_high), R0
push R1
mov R0, init'high
mov R1, init'low
cout (cpu_stack_high), R0
push R1
ret
; Stack manipulations 2
return1: mov R0, return2'high
mov R1, return2'low
cout (cpu_stack_high), R0
push R1
mov R0, init'high
mov R1, init'low
cout (cpu_stack_high), R0
push R1
return2: ret
t8_rec: cmp R0, R1
jeq ex_t8_rec
inc R0
jmp t8_rstub
ex_t8_rec: dec R0
dec R1
ret
t8_rstub: call t8_rec
jmp ex_t8_rec
; -------------------------------------------------
; SWAP|R
; SHL|R
; SHR|R
; ROL|R
; ROR|R
; ROLC|R
; RORC|R
test9: mov R0, 0xA5 ; SWAP test
mov R1, 0x5A
swap R0
cmp R0, 0x5A
jne error
swap R0
cmp R0, 0xA5
jne error
mov R0, 0xD2
swap R0
cmp R0, 0x2D
jne error
swap R1
cmp R0, 0x2D
jne error
cmp R1, 0xA5
jne error
mov R0, 0x2D
shl R0 ; SHL test
cmp R0, 0x5A
jne error
shl R0
cmp R0, 0xB4
jne error
shl R0
cmp R0, 0x68
jne error
shl R0
cmp R0, 0xD0
jne error
shl R0
cmp R0, 0xA0
jne error
shl R0
cmp R0, 0x40
jne error
shl R0
cmp R0, 0x80
jne error
shl R0
cmp R0, 0x00
jne error
mov R1, 0x84
shr R1 ; SHR test
cmp R1, 0x42
jne error
shr R1
cmp R1, 0x21
jne error
shr R1
cmp R1, 0x10
jne error
shr R1
cmp R1, 0x08
jne error
shr R1
cmp R1, 0x04
jne error
shr R1
cmp R1, 0x02
jne error
shr R1
cmp R1, 0x01
jne error
shr R1
cmp R1, 0x00
jne error
mov R0, 0xC5 ; ROL test
rol R0
cmp R0, 0x8B
jne error
rol R0
cmp R0, 0x17
jne error
rol R0
cmp R0, 0x2E
jne error
rol R0
cmp R0, 0x5C
jne error
rol R0
cmp R0, 0xB8
jne error
rol R0
cmp R0, 0x71
jne error
rol R0
cmp R0, 0xE2
jne error
rol R0
cmp R0, 0xC5
jne error
mov R1, 0x63 ; ROR test
ror R1
cmp R1, 0xB1
jne error
ror R1
cmp R1, 0xD8
jne error
ror R1
cmp R1, 0x6C
jne error
ror R1
cmp R1, 0x36
jne error
ror R1
cmp R1, 0x1B
jne error
ror R1
cmp R1, 0x8D
jne error
ror R1
cmp R1, 0xC6
jne error
ror R1
cmp R1, 0x63
jne error
xor R0, R0 ; ROLC generate
mov R0, 0xC5
rolc R0
push R0
rolc R0
push R0
rolc R0
push R0
rolc R0
push R0
rolc R0
push R0
rolc R0
push R0
rolc R0
push R0
rolc R0
push R0
rolc R0
cmp R0, 0xC5 ; ROLC verify
jne error
pop R0
cmp R0, 0x62
jne error
pop R0
cmp R0, 0xB1
jne error
pop R0
cmp R0, 0x58
jne error
pop R0
cmp R0, 0xAC
jne error
pop R0
cmp R0, 0x56
jne error
pop R0
cmp R0, 0x2B
jne error
pop R0
cmp R0, 0x15
jne error
pop R0
cmp R0, 0x8A
jne error
xor R1, R1 ; RORC generate
mov R1, 0x63
rorc R1
push R1
rorc R1
push R1
rorc R1
push R1
rorc R1
push R1
rorc R1
push R1
rorc R1
push R1
rorc R1
push R1
rorc R1
push R1
rorc R1
cmp R1, 0x63 ; RORC verify
jne error
pop R1
cmp R1, 0xC6
jne error
pop R1
cmp R1, 0x8C
jne error
pop R1
cmp R1, 0x19
jne error
pop R1
cmp R1, 0x33
jne error
pop R1
cmp R1, 0x66
jne error
pop R1
cmp R1, 0xCC
jne error
pop R1
cmp R1, 0x98
jne error
pop R1
cmp R1, 0x31
jne error
ret
; -------------------------------------------------
; AND|R|R
; AND|R|K
; OR|R|R
; OR|R|K
; XOR|R|R
; XOR|R|K
test10: mov R0, 0xA5 ; AND
swap R0
push R0
and R0, 0x0F
cmp R0, 0x0A
jne error
pop R0
push R0
and R0, 0x0F
cmp R0, 0x0A
pop R1
jne error
swap R1
mov R2, 0x0F
and R1, R2
cmp R1, 0x05
jne error
mov R0, 0x05 ; OR
mov R2, 0xA0
swap R0
or R2, R0
cmp R2, 0xF0
jne error
swap R0
or R0, 0x50
cmp R0, 0x55
jne error
mov R1, 0x01
mov R0, 0x01
xor R0, 0x01
jnz error
xor R0, R1
cmp R0, 0x01
jne error
ret
; -------------------------------------------------
test11:
mov R0, 0x03
cout (cpu_int_ctrl), R0
xin R0, (2)
or R0, 1
xout (2), R0
nop
nop
nop
nop
nop
nop
xin R0, (2)
and R0, 0xFE
xout (2), R0
nop
nop
nop
nop
cin R0, (cpu_int_ctrl)
or R0, 0x80
cout (cpu_int_ctrl), R0
nop
cin R0, (cpu_int_ctrl)
or R0, 0x80
cout (cpu_int_ctrl), R0
nop
cin R0, (cpu_int_ctrl)
or R0, 0x80
cout (cpu_int_ctrl), R0
nop
cin R0, (cpu_int_ctrl)
or R0, 0x80
cout (cpu_int_ctrl), R0
nop
nop
nop
nop
nop
nop
nop
nop
nop
ret
; -------------------------------------------------
; Tests clrc, setc
test12: sub R0, 0
jc error
setc
jnc error
nop
sub R0, 0
jc error
mov R0, 0
clrc
jc error
setc
jnc error
nop
clrc
jc error
ret
; -------------------------------------------------
isr: inc R14
reti
; -------------------------------------------------
org 0x3FF
error: jmp error
; -------------------------------------------------
org 0x2FF
ok: jmp ok
; -------------------------------------------------
File diff suppressed because it is too large Load Diff
+50
View File
@@ -0,0 +1,50 @@
#!/bin/sh
# ----------------------------------------------------------------------
# Project: JCPU, a portable 8-bit RISC CPU written in VHDL
# This file: rom-file generation for cpu_core
#
# Copyright (C) 2007 J. Ahrensfeld
#
# 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/>.
#
# For questions and ideas, please contact the author at jens@jayfield.org
#
# ---------------------------------------------------------------------
TARGET=$2
DSTDIR=$1
JASM_HOME=/cygdrive/w/vhdl/lib/CPUs/JCpu/tools
$JASM_HOME/jasm.rb $TARGET.jsm
irom_tcl_snippet="$TARGET.irom.tcl.snip"
irom_vhdl_snippet="$TARGET.irom.vhdl.snip"
irom_ld_vhdl_snippet="$TARGET.irom_ld.vhdl.snip"
xrom_tcl_snippet="$TARGET.xrom.tcl.snip"
xrom_vhdl_snippet="$TARGET.xrom.vhdl.snip"
xrom_ld_vhdl_snippet="$TARGET.xrom_ld.vhdl.snip"
$JASM_HOME/insrom.rb $irom_vhdl_snippet $JASM_HOME/irom.vhd.tpl >$DSTDIR/$TARGET\_irom.vhdl
$JASM_HOME/insrom.rb $irom_ld_vhdl_snippet $JASM_HOME/irom_ld.vhd.tpl >$DSTDIR/$TARGET\_irom_ld.vhdl
$JASM_HOME/insrom.rb $xrom_vhdl_snippet $JASM_HOME/xrom.vhd.tpl >$DSTDIR/$TARGET\_xrom.vhdl
$JASM_HOME/insrom.rb $xrom_ld_vhdl_snippet $JASM_HOME/xrom_ld.vhd.tpl >$DSTDIR/$TARGET\_xrom_ld.vhdl
cat $irom_tcl_snippet > $TARGET.tcl.snip.snip
cat $xrom_tcl_snippet >> $TARGET.tcl.snip.snip
$JASM_HOME/insrom.rb $TARGET.tcl.snip.snip $JASM_HOME/rom.tcl.tpl >$TARGET.tcl
rm -f *.snip
+29
View File
@@ -0,0 +1,29 @@
; -------------------------------------------------
; Constants
; -------------------------------------------------
; Chip register
include "../../../jasm/cregs.inc.jsm"
; -------------------------------------------------
; Program
; -------------------------------------------------
code
org 0x000
reset: jmp init
; -------------------------------------------------
; Main
; -------------------------------------------------
init: mov R0, 0x45
mov R1, 0xF5
call mul8x8
stop: jmp stop
; -------------------------------------------------
include "../../../jasm/mul8x8.inc.jsm"
+154
View File
@@ -0,0 +1,154 @@
# ----------------------------------------------------------------------
# Project: JCPU, a portable 8-bit RISC CPU written in VHDL
# This file: The ROM file for upload to target over JTAG
#
# Copyright (C) 2007 J. Ahrensfeld
#
# 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/>.
#
# For questions and ideas, please contact the author at jens@jayfield.org
#
# ---------------------------------------------------------------------
# ---------------------------------------------------------------------
# For Chipscope 9.1
# ---------------------------------------------------------------------
# Source JTAG/TCL frame work
cd $env(CHIPSCOPE)\\bin\\nt
source csejtag.tcl
namespace import ::chipscope::*
# Platform USB Cable
set PLATFORM_USB_CABLE_ARGS [list "port=USB2" "frequency=6000000"]
# frequency="24000000 | 12000000 | 6000000 | 3000000 | 1500000 | 750000"
# Create session
set handle [::chipscope::csejtag_session create 0]
# Open JTAG and lock
set open_result [::chipscope::csejtag_target open $handle $CSEJTAG_TARGET_PLATFORMUSB 0 $PLATFORM_USB_CABLE_ARGS]
set lock_result [::chipscope::csejtag_target lock $handle 1000]
set devlist [::chipscope::csejtag_tap autodetect_chain $handle $CSEJTAG_SCAN_DEFAULT]
# Get Device ID
set devtype "Virtex-4SX"
set devid 2
set irlength [::chipscope::csejtag_tap get_irlength $handle $devid]
set idcode [::chipscope::csejtag_tap get_device_idcode $handle $devid]
set CSE_OP $CSEJTAG_SHIFT_READWRITE
set CSE_ES $CSEJTAG_RUN_TEST_IDLE
# Write Program
# JASM_ROM_INSERT_HERE
# Assembled from mul8x8.jsm
# ---------------------------------------------------------------
# Shift the USER2 Instruction (b1111000010) into the Instruction Register of FPGA
# User 1
set result [::chipscope::csejtag_tap shift_device_ir $handle $devid $CSE_OP $CSE_ES 0 $irlength "3C2"]
# 0x000: JMP 0x001
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "00030001"
# 0x001: MOV R00, 0x45
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "00103450"
# 0x002: MOV R01, 0xF5
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "00203F51"
# 0x003: CALL 0x005
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0033B005"
# 0x004: JMP 0x004
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "00430004"
# 0x005: PUSH R02
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0053C002"
# 0x006: PUSH R03
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0063C003"
# 0x007: PUSH R04
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0073C004"
# 0x008: MOV R04, R01
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "00802014"
# 0x009: MOV R01, 0x00
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "00903001"
# 0x00A: MOV R02, 0x00
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "00A03002"
# 0x00B: MOV R03, 0x00
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "00B03003"
# 0x00C: CMP R04, 0x01
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "00C0F014"
# 0x00D: JEQ 0x015
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "00D39015"
# 0x00E: SHR R04
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "00E1F004"
# 0x00F: JNC 0x012
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "00F34012"
# 0x010: ADD R02, R00
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "01010002"
# 0x011: ADDC R03, R01
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "01112013"
# 0x012: SHL R00
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0121E000"
# 0x013: ROLC R01
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "01322001"
# 0x014: JMP 0x00C
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0143000C"
# 0x015: ADD R00, R02
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "01510020"
# 0x016: ADDC R01, R03
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "01612031"
# 0x017: POP R04
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0173D004"
# 0x018: POP R03
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0183D003"
# 0x019: POP R02
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0193D002"
# 0x01A: RET
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "01A3E000"
# Assembled from mul8x8.jsm
# ---------------------------------------------------------------
# Shift the USER2 Instruction (b1111000011) into the Instruction Register of FPGA
# User 2
set result [::chipscope::csejtag_tap shift_device_ir $handle $devid $CSE_OP $CSE_ES 0 $irlength "3C3"]
::chipscope::csejtag_target unlock $handle
::chipscope::csejtag_target close $handle
::chipscope::csejtag_session destroy $handle
exit
+50
View File
@@ -0,0 +1,50 @@
; -------------------------------------------------
; Constants
; -------------------------------------------------
; Chip register
cpu_revision: equ 0x00 ; RO
cpu_control: equ 0x01 ; R/W
cpu_status: equ 0x02 ; RO
cpu_int_ctrl: equ 0x03 ; R/W
; -------------------------------------------------
; Program
; -------------------------------------------------
code
reset: jmp init
org 0x001
; nop
reti
; -------------------------------------------------
; Main
; -------------------------------------------------
init: mov R0, 0x05
cout (cpu_int_ctrl), R0
mov R0, 0x00
loop: nop
inc R0
nop
call subr
nop
push R3
nop
push R2
nop
push R1
nop
push R0
nop
pop R0
nop
pop R1
nop
pop R2
nop
pop R3
nop
jmp loop
subr: ret
+157
View File
@@ -0,0 +1,157 @@
# ----------------------------------------------------------------------
# Project: JCPU, a portable 8-bit RISC CPU written in VHDL
# This file: The ROM file for upload to target over JTAG
#
# Copyright (C) 2007 J. Ahrensfeld
#
# 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/>.
#
# For questions and ideas, please contact the author at jens@jayfield.org
#
# ---------------------------------------------------------------------
# ---------------------------------------------------------------------
# For Chipscope 9.1
# ---------------------------------------------------------------------
# Source JTAG/TCL frame work
cd $env(CHIPSCOPE)\\bin\\nt
source csejtag.tcl
namespace import ::chipscope::*
# Platform USB Cable
set PLATFORM_USB_CABLE_ARGS [list "port=USB2" "frequency=6000000"]
# frequency="24000000 | 12000000 | 6000000 | 3000000 | 1500000 | 750000"
# Create session
set handle [::chipscope::csejtag_session create 0]
# Open JTAG and lock
set open_result [::chipscope::csejtag_target open $handle $CSEJTAG_TARGET_PLATFORMUSB 0 $PLATFORM_USB_CABLE_ARGS]
set lock_result [::chipscope::csejtag_target lock $handle 1000]
set devlist [::chipscope::csejtag_tap autodetect_chain $handle $CSEJTAG_SCAN_DEFAULT]
# Get Device ID
set devtype "Virtex-4SX"
set devid 2
set irlength [::chipscope::csejtag_tap get_irlength $handle $devid]
set idcode [::chipscope::csejtag_tap get_device_idcode $handle $devid]
set CSE_OP $CSEJTAG_SHIFT_READWRITE
set CSE_ES $CSEJTAG_RUN_TEST_IDLE
# Write Program
# JASM_ROM_INSERT_HERE
# Assembled from reti_issue.jsm
# ---------------------------------------------------------------
# Shift the USER2 Instruction (b1111000010) into the Instruction Register of FPGA
# User 1
set result [::chipscope::csejtag_tap shift_device_ir $handle $devid $CSE_OP $CSE_ES 0 $irlength "3C2"]
# 0x000: JMP 0x002
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "00030002"
# 0x001: RETI
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0013F000"
# 0x002: MOV R00, 0x05
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "00203050"
# 0x003: COUT (0x03), R00
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "00326030"
# 0x004: MOV R00, 0x00
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "00403000"
# 0x005: NOP
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "00500000"
# 0x006: INC R00
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "00611010"
# 0x007: NOP
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "00700000"
# 0x008: CALL 0x01B
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0083B01B"
# 0x009: NOP
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "00900000"
# 0x00A: PUSH R03
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "00A3C003"
# 0x00B: NOP
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "00B00000"
# 0x00C: PUSH R02
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "00C3C002"
# 0x00D: NOP
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "00D00000"
# 0x00E: PUSH R01
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "00E3C001"
# 0x00F: NOP
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "00F00000"
# 0x010: PUSH R00
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0103C000"
# 0x011: NOP
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "01100000"
# 0x012: POP R00
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0123D000"
# 0x013: NOP
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "01300000"
# 0x014: POP R01
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0143D001"
# 0x015: NOP
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "01500000"
# 0x016: POP R02
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0163D002"
# 0x017: NOP
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "01700000"
# 0x018: POP R03
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0183D003"
# 0x019: NOP
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "01900000"
# 0x01A: JMP 0x005
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "01A30005"
# 0x01B: RET
::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "01B3E000"
# Assembled from reti_issue.jsm
# ---------------------------------------------------------------
# Shift the USER2 Instruction (b1111000011) into the Instruction Register of FPGA
# User 2
set result [::chipscope::csejtag_tap shift_device_ir $handle $devid $CSE_OP $CSE_ES 0 $irlength "3C3"]
::chipscope::csejtag_target unlock $handle
::chipscope::csejtag_target close $handle
::chipscope::csejtag_session destroy $handle
exit
Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

+674
View File
@@ -0,0 +1,674 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
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/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
Binary file not shown.
+22
View File
@@ -0,0 +1,22 @@
## NOTE: Do not edit this file.
##
vlib work
vcom -explicit -93 "../../../PCK_FIO-1.16/PCK_FIO.vhd"
vcom -explicit -93 "../src/core/cpu_pkg.vhd"
vcom -explicit -93 "../src/core/stack_ctrl.vhd"
vcom -explicit -93 "../src/core/reg_dual.vhd"
vcom -explicit -93 "../src/core/chipram.vhd"
vcom -explicit -93 "../src/core/chipreg.vhd"
vcom -explicit -93 "../src/core/pc.vhd"
vcom -explicit -93 "../src/core/dpath_ctrl.vhd"
vcom -explicit -93 "../src/core/int_ctrl.vhd"
vcom -explicit -93 "../src/core/alu.vhd"
vcom -explicit -93 "../src/core/cpu.vhd"
vcom -explicit -93 "../src/itest_irom.vhdl"
vcom -explicit -93 "../src/tb_cpu_itest.vhd"
vsim -t 1ps -lib work tb_cpu
do {tb_cpu.wdo}
view wave
view structure
view signals
run 50us
+107
View File
@@ -0,0 +1,107 @@
onerror {resume}
quietly WaveActivateNextPane {} 0
add wave -noupdate -format Logic /tb_cpu/rst
add wave -noupdate -format Logic /tb_cpu/clk
add wave -noupdate -format Logic /tb_cpu/ce
add wave -noupdate -format Logic /tb_cpu/uut/cpu_active
add wave -noupdate -format Logic /tb_cpu/int_in
add wave -noupdate -format Logic /tb_cpu/int_ack
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/irom_data
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/irom_addr
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/xmem_din
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/xmem_dout
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/xmem_addr
add wave -noupdate -format Logic /tb_cpu/xmem_we
add wave -noupdate -format Logic /tb_cpu/xmem_re
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/sram
add wave -noupdate -format Logic /tb_cpu/uut/io_sel
add wave -noupdate -format Literal /tb_cpu/uut/iphase
add wave -noupdate -divider CPU
add wave -noupdate -format Literal /tb_cpu/reg
add wave -noupdate -format Literal /tb_cpu/uut/inst_dpath_ctrl/dbg_iname
add wave -noupdate -format Literal /tb_cpu/uut/cpu_status
add wave -noupdate -format Literal /tb_cpu/uut/status_reg
add wave -noupdate -format Literal /tb_cpu/uut/ctrl
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/stk_out
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/stk_in
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/stk_reg
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/pc_in
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/pc_next
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/idata
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/int_pc_addr
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/iphase
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/const_data
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/reg_a_dout
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/reg_b_dout
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/reg_din
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/alu_op1
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/alu_op2
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/alu_result
add wave -noupdate -format Literal /tb_cpu/uut/alu_status
add wave -noupdate -format Logic /tb_cpu/uut/pc_inc
add wave -noupdate -format Logic /tb_cpu/uut/pc_load
add wave -noupdate -format Logic /tb_cpu/uut/stk_we
add wave -noupdate -format Logic /tb_cpu/uut/cmem_we
add wave -noupdate -format Literal /tb_cpu/uut/ctrl_iphase
add wave -noupdate -format Logic /tb_cpu/uut/was_pcld
add wave -noupdate -format Logic /tb_cpu/uut/was_pop2pc
add wave -noupdate -format Logic /tb_cpu/uut/int_pc_load
add wave -noupdate -format Logic /tb_cpu/uut/int_stk_push
add wave -noupdate -format Logic /tb_cpu/uut/stk_push
add wave -noupdate -format Logic /tb_cpu/uut/stk_pop
add wave -noupdate -format Logic /tb_cpu/uut/status_save
add wave -noupdate -format Logic /tb_cpu/uut/status_restore
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/stk_ptr
add wave -noupdate -divider Stack
add wave -noupdate -format Logic /tb_cpu/clk
add wave -noupdate -format Literal /tb_cpu/uut/inst_dpath_ctrl/dbg_iname
add wave -noupdate -format Logic /tb_cpu/uut/inst_stack_ctrl/push
add wave -noupdate -format Logic /tb_cpu/uut/inst_stack_ctrl/pop
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/inst_stack_ctrl/din
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/inst_stack_ctrl/dout
add wave -noupdate -format Logic /tb_cpu/uut/inst_stack_ctrl/mem_we
add wave -noupdate -divider Chipram
add wave -noupdate -format Logic /tb_cpu/uut/inst_chipram/we_a
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/inst_chipram/din_a
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/inst_chipram/addr_a
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/inst_chipram/dout_a
add wave -noupdate -format Logic /tb_cpu/uut/inst_chipram/we_b
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/inst_chipram/din_b
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/inst_chipram/addr_b
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/inst_chipram/dout_b
add wave -noupdate -divider Sequencer
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/inst_dpath_ctrl/inst_in
add wave -noupdate -format Literal /tb_cpu/uut/inst_dpath_ctrl/iphase_in
add wave -noupdate -format Literal /tb_cpu/uut/inst_dpath_ctrl/status_in
add wave -noupdate -format Literal /tb_cpu/uut/inst_dpath_ctrl/ctrl_out
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/inst_dpath_ctrl/idout
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/inst_dpath_ctrl/ddout
add wave -noupdate -format Literal /tb_cpu/uut/inst_dpath_ctrl/opcode
add wave -noupdate -format Literal /tb_cpu/uut/inst_dpath_ctrl/ctrl_lines
add wave -noupdate -format Literal /tb_cpu/uut/inst_dpath_ctrl/dbg_iname
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_cpu/uut/inst_reg_ab/mem
add wave -noupdate -divider {Chip register}
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/creg_addr
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/creg_din
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/creg_dout
add wave -noupdate -format Literal /tb_cpu/uut/creg_ctrl_out
add wave -noupdate -format Literal /tb_cpu/uut/inst_dpath_ctrl/dbg_iname
add wave -noupdate -format Logic /tb_cpu/clk
add wave -noupdate -format Logic /tb_cpu/uut/inst_int_ctrl/int_exit
add wave -noupdate -format Literal /tb_cpu/uut/inst_int_ctrl/int_state
TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 1} {136355 ps} 0}
configure wave -namecolwidth 166
configure wave -valuecolwidth 101
configure wave -justifyvalue left
configure wave -signalnamewidth 1
configure wave -snapdistance 10
configure wave -datasetprefix 0
configure wave -rowmargin 4
configure wave -childrowmargin 2
configure wave -gridoffset 0
configure wave -gridperiod 1
configure wave -griddelta 40
configure wave -timeline 0
update
WaveRestoreZoom {93532 ps} {206468 ps}
+21
View File
@@ -0,0 +1,21 @@
## NOTE: Do not edit this file.
##
vlib work
vcom -explicit -93 "../src/core/cpu_pkg.vhd"
vcom -explicit -93 "../src/core/stack_ctrl.vhd"
vcom -explicit -93 "../src/core/reg_dual.vhd"
vcom -explicit -93 "../src/core/chipram.vhd"
vcom -explicit -93 "../src/core/pc.vhd"
vcom -explicit -93 "../src/core/dpath_ctrl.vhd"
vcom -explicit -93 "../src/core/int_ctrl.vhd"
vcom -explicit -93 "../src/core/alu.vhd"
vcom -explicit -93 "../src/core/cpu.vhd"
vcom -explicit -93 "../src/cpu_embedded.vhd"
vcom -explicit -93 "../src/tb_cpu_embedded.vhd"
vcom -explicit -93 "../src/itest_irom.vhdl"
vsim -t 1ps -lib work tb_cpu_embedded
do {tb_cpu_embedded.wdo}
view wave
view structure
view signals
run 10us
+26
View File
@@ -0,0 +1,26 @@
onerror {resume}
quietly WaveActivateNextPane {} 0
add wave -noupdate -format Logic /tb_cpu_embedded/rst
add wave -noupdate -format Logic /tb_cpu_embedded/clk
add wave -noupdate -format Logic /tb_cpu_embedded/ce
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu_embedded/sram
add wave -noupdate -format Logic /tb_cpu_embedded/int_in
add wave -noupdate -format Logic /tb_cpu_embedded/int_ack
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu_embedded/uut/rom_addr
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu_embedded/uut/rom_data
TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 1} {2168142 ps} 0}
configure wave -namecolwidth 143
configure wave -valuecolwidth 101
configure wave -justifyvalue left
configure wave -signalnamewidth 1
configure wave -snapdistance 10
configure wave -datasetprefix 0
configure wave -rowmargin 4
configure wave -childrowmargin 2
configure wave -gridoffset 0
configure wave -gridperiod 1
configure wave -griddelta 40
configure wave -timeline 0
update
WaveRestoreZoom {0 ps} {10500 ns}
+22
View File
@@ -0,0 +1,22 @@
## NOTE: Do not edit this file.
##
vlib work
vcom -explicit -93 "../../../PCK_FIO-1.16/PCK_FIO.vhd"
vcom -explicit -93 "../src/core/cpu_pkg.vhd"
vcom -explicit -93 "../src/core/stack_ctrl.vhd"
vcom -explicit -93 "../src/core/reg_dual.vhd"
vcom -explicit -93 "../src/core/chipram.vhd"
vcom -explicit -93 "../src/core/chipreg.vhd"
vcom -explicit -93 "../src/core/pc.vhd"
vcom -explicit -93 "../src/core/dpath_ctrl.vhd"
vcom -explicit -93 "../src/core/int_ctrl.vhd"
vcom -explicit -93 "../src/core/alu.vhd"
vcom -explicit -93 "../src/core/cpu.vhd"
vcom -explicit -93 "../src/itest_irom.vhdl"
vcom -explicit -93 "../src/tb_cpu_itest.vhd"
vsim -t 1ps -lib work tb_cpu
do {tb_cpu_itest.wdo}
view wave
view structure
view signals
run 400us
+123
View File
@@ -0,0 +1,123 @@
onerror {resume}
quietly WaveActivateNextPane {} 0
add wave -noupdate -format Logic /tb_cpu/rst
add wave -noupdate -format Logic /tb_cpu/clk
add wave -noupdate -format Logic /tb_cpu/ce
add wave -noupdate -format Logic /tb_cpu/int_in
add wave -noupdate -format Logic /tb_cpu/int_ack
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/irom_data
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/irom_addr
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/xmem_din
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/xmem_dout
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/xmem_addr
add wave -noupdate -format Logic /tb_cpu/xmem_we
add wave -noupdate -format Logic /tb_cpu/xmem_re
add wave -noupdate -format Logic /tb_cpu/xmem_wait
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/sram
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_cpu/reg
add wave -noupdate -format Logic /tb_cpu/uut/io_sel
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/mem_data
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/mem_addr
add wave -noupdate -divider CPU
add wave -noupdate -format Literal /tb_cpu/uut/inst_dpath_ctrl/dbg_iname
add wave -noupdate -format Literal /tb_cpu/uut/cpu_status
add wave -noupdate -format Literal /tb_cpu/uut/status_reg
add wave -noupdate -format Literal /tb_cpu/uut/ctrl
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/stk_out
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/stk_in
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/stk_reg
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/pc_in
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/pc_next
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/idata
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/int_pc_addr
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/iphase
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/const_data
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/reg_a_dout
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/reg_b_dout
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/reg_din
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/alu_op1
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/alu_op2
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/alu_result
add wave -noupdate -format Literal /tb_cpu/uut/alu_status
add wave -noupdate -format Logic /tb_cpu/uut/pc_inc
add wave -noupdate -format Logic /tb_cpu/uut/pc_load
add wave -noupdate -format Logic /tb_cpu/uut/cpu_active
add wave -noupdate -format Logic /tb_cpu/uut/stk_we
add wave -noupdate -format Logic /tb_cpu/uut/cmem_we
add wave -noupdate -format Literal /tb_cpu/uut/ctrl_iphase
add wave -noupdate -format Logic /tb_cpu/uut/was_pcld
add wave -noupdate -format Logic /tb_cpu/uut/was_pop2pc
add wave -noupdate -format Logic /tb_cpu/uut/int_pc_load
add wave -noupdate -format Logic /tb_cpu/uut/int_stk_push
add wave -noupdate -format Logic /tb_cpu/uut/stk_push
add wave -noupdate -format Logic /tb_cpu/uut/stk_pop
add wave -noupdate -format Logic /tb_cpu/uut/status_save
add wave -noupdate -format Logic /tb_cpu/uut/status_restore
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/stk_ptr
add wave -noupdate -divider Stack
add wave -noupdate -format Logic /tb_cpu/clk
add wave -noupdate -format Literal /tb_cpu/uut/inst_dpath_ctrl/dbg_iname
add wave -noupdate -format Logic /tb_cpu/uut/inst_stack_ctrl/push
add wave -noupdate -format Logic /tb_cpu/uut/inst_stack_ctrl/pop
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/inst_stack_ctrl/din
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/inst_stack_ctrl/dout
add wave -noupdate -format Logic /tb_cpu/uut/inst_stack_ctrl/mem_we
add wave -noupdate -divider Chipram
add wave -noupdate -format Logic /tb_cpu/uut/inst_chipram/we_a
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/inst_chipram/din_a
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/inst_chipram/addr_a
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/inst_chipram/dout_a
add wave -noupdate -format Logic /tb_cpu/uut/inst_chipram/we_b
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/inst_chipram/din_b
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/inst_chipram/addr_b
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/inst_chipram/dout_b
add wave -noupdate -divider Sequencer
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/reg
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/inst_dpath_ctrl/inst_in
add wave -noupdate -format Literal /tb_cpu/uut/inst_dpath_ctrl/iphase_in
add wave -noupdate -format Literal /tb_cpu/uut/inst_dpath_ctrl/status_in
add wave -noupdate -format Literal /tb_cpu/uut/inst_dpath_ctrl/ctrl_out
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/inst_dpath_ctrl/idout
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/inst_dpath_ctrl/ddout
add wave -noupdate -format Literal /tb_cpu/uut/inst_dpath_ctrl/opcode
add wave -noupdate -format Literal /tb_cpu/uut/inst_dpath_ctrl/ctrl_lines
add wave -noupdate -format Literal /tb_cpu/uut/inst_dpath_ctrl/dbg_iname
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_cpu/uut/inst_reg_ab/mem
add wave -noupdate -divider {Chip register}
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/creg_dout
add wave -noupdate -format Literal /tb_cpu/uut/creg_ctrl_out
add wave -noupdate -format Literal /tb_cpu/uut/inst_dpath_ctrl/dbg_iname
add wave -noupdate -format Logic /tb_cpu/clk
add wave -noupdate -divider {Interrup Ctrl.}
add wave -noupdate -format Logic /tb_cpu/uut/inst_int_ctrl/int_in
add wave -noupdate -format Literal -expand /tb_cpu/uut/inst_int_ctrl/ctrl_in
add wave -noupdate -format Logic /tb_cpu/uut/inst_int_ctrl/int_sampled
add wave -noupdate -format Logic /tb_cpu/uut/inst_int_ctrl/int_request
add wave -noupdate -format Logic /tb_cpu/uut/inst_int_ctrl/int_ack
add wave -noupdate -format Logic /tb_cpu/uut/inst_int_ctrl/int_exit
add wave -noupdate -format Logic /tb_cpu/uut/inst_int_ctrl/int_ack_out
add wave -noupdate -format Logic /tb_cpu/uut/inst_int_ctrl/stat_save_out
add wave -noupdate -format Logic /tb_cpu/uut/inst_int_ctrl/stat_rest_out
add wave -noupdate -format Logic /tb_cpu/uut/inst_int_ctrl/pc_load_out
add wave -noupdate -format Logic /tb_cpu/uut/inst_int_ctrl/stk_push_out
add wave -noupdate -format Logic /tb_cpu/uut/inst_int_ctrl/stk_pop_out
add wave -noupdate -format Literal /tb_cpu/uut/inst_int_ctrl/int_state
add wave -noupdate -format Logic /tb_cpu/uut/inst_int_ctrl/pc_load
add wave -noupdate -format Logic /tb_cpu/uut/inst_int_ctrl/stk_push
add wave -noupdate -format Logic /tb_cpu/uut/inst_int_ctrl/stk_pop
TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 1} {53866171 ps} 0}
configure wave -namecolwidth 166
configure wave -valuecolwidth 101
configure wave -justifyvalue left
configure wave -signalnamewidth 1
configure wave -snapdistance 10
configure wave -datasetprefix 0
configure wave -rowmargin 4
configure wave -childrowmargin 2
configure wave -gridoffset 0
configure wave -gridperiod 1
configure wave -griddelta 40
configure wave -timeline 0
update
WaveRestoreZoom {0 ps} {420 us}
+22
View File
@@ -0,0 +1,22 @@
## NOTE: Do not edit this file.
##
vlib work
vcom -explicit -93 "../../../PCK_FIO-1.16/PCK_FIO.vhd"
vcom -explicit -93 "../src/core/cpu_pkg.vhd"
vcom -explicit -93 "../src/core/stack_ctrl.vhd"
vcom -explicit -93 "../src/core/reg_dual.vhd"
vcom -explicit -93 "../src/core/chipram.vhd"
vcom -explicit -93 "../src/core/chipreg.vhd"
vcom -explicit -93 "../src/core/pc.vhd"
vcom -explicit -93 "../src/core/dpath_ctrl.vhd"
vcom -explicit -93 "../src/core/int_ctrl.vhd"
vcom -explicit -93 "../src/core/alu.vhd"
vcom -explicit -93 "../src/core/cpu.vhd"
vcom -explicit -93 "../src/irom_reti_issue.vhdl"
vcom -explicit -93 "../src/core/tb_cpu.vhd"
vsim -t 1ps -lib work tb_cpu
do {tb_cpu_reti_issue.wdo}
view wave
view structure
view signals
run 50us
+82
View File
@@ -0,0 +1,82 @@
onerror {resume}
quietly WaveActivateNextPane {} 0
add wave -noupdate -format Literal /tb_cpu/uut/iphase
add wave -noupdate -format Literal /tb_cpu/uut/inst_dpath_ctrl/ctrl_lines
add wave -noupdate -divider {Chip RAM}
add wave -noupdate -format Literal /tb_cpu/uut/iphase
add wave -noupdate -format Literal /tb_cpu/uut/inst_dpath_ctrl/dbg_iname
add wave -noupdate -format Logic /tb_cpu/uut/inst_chipram/clka
add wave -noupdate -format Logic /tb_cpu/uut/inst_chipram/clkb
add wave -noupdate -format Logic /tb_cpu/uut/inst_chipram/en_a
add wave -noupdate -format Logic /tb_cpu/uut/inst_chipram/en_b
add wave -noupdate -format Logic /tb_cpu/uut/inst_chipram/we_a
add wave -noupdate -format Logic /tb_cpu/uut/inst_chipram/we_b
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/inst_chipram/addr_a
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/inst_chipram/addr_b
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/inst_chipram/din_a
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/inst_chipram/din_b
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/inst_chipram/dout_a
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/inst_chipram/dout_b
add wave -noupdate -divider {Interrupt controller}
add wave -noupdate -format Literal /tb_cpu/uut/iphase
add wave -noupdate -format Literal /tb_cpu/uut/inst_dpath_ctrl/dbg_iname
add wave -noupdate -format Logic /tb_cpu/uut/inst_int_ctrl/rst
add wave -noupdate -format Logic /tb_cpu/uut/inst_int_ctrl/clk
add wave -noupdate -format Literal /tb_cpu/uut/inst_int_ctrl/ctrl_in
add wave -noupdate -format Logic /tb_cpu/uut/inst_int_ctrl/int_in
add wave -noupdate -format Logic /tb_cpu/uut/inst_int_ctrl/int_reg
add wave -noupdate -format Logic /tb_cpu/uut/inst_int_ctrl/int_request
add wave -noupdate -format Logic /tb_cpu/uut/inst_int_ctrl/int_request_clr
add wave -noupdate -format Logic /tb_cpu/uut/inst_int_ctrl/int_exit
add wave -noupdate -format Literal /tb_cpu/uut/inst_int_ctrl/iphase_in
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/inst_int_ctrl/pc_addr_out
add wave -noupdate -format Logic /tb_cpu/uut/inst_int_ctrl/int_ack
add wave -noupdate -format Logic /tb_cpu/uut/inst_int_ctrl/stat_save_out
add wave -noupdate -format Logic /tb_cpu/uut/inst_int_ctrl/stat_rest_out
add wave -noupdate -format Logic /tb_cpu/uut/inst_int_ctrl/pc_load_out
add wave -noupdate -format Logic /tb_cpu/uut/inst_int_ctrl/stk_push_out
add wave -noupdate -format Literal /tb_cpu/uut/inst_int_ctrl/int_state
add wave -noupdate -format Literal /tb_cpu/uut/inst_int_ctrl/int_state_next
add wave -noupdate -format Logic /tb_cpu/uut/inst_int_ctrl/pc_load
add wave -noupdate -format Logic /tb_cpu/uut/inst_int_ctrl/stk_push
add wave -noupdate -format Logic /tb_cpu/uut/inst_int_ctrl/stk_pop
add wave -noupdate -format Logic /tb_cpu/uut/inst_int_ctrl/stk_pop_out
add wave -noupdate -format Logic /tb_cpu/uut/inst_int_ctrl/stk_push_out
add wave -noupdate -divider PC
add wave -noupdate -format Literal /tb_cpu/uut/iphase
add wave -noupdate -format Literal /tb_cpu/uut/inst_dpath_ctrl/dbg_iname
add wave -noupdate -format Logic /tb_cpu/uut/inst_pc/rst
add wave -noupdate -format Logic /tb_cpu/uut/inst_pc/clk
add wave -noupdate -format Logic /tb_cpu/uut/inst_pc/inc
add wave -noupdate -format Logic /tb_cpu/uut/inst_pc/load
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/inst_pc/pc_in
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/inst_pc/pc_out
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/inst_pc/pc_next
add wave -noupdate -divider {Stack controller}
add wave -noupdate -format Literal /tb_cpu/uut/iphase
add wave -noupdate -format Literal /tb_cpu/uut/inst_dpath_ctrl/dbg_iname
add wave -noupdate -format Logic /tb_cpu/uut/inst_stack_ctrl/rst
add wave -noupdate -format Logic /tb_cpu/uut/inst_stack_ctrl/clk
add wave -noupdate -format Logic /tb_cpu/uut/inst_stack_ctrl/push
add wave -noupdate -format Logic /tb_cpu/uut/inst_stack_ctrl/pop
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/inst_stack_ctrl/ptr_out
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/inst_stack_ctrl/din
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/inst_stack_ctrl/dout
add wave -noupdate -format Logic /tb_cpu/uut/inst_stack_ctrl/mem_we
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu/uut/inst_stack_ctrl/ptr
TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 1} {8115990 ps} 0}
configure wave -namecolwidth 150
configure wave -valuecolwidth 100
configure wave -justifyvalue left
configure wave -signalnamewidth 1
configure wave -snapdistance 10
configure wave -datasetprefix 0
configure wave -rowmargin 4
configure wave -childrowmargin 2
configure wave -gridoffset 0
configure wave -gridperiod 1
configure wave -griddelta 40
configure wave -timeline 0
update
WaveRestoreZoom {8048536 ps} {8340629 ps}
+21
View File
@@ -0,0 +1,21 @@
## NOTE: Do not edit this file.
##
vlib work
vcom -explicit -93 "../src/core/cpu_pkg.vhd"
vcom -explicit -93 "../src/core/stack_ctrl.vhd"
vcom -explicit -93 "../src/core/reg_dual.vhd"
vcom -explicit -93 "../src/core/chipram.vhd"
vcom -explicit -93 "../src/core/pc.vhd"
vcom -explicit -93 "../src/core/dpath_ctrl.vhd"
vcom -explicit -93 "../src/core/int_ctrl.vhd"
vcom -explicit -93 "../src/core/alu.vhd"
vcom -explicit -93 "../src/core/cpu.vhd"
vcom -explicit -93 "../src/cpu_embedded.vhd"
vcom -explicit -93 "../src/tb_cpu_embedded.vhd"
vcom -explicit -93 "../src/mul8x8_irom.vhdl"
vsim -t 1ps -lib work tb_cpu_embedded
do {tb_mul8x8.wdo}
view wave
view structure
view signals
run 10us
+31
View File
@@ -0,0 +1,31 @@
onerror {resume}
quietly WaveActivateNextPane {} 0
add wave -noupdate -format Logic /tb_cpu_embedded/uut/inst_cpu/rst
add wave -noupdate -format Logic /tb_cpu_embedded/uut/inst_cpu/clk
add wave -noupdate -format Logic /tb_cpu_embedded/uut/inst_cpu/ce
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu_embedded/uut/inst_cpu/instr_din
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu_embedded/uut/inst_cpu/instr_addr
add wave -noupdate -format Literal /tb_cpu_embedded/uut/inst_cpu/cpu_status
add wave -noupdate -format Literal /tb_cpu_embedded/uut/inst_cpu/status_reg
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu_embedded/uut/inst_cpu/alu_op1
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu_embedded/uut/inst_cpu/alu_op2
add wave -noupdate -format Literal -radix hexadecimal /tb_cpu_embedded/uut/inst_cpu/alu_result
add wave -noupdate -format Literal /tb_cpu_embedded/uut/inst_cpu/alu_status
add wave -noupdate -format Literal /tb_cpu_embedded/uut/inst_cpu/inst_dpath_ctrl/dbg_iname
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_cpu_embedded/uut/inst_cpu/inst_reg_ab/mem
TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 1} {529679 ps} 0}
configure wave -namecolwidth 143
configure wave -valuecolwidth 101
configure wave -justifyvalue left
configure wave -signalnamewidth 1
configure wave -snapdistance 10
configure wave -datasetprefix 0
configure wave -rowmargin 4
configure wave -childrowmargin 2
configure wave -gridoffset 0
configure wave -gridperiod 1
configure wave -griddelta 40
configure wave -timeline 0
update
WaveRestoreZoom {9002500 ps} {10052500 ps}
+236
View File
@@ -0,0 +1,236 @@
--------------------------------------------------------------------------
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
-- This file: The arithmetic logic unit
--
-- Copyright (C) 2007 J. Ahrensfeld
--
-- 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/>.
--
-- For questions and ideas, please contact the author at jens@jayfield.org
--
--------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
use work.cpu_pkg.all;
entity alu is
Generic (
data_width : integer := 8
);
Port (
rst : in STD_LOGIC;
clk : in STD_LOGIC;
op_en : in STD_LOGIC;
cy_in : in STD_LOGIC;
op1_in : in unsigned (data_width-1 downto 0);
op2_in : in unsigned (data_width-1 downto 0);
opsel : in alu_op_t;
res_out : out unsigned (data_width-1 downto 0);
stat_load : in STD_LOGIC;
stat_in : in alu_status_t;
stat_out : out alu_status_t
);
end alu;
architecture Behavioral of alu is
signal sum_cy, sh_cy, sum_cy_in, sh_cy_in, left_shift, add_subn : STD_LOGIC;
signal result, sum_res, lf_res, sh_res, res_reg : unsigned (data_width-1 downto 0);
signal status, stat_reg : alu_status_t;
--------------------------------------------------------------------------
function test_zero(arg : unsigned) return STD_LOGIC is
variable result : STD_LOGIC;
begin
result := '0';
for i in arg'range loop
result := result or To_X01(arg(i));
end loop;
return not result;
end test_zero;
--------------------------------------------------------------------------
begin
--------------------------------------------------------------------------
proc_logic_func:
process (op1_in, op2_in, opsel)
begin
case opsel is
when op1_and_op2 =>
lf_res <= op1_in and op2_in;
when op1_or_op2 =>
lf_res <= op1_in or op2_in;
when op1_xor_op2 =>
lf_res <= op1_in xor op2_in;
when others =>
lf_res <= (others => '-');
end case;
end process;
--------------------------------------------------------------------------
proc_shift_func:
process (op1_in, left_shift, sh_cy_in)
begin
if left_shift = '1' then
sh_res <= op1_in(op1_in'left-1 downto op1_in'right) & sh_cy_in;
sh_cy <= op1_in(op1_in'left);
else
sh_res <= sh_cy_in & op1_in(op1_in'left downto op1_in'right+1);
sh_cy <= op1_in(op1_in'right);
end if;
end process;
--------------------------------------------------------------------------
proc_alu_out:
process(opsel, op1_in, op2_in, res_reg, stat_reg, lf_res, sum_res, sh_res, sum_cy, sh_cy, cy_in)
begin
case opsel is
when op1_add_op2 | op1_sub_op2 | op1_addc_op2 | op1_subc_op2 =>
status.zero <= test_zero(res_reg);
status.carry <= sum_cy;
result <= sum_res;
when op1_and_op2 | op1_or_op2 | op1_xor_op2 =>
status.zero <= test_zero(res_reg);
status.carry <= stat_reg.carry;
result <= lf_res;
when shl_op | shr_op | rol_op | ror_op | rolc_op | rorc_op =>
status.zero <= test_zero(res_reg);
status.carry <= sh_cy;
result <= sh_res;
when swap_op =>
result <= op1_in(op1_in'left-op1_in'length/2 downto op1_in'right) & op1_in(op1_in'left downto op1_in'right+op1_in'length/2);
status <= stat_reg;
when others =>
result <= op2_in;
status.zero <= stat_reg.zero;
status.carry <= stat_reg.carry or cy_in;
end case;
end process;
--------------------------------------------------------------------------
proc_alu_in:
process(opsel, op1_in, stat_reg)
begin
add_subn <= '-';
sum_cy_in <= '-';
sh_cy_in <= '-';
left_shift <= '-';
case opsel is
when op1_add_op2 =>
sum_cy_in <= '0';
add_subn <= '1';
when op1_sub_op2 =>
sum_cy_in <= '0';
add_subn <= '0';
when op1_addc_op2 =>
sum_cy_in <= stat_reg.carry;
add_subn <= '1';
when op1_subc_op2 =>
sum_cy_in <= stat_reg.carry;
add_subn <= '0';
when shl_op =>
sh_cy_in <= '0';
left_shift <= '1';
when shr_op =>
sh_cy_in <= '0';
left_shift <= '0';
when rol_op =>
sh_cy_in <= op1_in(op1_in'left);
left_shift <= '1';
when ror_op =>
sh_cy_in <= op1_in(op1_in'right);
left_shift <= '0';
when rolc_op =>
sh_cy_in <= stat_reg.carry;
left_shift <= '1';
when rorc_op =>
sh_cy_in <= stat_reg.carry;
left_shift <= '0';
when others => null;
end case;
end process;
--------------------------------------------------------------------------
proc_res_reg:
process(clk, rst, op_en, stat_load, res_reg, stat_reg)
begin
if rst = '1' then
res_reg <= (others => '0');
stat_reg <= (others => '0');
elsif rising_edge(clk) then
if op_en = '1' then
res_reg <= result;
stat_reg <= status;
elsif stat_load = '1' then
stat_reg <= stat_in;
end if;
end if;
res_out <= res_reg;
stat_out <= stat_reg;
end process;
--------------------------------------------------------------------------
alu_addsub:
process(op1_in, op2_in, sum_cy_in, add_subn)
variable sum : unsigned(data_width+1 downto 0);
variable op1, op2 : unsigned(data_width+1 downto 0);
begin
if add_subn = '1' then
op1 := '0' & op1_in & '1';
op2 := '0' & op2_in & sum_cy_in;
sum := op1 + op2;
else
op1 := '0' & op1_in & not sum_cy_in;
op2 := '0' & op2_in & '1';
sum := op1 - op2;
end if;
-- Form sum + carry
sum_res <= sum(data_width downto 1);
sum_cy <= sum(sum'left);
end process;
--------------------------------------------------------------------------
end Behavioral;
+85
View File
@@ -0,0 +1,85 @@
--------------------------------------------------------------------------
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
-- This file: On-chip RAM
--
-- Copyright (C) 2007 J. Ahrensfeld
--
-- 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/>.
--
-- For questions and ideas, please contact the author at jens@jayfield.org
--
--------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
use work.cpu_pkg.all;
entity chipram is
Generic (
addr_width : integer := 3;
data_width : integer := 8
);
Port (
clka : in STD_LOGIC;
clkb : in STD_LOGIC;
en_a : in STD_LOGIC;
en_b : in STD_LOGIC;
we_a : in STD_LOGIC;
we_b : in STD_LOGIC;
addr_a : in unsigned (addr_width-1 downto 0);
addr_b : in unsigned (addr_width-1 downto 0);
din_a : in unsigned (data_width-1 downto 0);
din_b : in unsigned (data_width-1 downto 0);
dout_a : out unsigned (data_width-1 downto 0);
dout_b : out unsigned (data_width-1 downto 0)
);
end chipram;
architecture Behavioral of chipram is
constant depth : integer := 2**addr_width;
type RAMtype is array (0 to depth-1) of unsigned (data_width-1 downto 0);
shared variable RAM : RAMtype;
begin
process (clka)
begin
if clka'event and clka = '1' then
if en_a = '1' then
if we_a = '1' then
RAM(to_integer(addr_a)) := din_a;
end if;
dout_a <= RAM(to_integer(addr_a));
end if;
end if;
end process;
process (clkb)
begin
if clkb'event and clkb = '1' then
if en_b = '1' then
if we_b = '1' then
RAM(to_integer(addr_b)) := din_b;
end if;
dout_b <= RAM(to_integer(addr_b));
end if;
end if;
end process;
end Behavioral;
+117
View File
@@ -0,0 +1,117 @@
--------------------------------------------------------------------------
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
-- This file: On-Chip registers
--
-- Copyright (C) 2007 J. Ahrensfeld
--
-- 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/>.
--
-- For questions and ideas, please contact the author at jens@jayfield.org
--
--------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
use work.cpu_pkg.all;
entity chipreg is
Port (
rst : in STD_LOGIC;
clk : in STD_LOGIC;
we : in STD_LOGIC;
addr : in dmem_addr_t;
din : in dmem_data_t;
dout : out dmem_data_t;
ctrl_in : in creg_ctrl_in_t;
ctrl_out : out creg_ctrl_out_t
);
end chipreg;
architecture Behavioral of chipreg is
signal reg_bank_sel : bank_sel_t;
signal reg_int_ctrl : int_ctrl_in_t;
signal reg_stk_high : unsigned(IMEM_ADDR_WIDTH-DMEM_ADDR_WIDTH-1 downto 0);
signal reg_cmem_high : unsigned(IMEM_ADDR_WIDTH-DMEM_ADDR_WIDTH-1 downto 0);
begin
proc_assign_ctrl_lines:
process (clk)
begin
if rising_edge(clk) then
ctrl_out.bank_sel <= reg_bank_sel;
ctrl_out.int_ctrl <= reg_int_ctrl;
ctrl_out.stk_high <= reg_stk_high;
ctrl_out.cmem_high <= reg_cmem_high;
end if;
end process;
proc_reg_write:
process (rst, clk)
begin
if rst = '1' then
reg_stk_high <= (others => '0');
reg_cmem_high <= (others => '0');
reg_bank_sel <= (others => '0');
reg_int_ctrl.enable <= '0';
elsif rising_edge(clk) then
if we = '1' then
case addr is
when X"01" =>
reg_bank_sel(bank_sel_t'range) <= din(bank_sel_t'range);
when X"03" =>
reg_int_ctrl.enable <= din(0);
when X"04" =>
reg_cmem_high <= din(IMEM_ADDR_WIDTH-DMEM_ADDR_WIDTH-1 downto 0);
when X"05" =>
reg_stk_high <= din(IMEM_ADDR_WIDTH-DMEM_ADDR_WIDTH-1 downto 0);
when others => null;
end case;
end if;
end if;
end process;
proc_reg_read:
process (clk)
begin
if rising_edge(clk) then
case addr is
when X"00" => -- Revison
dout <= to_unsigned(REVISION, dmem_data_t'length);
when X"01" => -- Control 0
dout <= (7 downto bank_sel_t'length => '0') & reg_bank_sel;
when X"02" => -- CPU status
dout <= "000000" & ctrl_in.alu.carry & ctrl_in.alu.zero;
when X"03" => -- Interrupt control
dout <= "0000000" & reg_int_ctrl.enable;
when X"04" => -- Upper stack bits out
dout <= "0000" & reg_cmem_high;
when X"05" => -- Upper cmem bits out
dout <= "0000" & reg_stk_high;
when others =>
if addr(0) = '0' then
dout <= X"DE";
else
dout <= X"AD";
end if;
end case;
end if;
end process;
end Behavioral;
+564
View File
@@ -0,0 +1,564 @@
--------------------------------------------------------------------------
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
-- This file: JCPU top file
--
-- Copyright (C) 2007 J. Ahrensfeld
--
-- 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/>.
--
-- For questions and ideas, please contact the author at jens@jayfield.org
--
--------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
use work.cpu_pkg.all;
entity cpu is
Generic (
use_instr_register : boolean := false;
use_ctrl_rom : boolean := true
);
Port (
rst : in STD_LOGIC;
clk : in STD_LOGIC;
ce : in STD_LOGIC;
int_in : in STD_LOGIC;
int_ack : out STD_LOGIC;
xmem_we : out STD_LOGIC;
xmem_re : out STD_LOGIC;
instr_din : in unsigned (IMEM_DATA_WIDTH-1 downto 0);
instr_addr : out unsigned (IMEM_ADDR_WIDTH-1 downto 0);
xmem_din : in unsigned (DMEM_DATA_WIDTH-1 downto 0);
xmem_dout : out unsigned (DMEM_DATA_WIDTH-1 downto 0);
xmem_addr : out unsigned (DMEM_ADDR_WIDTH-1 downto 0);
io_sel : out std_logic
);
end cpu;
architecture rtl of cpu is
COMPONENT stack_ctrl
GENERIC (
addr_width : integer
);
Port (
rst : in STD_LOGIC;
clk : in STD_LOGIC;
push : in STD_LOGIC;
pop : in STD_LOGIC;
din : in inst_addr_t;
dout : out inst_addr_t;
mem_we : out STD_LOGIC;
ptr_out : out unsigned (addr_width-1 downto 0)
);
END COMPONENT;
COMPONENT pc
Port (
rst : in STD_LOGIC;
clk : in STD_LOGIC;
inc : in STD_LOGIC;
load : in STD_LOGIC;
pc_in : in inst_addr_t;
pc_out : out inst_addr_t;
pc_next : out inst_addr_t
);
END COMPONENT;
COMPONENT dpath_ctrl
GENERIC (
use_rom : boolean
);
Port (
inst_in : in inst_t;
iphase_in : in iphase_t;
status_in : in cpu_status_t;
ctrl_out : out dpath_ctrl_out_t;
idout : out inst_addr_t;
ddout : out dmem_data_t
);
END COMPONENT;
COMPONENT int_ctrl
Port (
rst : in STD_LOGIC;
clk : in STD_LOGIC;
ctrl_in : in int_ctrl_in_t;
int_in : in STD_LOGIC;
int_exit : in STD_LOGIC;
iphase_in : in iphase_t;
int_ack_out : out STD_LOGIC;
stat_save_out : out STD_LOGIC;
stat_rest_out : out STD_LOGIC;
pc_addr_out : out inst_addr_t;
pc_load_out : out STD_LOGIC;
stk_push_out : out STD_LOGIC;
stk_pop_out : out STD_LOGIC
);
END COMPONENT;
COMPONENT reg_dual
GENERIC (
addr_width : integer;
data_width : integer
);
Port (
clk : in STD_LOGIC;
we_a : in STD_LOGIC;
ptr_a : in reg_ptr_t;
ptr_b : in reg_ptr_t;
din_a : in unsigned (data_width-1 downto 0);
dout_a : out unsigned (data_width-1 downto 0);
dout_b : out unsigned (data_width-1 downto 0)
);
END COMPONENT;
COMPONENT chipram
GENERIC (
addr_width : integer;
data_width : integer
);
Port (
clka : in STD_LOGIC;
clkb : in STD_LOGIC;
en_a : in STD_LOGIC;
en_b : in STD_LOGIC;
we_a : in STD_LOGIC;
we_b : in STD_LOGIC;
addr_a : in unsigned (addr_width-1 downto 0);
addr_b : in unsigned (addr_width-1 downto 0);
din_a : in unsigned (data_width-1 downto 0);
din_b : in unsigned (data_width-1 downto 0);
dout_a : out unsigned (data_width-1 downto 0);
dout_b : out unsigned (data_width-1 downto 0)
);
END COMPONENT;
COMPONENT chipreg
Port (
rst : in STD_LOGIC;
clk : in STD_LOGIC;
we : in STD_LOGIC;
addr : in dmem_addr_t;
din : in dmem_data_t;
dout : out dmem_data_t;
ctrl_in : in creg_ctrl_in_t;
ctrl_out : out creg_ctrl_out_t
);
END COMPONENT;
COMPONENT alu
GENERIC (
data_width : integer := 8
);
Port (
rst : in STD_LOGIC;
clk : in STD_LOGIC;
op_en : in STD_LOGIC;
cy_in : in STD_LOGIC;
op1_in : in unsigned (data_width-1 downto 0);
op2_in : in unsigned (data_width-1 downto 0);
opsel : in alu_op_t;
res_out : out unsigned (data_width-1 downto 0);
stat_load : in STD_LOGIC;
stat_in : in alu_status_t;
stat_out : out alu_status_t
);
END COMPONENT;
signal cpu_status, status_reg : cpu_status_t; -- := cpu_status_t(others => '0');
signal ctrl : dpath_ctrl_out_t;
signal stk_out : inst_addr_t;
signal stk_in : inst_addr_t;
signal stk_reg : inst_addr_t;
signal pc_in, pc_out, pc_next, idata, int_pc_addr : inst_addr_t;
signal iphase : iphase_t;
signal const_data, reg_a_dout, reg_b_dout : dmem_data_t;
signal reg_din : dmem_data_t;
signal alu_op1, alu_op2, alu_result : dmem_data_t;
signal alu_status : alu_status_t;
signal pc_inc, pc_load, cpu_active, stk_we, cmem_we, creg_we : STD_LOGIC;
signal ctrl_inst : inst_t;
signal ctrl_iphase : iphase_t;
signal was_pcld, was_pop2pc, int_pc_load, int_stk_push, int_stk_pop, stk_push, stk_pop : STD_LOGIC;
signal status_save, status_restore : STD_LOGIC;
signal creg_dout : dmem_data_t;
signal cmem_din, cmem_dout : inst_addr_t;
signal stk_addr, cmem_addr : unsigned(CHIPRAM_SIZE_BITS-1 downto 0);
signal stk_ptr : unsigned(STACK_SIZE_BITS-1 downto 0);
signal creg_ctrl_out : creg_ctrl_out_t;
signal creg_ctrl_in : creg_ctrl_in_t;
signal irq_out : std_logic;
signal xio_sel, cio_sel : std_logic;
signal mem_data : dmem_data_t;
signal mem_addr : dmem_data_t;
begin
io_sel <= xio_sel;
instr_addr <= pc_out;
pc_inc <= cpu_active and ctrl.lines.pc_inc;
stk_addr <= '0' & stk_ptr;
cpu_status.alu <= alu_status;
creg_ctrl_in.alu <= alu_status;
xmem_dout <= mem_data;
xmem_addr <= mem_addr;
cmem_din <= creg_ctrl_out.cmem_high & mem_data;
cmem_addr <= '1' & creg_ctrl_out.bank_sel & mem_addr(MIN(cmem_addr'length-creg_ctrl_out.bank_sel'length-1, mem_addr'length)-1 downto 0);
--------------------------------------------------------------------
mem_ctrl_lines:
process(ctrl.lines)
begin
xio_sel <= '0';
xmem_re <= '0';
xmem_we <= '0';
cio_sel <= '0';
cmem_we <= '0';
creg_we <= '0';
case ctrl.lines.mem_access is
when xmem_access =>
xmem_re <= ctrl.lines.mem_read;
xmem_we <= ctrl.lines.mem_write;
when xio_access =>
xio_sel <= '1';
xmem_re <= ctrl.lines.mem_read;
xmem_we <= ctrl.lines.mem_write;
when cmem_access =>
cmem_we <= ctrl.lines.mem_write;
when cio_access =>
cio_sel <= '1';
creg_we <= ctrl.lines.mem_write;
when others => null;
end case;
end process;
iphase_counter:
process(rst, clk, ce)
variable pos : integer;
begin
if rst = '1' then
iphase <= iphase_t'low;
cpu_active <= '0';
elsif rising_edge(clk) then
cpu_active <= '0';
if ce = '1' then
cpu_active <= '1';
if iphase = iphase_t'high then
iphase <= iphase_t'low;
else
iphase <= iphase + 1;
end if;
end if;
end if;
end process;
gen_instr_reg:
if use_instr_register = true generate
instr_reg:
process (rst, clk, ce)
begin
if rst = '1' then
ctrl_inst <= (others => '0');
ctrl_iphase <= 0;
elsif rising_edge(clk) and ce = '1' then
ctrl_inst <= instr_din;
ctrl_iphase <= iphase;
end if;
end process;
end generate;
gen_instr_direct:
if use_instr_register = false generate
ctrl_inst <= instr_din;
ctrl_iphase <= iphase;
end generate;
status_register:
process(clk, status_save)
begin
if rising_edge(clk) and status_save = '1' then
status_reg.alu <= alu_status;
end if;
end process;
pc_pushpop:
process(ctrl.lines, int_pc_load, int_stk_push, int_stk_pop, was_pop2pc)
begin
pc_load <= ctrl.lines.pc_load or int_pc_load;
stk_push <= (ctrl.lines.stk_pushd or ctrl.lines.stk_push) or (int_stk_push and not was_pop2pc);
stk_pop <= ctrl.lines.stk_popd or int_stk_pop or (ctrl.lines.stk_pop and not int_pc_load);
end process;
lines_delay:
process(clk)
begin
if rising_edge(clk) then
was_pcld <= ctrl.lines.pc_load;
was_pop2pc <= ctrl.lines.stk_pop and ctrl.lines.pc_load;
end if;
end process;
stk_mux:
process(ctrl.lines, was_pcld, int_stk_push, pc_next, idata, reg_a_dout, creg_ctrl_out)
begin
if was_pcld = '1' and int_stk_push = '1' then
stk_in <= idata;
elsif ctrl.lines.stk_pushd = '1' then
stk_in <= creg_ctrl_out.stk_high & reg_a_dout;
else
stk_in <= pc_next;
end if;
end process;
pc_mux:
process(ctrl.lines, int_pc_load, int_stk_pop, idata, int_pc_addr, stk_out)
begin
pc_in <= stk_out;
if int_pc_load = '1' then
if int_stk_pop = '0' then
pc_in <= int_pc_addr;
end if;
elsif ctrl.lines.pc_load = '1' then
if ctrl.lines.stk_pop = '0' then
pc_in <= idata;
end if;
end if;
end process;
mem_data_mux:
process(ctrl.lines.ddata_src_sel, reg_a_dout, reg_b_dout, const_data, creg_ctrl_out)
begin
case ctrl.lines.ddata_src_sel is
when reg_a =>
mem_data <= reg_a_dout;
when reg_b =>
mem_data <= reg_b_dout;
when const =>
mem_data <= const_data;
when others =>
mem_data <= const_data;
end case;
end process;
mem_addr_mux:
process(ctrl.lines.daddr_src_sel, reg_a_dout, reg_b_dout, const_data, creg_ctrl_out.bank_sel)
begin
case ctrl.lines.daddr_src_sel is
when reg_a =>
mem_addr <= reg_a_dout;
when reg_b =>
mem_addr <= reg_b_dout;
when const =>
mem_addr <= const_data;
when others =>
mem_addr <= const_data;
end case;
end process;
reg_in_mux:
process(ctrl.lines.reg_src_sel, cio_sel, xmem_din, alu_result, stk_out, cmem_dout, creg_dout)
variable data : dmem_data_t;
begin
case ctrl.lines.reg_src_sel is
when xmem_src =>
data := xmem_din;
when cmem_src =>
if cio_sel = '0' then
data := cmem_dout(dmem_data_t'range);
else
data := creg_dout(dmem_data_t'range);
end if;
when stk_src =>
data := stk_out(dmem_data_t'range);
when others =>
data := alu_result;
end case;
reg_din <= data;
end process;
alu_op1_mux:
process(ctrl.lines.alu_op1_src_sel, reg_a_dout, reg_b_dout, const_data)
variable data : dmem_data_t;
begin
case ctrl.lines.alu_op1_src_sel is
when reg_a =>
data := reg_a_dout;
when reg_b =>
data := reg_b_dout;
when others =>
data := const_data;
end case;
alu_op1 <= data;
end process;
alu_op2_mux:
process(ctrl.lines.alu_op2_src_sel, reg_a_dout, reg_b_dout, const_data)
variable data : dmem_data_t;
begin
case ctrl.lines.alu_op2_src_sel is
when reg_a =>
data := reg_a_dout;
when reg_b =>
data := reg_b_dout;
when others =>
data := const_data;
end case;
alu_op2 <= data;
end process;
--------------------------------------------------------------------
inst_stack_ctrl: stack_ctrl
GENERIC MAP (
addr_width => STACK_SIZE_BITS
)
PORT MAP(
rst => rst,
clk => clk,
push => stk_push,
pop => stk_pop,
dout => stk_reg,
din => stk_in,
ptr_out => stk_ptr,
mem_we => stk_we
);
inst_pc: pc
PORT MAP(
rst => rst,
clk => clk,
inc => pc_inc,
load => pc_load,
pc_in => pc_in,
pc_out => pc_out,
pc_next => pc_next
);
inst_dpath_ctrl: dpath_ctrl
GENERIC MAP (
use_rom => use_ctrl_rom
)
PORT MAP(
inst_in => ctrl_inst,
iphase_in => ctrl_iphase,
status_in => cpu_status,
ctrl_out => ctrl,
ddout => const_data,
idout => idata
);
inst_int_ctrl: int_ctrl
PORT MAP(
rst => rst,
clk => clk,
ctrl_in => creg_ctrl_out.int_ctrl,
int_in => int_in,
int_ack_out => int_ack,
int_exit => ctrl.lines.int_exit,
iphase_in => ctrl_iphase,
stat_save_out => status_save,
stat_rest_out => status_restore,
pc_addr_out => int_pc_addr,
pc_load_out => int_pc_load,
stk_push_out => int_stk_push,
stk_pop_out => int_stk_pop
);
inst_reg_ab: reg_dual
GENERIC MAP (
addr_width => REG_SIZE_BITS,
data_width => DMEM_DATA_WIDTH
)
PORT MAP(
clk => clk,
we_a => ctrl.lines.reg_we,
ptr_a => ctrl.reg_a_ptr,
ptr_b => ctrl.reg_b_ptr,
din_a => reg_din,
dout_a => reg_a_dout,
dout_b => reg_b_dout
);
inst_chipram: chipram
GENERIC MAP (
addr_width => CHIPRAM_SIZE_BITS,
data_width => IMEM_ADDR_WIDTH
)
PORT MAP(
clka => clk,
clkb => clk,
en_a => cpu_active,
en_b => cpu_active,
we_a => stk_we,
we_b => cmem_we,
addr_a => stk_addr,
addr_b => cmem_addr,
din_a => stk_reg,
din_b => cmem_din,
dout_a => stk_out,
dout_b => cmem_dout
);
inst_chipreg: chipreg
PORT MAP(
rst => rst,
clk => clk,
we => creg_we,
addr => mem_addr,
din => mem_data,
dout => creg_dout,
ctrl_in => creg_ctrl_in,
ctrl_out => creg_ctrl_out
);
inst_alu: alu
GENERIC MAP (
data_width => DMEM_DATA_WIDTH
)
PORT MAP(
rst => rst,
clk => clk,
op_en => ctrl.lines.alu_load,
cy_in => ctrl.lines.alu_cy_in,
op1_in => alu_op1,
op2_in => alu_op2,
opsel => ctrl.lines.alu_opsel,
res_out => alu_result,
stat_load => status_restore,
stat_in => status_reg.alu,
stat_out => alu_status
);
end rtl;
+856
View File
@@ -0,0 +1,856 @@
--------------------------------------------------------------------------
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
-- This file: Types, constants and functions for JCPU
--
-- Copyright (C) 2007 J. Ahrensfeld
--
-- 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/>.
--
-- For questions and ideas, please contact the author at jens@jayfield.org
--
--------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
package cpu_pkg is
-- Revision of the CPU
constant REVISION : integer := 4;
-- Chipram depth (valid values 9..floor(log2(BlockRamBytes)))
constant CHIPRAM_SIZE_BITS : integer := 10;
-- Number of registers (16 registers fixed)
constant REG_SIZE_BITS : integer := 4;
-- Instruction memory
constant IMEM_ADDR_WIDTH : integer := 12;
-- Data memory
constant DMEM_DATA_WIDTH : integer := 8;
constant DMEM_ADDR_WIDTH : integer := 8;
-- Instruction format
constant INST_OPCODE_WIDTH : integer := 6;
constant IMEM_DATA_WIDTH : integer := INST_OPCODE_WIDTH + DMEM_DATA_WIDTH + REG_SIZE_BITS;
-- Microcode ROM
constant MUCODE_ADDR_WIDTH : integer := 9;
-- Stack depth (uses lower half of CHIPRAM)
constant STACK_SIZE_BITS : integer := CHIPRAM_SIZE_BITS-1;
--Types
subtype iphase_t is integer range 0 to 1;
type mem_access_t is (cmem_access, xmem_access, cio_access, xio_access);
type reg_src_t is (alu_src, stk_src, cmem_src, xmem_src);
type alu_src_t is (reg_a, reg_b, const);
type ddata_src_t is (reg_a, reg_b, const);
type daddr_src_t is (reg_a, reg_b, const);
subtype instr_name_t is string(1 to 12);
type instr_name_array_t is array (0 to 63) of instr_name_t;
subtype opcode_t is unsigned (INST_OPCODE_WIDTH-1 downto 0);
subtype inst_data_t is unsigned (IMEM_ADDR_WIDTH-1 downto 0);
subtype inst_addr_t is unsigned (IMEM_ADDR_WIDTH-1 downto 0);
subtype inst_t is unsigned (IMEM_DATA_WIDTH-1 downto 0);
subtype dmem_data_t is unsigned (DMEM_DATA_WIDTH-1 downto 0);
subtype dmem_addr_t is unsigned (DMEM_DATA_WIDTH-1 downto 0);
subtype reg_ptr_t is unsigned (3 downto 0);
type dmem_array_t is array (natural range <>) of dmem_data_t;
type instr_addr_array is array (integer range <>) of inst_addr_t;
subtype bank_sel_t is unsigned (CHIPRAM_SIZE_BITS-DMEM_DATA_WIDTH-2 downto 0);
type alu_op_t is
(
pass_op2,
op1_add_op2,
op1_sub_op2,
op1_addc_op2,
op1_subc_op2,
op1_and_op2,
op1_or_op2,
op1_xor_op2,
swap_op,
shl_op,
shr_op,
rol_op,
ror_op,
rolc_op,
rorc_op
);
type alu_status_t is record
zero : STD_LOGIC;
carry : STD_LOGIC;
end record;
type cpu_status_t is record
alu : alu_status_t;
end record;
type ctrl_lines_t is record
reg_we : STD_LOGIC;
reg_src_sel : reg_src_t;
alu_op1_src_sel : alu_src_t;
alu_op2_src_sel : alu_src_t;
alu_opsel : alu_op_t;
alu_load : STD_LOGIC;
alu_cy_in : STD_LOGIC;
ddata_src_sel : ddata_src_t;
daddr_src_sel : daddr_src_t;
pc_load : STD_LOGIC;
pc_inc : STD_LOGIC;
stk_push : STD_LOGIC;
stk_pop : STD_LOGIC;
stk_pushd : STD_LOGIC;
stk_popd : STD_LOGIC;
mem_access : mem_access_t;
mem_read : STD_LOGIC;
mem_write : STD_LOGIC;
int_exit : STD_LOGIC;
end record;
type dpath_ctrl_out_t is record
lines : ctrl_lines_t;
reg_a_ptr : reg_ptr_t;
reg_b_ptr : reg_ptr_t;
end record;
type int_ctrl_in_t is record
enable : std_logic;
end record;
type creg_ctrl_out_t is record
bank_sel : bank_sel_t;
int_ctrl : int_ctrl_in_t;
stk_high : unsigned(IMEM_ADDR_WIDTH-DMEM_ADDR_WIDTH-1 downto 0);
cmem_high : unsigned(IMEM_ADDR_WIDTH-DMEM_ADDR_WIDTH-1 downto 0);
end record;
type creg_ctrl_in_t is record
alu : alu_status_t;
end record;
type murom_t is array (0 to integer(2**MUCODE_ADDR_WIDTH)-1) of ctrl_lines_t;
constant instr_name_array : instr_name_array_t :=
(
"NOP ", -- 00
"HALT ", -- 01
"MOV|R|R ", -- 02
"MOV|R|K ", -- 03
"MOVX|R|Ri ", -- 04
"MOVX|R|Ki ", -- 05
"MOVX|Ri|R ", -- 06
"MOVX|Ri|K ", -- 07
"MOVX|Ki|R ", -- 08
"MOVC|R|Ri ", -- 09
"MOVC|R|Ki ", -- 0A
"MOVC|Ri|R ", -- 0B
"MOVC|Ri|K ", -- 0C
"MOVC|Ki|R ", -- 0D
"CMP|R|R ", -- 0E
"CMP|R|K ", -- 0F
"ADD|R|R ", -- 10
"ADD|R|K ", -- 11
"ADDC|R|R ", -- 12
"ADDC|R|K ", -- 13
"SUB|R|R ", -- 14
"SUB|R|K ", -- 15
"SUBC|R|R ", -- 16
"SUBC|R|K ", -- 17
"AND|R|R ", -- 18
"AND|R|K ", -- 19
"OR|R|R ", -- 1A
"OR|R|K ", -- 1B
"XOR|R|R ", -- 1C
"XOR|R|K ", -- 1D
"SHL|R ", -- 1E
"SHR|R ", -- 1F
"ROL|R ", -- 20
"ROR|R ", -- 21
"ROLC|R ", -- 22
"RORC|R ", -- 23
"XOUT|Ki|R ", -- 24
"XOUT|Ri|K ", -- 25
"COUT|Ki|R ", -- 26
"COUT|Ri|K ", -- 27
"XIN|R|Ki ", -- 28
"CIN|R|Ki ", -- 29
"SWAP|R ", -- 2A
"SETC ", -- 2B
"UNDEF ", -- 2C
"UNDEF ", -- 2D
"SUB|K|R ", -- 2E
"SUBC|K|R ", -- 2F
"JMP|K ", -- 30
"JZ|K ", -- 31
"JNZ|K ", -- 32
"JC|K ", -- 33
"JNC|K ", -- 34
"JLT|K ", -- 35
"JGT|K ", -- 36
"JLE|K ", -- 37
"JGE|K ", -- 38
"JEQ|K ", -- 39
"JNE|K ", -- 3A
"CALL|K ", -- 3B
"PUSH|R ", -- 3C
"POP|R ", -- 3D
"RET ", -- 3E
"RETI " -- 3F
);
-- Functions
function Instr(opcode : opcode_t) return inst_t;
function Instr(opcode : opcode_t; data : inst_data_t) return inst_t;
function Instr(opcode : opcode_t; data : inst_data_t; reg : integer) return inst_t;
function Instr(opcode : opcode_t; reg_a : integer) return inst_t;
function Instr(opcode : opcode_t; reg_a, reg_b : integer) return inst_t;
function Instr(opcode : opcode_t; reg_a, reg_b, reg_c : integer) return inst_t;
function ctrl_lines_default return ctrl_lines_t;
function idecoder(instr_name : instr_name_t; iphase : iphase_t; status : cpu_status_t) return ctrl_lines_t;
function idecoder(opcode : opcode_t; iphase : iphase_t; status : cpu_status_t) return ctrl_lines_t;
function gen_murom return murom_t;
function get_muromaddr (opcode : opcode_t; iphase : iphase_t; status : cpu_status_t) return unsigned;
function MIN (X, Y: INTEGER) return INTEGER;
function MAX (X, Y: INTEGER) return INTEGER;
end cpu_pkg;
package body cpu_pkg is
function Instr(opcode : opcode_t) return inst_t is
variable inst : inst_t := (others => '0');
begin
inst(inst_t'length-1 downto inst_t'length-opcode_t'length) := opcode;
return inst;
end Instr;
function Instr(opcode : opcode_t; data : inst_data_t) return inst_t is
variable inst : inst_t := (others => '0');
begin
inst(inst_t'length-1 downto inst_t'length-opcode_t'length) := opcode;
inst(inst_t'length-opcode_t'length-1 downto inst_t'length-opcode_t'length-inst_addr_t'length) := data;
return inst;
end Instr;
function Instr(opcode : opcode_t; data : inst_data_t; reg : integer) return inst_t is
variable inst : inst_t := (others => '0');
begin
inst(inst_t'length-1 downto inst_t'length-opcode_t'length) := opcode;
inst(inst_t'length-opcode_t'length-1 downto inst_t'length-opcode_t'length-inst_data_t'length) := data;
inst(reg_ptr_t'length-1 downto 0) := reg_ptr_t(to_unsigned(reg, reg_ptr_t'length));
return inst;
end Instr;
function Instr(opcode : opcode_t; reg_a : integer) return inst_t is
variable inst : inst_t := (others => '0');
begin
inst(inst_t'length-1 downto inst_t'length-opcode_t'length) := opcode;
inst(reg_ptr_t'length-1 downto 0) := reg_ptr_t(to_unsigned(reg_a, reg_ptr_t'length));
return inst;
end Instr;
function Instr(opcode : opcode_t; reg_a, reg_b : integer) return inst_t is
variable inst : inst_t := (others => '0');
begin
inst(inst_t'length-1 downto inst_t'length-opcode_t'length) := opcode;
inst(2*(reg_ptr_t'length)-1 downto reg_ptr_t'length) := reg_ptr_t(to_unsigned(reg_b, reg_ptr_t'length));
inst(reg_ptr_t'length-1 downto 0) := reg_ptr_t(to_unsigned(reg_a, reg_ptr_t'length));
return inst;
end Instr;
function Instr(opcode : opcode_t; reg_a, reg_b, reg_c : integer) return inst_t is
variable inst : inst_t := (others => '0');
begin
inst(inst_t'length-1 downto inst_t'length-opcode_t'length) := opcode;
inst(3*(reg_ptr_t'length)-1 downto 2*reg_ptr_t'length) := reg_ptr_t(to_unsigned(reg_c, reg_ptr_t'length));
inst(2*(reg_ptr_t'length)-1 downto reg_ptr_t'length) := reg_ptr_t(to_unsigned(reg_b, reg_ptr_t'length));
inst(reg_ptr_t'length-1 downto 0) := reg_ptr_t(to_unsigned(reg_a, reg_ptr_t'length));
return inst;
end Instr;
function ctrl_lines_default return ctrl_lines_t is
variable result : ctrl_lines_t;
begin
result.pc_load := '0';
result.pc_inc := '0';
result.stk_push := '0';
result.stk_pop := '0';
result.stk_pushd := '0';
result.stk_popd := '0';
result.reg_we := '0';
result.reg_src_sel := alu_src;
result.ddata_src_sel := reg_a;
result.daddr_src_sel := reg_b;
result.alu_opsel := pass_op2;
result.alu_op1_src_sel := reg_a;
result.alu_op2_src_sel := reg_b;
result.alu_load := '0';
result.alu_cy_in := '0';
result.mem_access := cmem_access;
result.mem_read := '0';
result.mem_write := '0';
result.int_exit := '0';
return result;
end ctrl_lines_default;
function idecoder(opcode : opcode_t; iphase : iphase_t; status : cpu_status_t) return ctrl_lines_t is
variable instr_name : instr_name_t;
begin
instr_name := instr_name_array(to_integer(opcode));
return idecoder(instr_name, iphase, status);
end idecoder;
function idecoder(instr_name : instr_name_t; iphase : iphase_t; status : cpu_status_t) return ctrl_lines_t is
variable result : ctrl_lines_t;
variable ze, cy : STD_LOGIC;
begin
ze := status.alu.zero;
cy := status.alu.carry;
result := ctrl_lines_default;
if iphase = 0 then
result.pc_inc := '1';
end if;
case instr_name is
when "HALT " =>
result.pc_inc := '0';
when "SETC " => -- carry <= 1
result.reg_src_sel := alu_src;
result.alu_opsel := pass_op2;
result.alu_op2_src_sel := reg_b;
result.alu_load := '1';
result.alu_cy_in := '1';
when "MOV|R|R " => -- R(a) <= R(b)
result.reg_src_sel := alu_src;
result.alu_opsel := pass_op2;
result.alu_op2_src_sel := reg_b;
result.alu_load := '1';
if iphase = 1 then
result.reg_we := '1';
end if;
when "MOV|R|K " => -- R(a) <= #kk
result.reg_src_sel := alu_src;
result.alu_opsel := pass_op2;
result.alu_op2_src_sel := const;
result.alu_load := '1';
if iphase = 1 then
result.reg_we := '1';
end if;
when "MOVC|Ri|R " => -- [R(b)] <= R(a)
result.mem_access := cmem_access;
result.daddr_src_sel := reg_b;
result.ddata_src_sel := reg_a;
if iphase = 0 then
result.mem_write := '1';
end if;
when "MOVC|Ri|K " => -- [R(a)] <= kk
result.mem_access := cmem_access;
result.daddr_src_sel := reg_a;
result.ddata_src_sel := const;
if iphase = 0 then
result.mem_write := '1';
end if;
when "COUT|Ri|K " => -- [R(a)] <= kk
result.mem_access := cio_access;
result.daddr_src_sel := reg_a;
result.ddata_src_sel := const;
if iphase = 0 then
result.mem_write := '1';
end if;
when "MOVC|R|Ri " => -- R(a) <= [R(b)]
result.mem_access := cmem_access;
result.reg_src_sel := cmem_src;
result.daddr_src_sel := reg_b;
if iphase = 1 then
result.reg_we := '1';
end if;
when "MOVC|R|Ki " => -- R(a) <= [#addr]
result.mem_access := cmem_access;
result.reg_src_sel := cmem_src;
result.daddr_src_sel := const;
if iphase = 1 then
result.reg_we := '1';
end if;
when "CIN|R|Ki " => -- R(a) <= [#addr]
result.mem_access := cio_access;
result.reg_src_sel := cmem_src;
result.daddr_src_sel := const;
if iphase = 1 then
result.reg_we := '1';
end if;
when "MOVC|Ki|R " => -- [#addr] <= R(a)
result.mem_access := cmem_access;
result.daddr_src_sel := const;
result.ddata_src_sel := reg_a;
if iphase = 0 then
result.mem_write := '1';
end if;
when "COUT|Ki|R " => -- [#addr] <= R(a)
result.mem_access := cio_access;
result.daddr_src_sel := const;
result.ddata_src_sel := reg_a;
if iphase = 0 then
result.mem_write := '1';
end if;
when "MOVX|Ri|R " => -- [R(b)] <= R(a)
result.mem_access := xmem_access;
result.daddr_src_sel := reg_b;
result.ddata_src_sel := reg_a;
if iphase = 0 then
result.mem_write := '1';
end if;
when "MOVX|Ri|K " => -- [R(a)] <= kk
result.mem_access := xmem_access;
result.daddr_src_sel := reg_a;
result.ddata_src_sel := const;
if iphase = 0 then
result.mem_write := '1';
end if;
when "XOUT|Ri|K " => -- [R(a)] <= kk
result.mem_access := xio_access;
result.daddr_src_sel := reg_a;
result.ddata_src_sel := const;
if iphase = 0 then
result.mem_write := '1';
end if;
when "MOVX|R|Ri " => -- R(a) <= [R(b)]
result.mem_access := xmem_access;
result.reg_src_sel := xmem_src;
result.daddr_src_sel := reg_b;
if iphase = 0 then
result.mem_read := '1';
elsif iphase = 1 then
result.reg_we := '1';
end if;
when "MOVX|R|Ki " => -- R(a) <= [#addr]
result.mem_access := xmem_access;
result.reg_src_sel := xmem_src;
result.daddr_src_sel := const;
if iphase = 0 then
result.mem_read := '1';
elsif iphase = 1 then
result.reg_we := '1';
end if;
when "XIN|R|Ki " => -- R(a) <= [#addr]
result.mem_access := xio_access;
result.reg_src_sel := xmem_src;
result.daddr_src_sel := const;
if iphase = 0 then
result.mem_read := '1';
elsif iphase = 1 then
result.reg_we := '1';
end if;
when "MOVX|Ki|R " => -- [#addr] <= R(a)
result.mem_access := xmem_access;
result.daddr_src_sel := const;
result.ddata_src_sel := reg_a;
if iphase = 0 then
result.mem_write := '1';
end if;
when "XOUT|Ki|R " => -- [#addr] <= R(a)
result.mem_access := xio_access;
result.daddr_src_sel := const;
result.ddata_src_sel := reg_a;
if iphase = 0 then
result.mem_write := '1';
end if;
when "ADD|R|R " => -- R(a) <= R(a) + R(b)
result.alu_opsel := op1_add_op2;
result.alu_op1_src_sel := reg_a;
result.alu_op2_src_sel := reg_b;
result.reg_src_sel := alu_src;
result.alu_load := '1';
if iphase = 1 then
result.reg_we := '1';
end if;
when "ADD|R|K " => -- R(a) <= R(a) + k
result.alu_opsel := op1_add_op2;
result.alu_op1_src_sel := reg_a;
result.alu_op2_src_sel := const;
result.reg_src_sel := alu_src;
result.alu_load := '1';
if iphase = 1 then
result.reg_we := '1';
end if;
when "ADDC|R|R " => -- R(a) <= R(a) + R(b)
result.alu_opsel := op1_addc_op2;
result.alu_op1_src_sel := reg_a;
result.alu_op2_src_sel := reg_b;
result.reg_src_sel := alu_src;
result.alu_load := '1';
if iphase = 1 then
result.reg_we := '1';
end if;
when "ADDC|R|K " => -- R(a) <= R(a) + k
result.alu_opsel := op1_addc_op2;
result.alu_op1_src_sel := reg_a;
result.alu_op2_src_sel := const;
result.reg_src_sel := alu_src;
result.alu_load := '1';
if iphase = 1 then
result.reg_we := '1';
end if;
when "SUB|R|R " => -- R(a) <= R(a) + R(b)
result.alu_opsel := op1_sub_op2;
result.alu_op1_src_sel := reg_a;
result.alu_op2_src_sel := reg_b;
result.reg_src_sel := alu_src;
result.alu_load := '1';
if iphase = 1 then
result.reg_we := '1';
end if;
when "SUB|R|K " => -- R(a) <= R(a) + k
result.alu_opsel := op1_sub_op2;
result.alu_op1_src_sel := reg_a;
result.alu_op2_src_sel := const;
result.reg_src_sel := alu_src;
result.alu_load := '1';
if iphase = 1 then
result.reg_we := '1';
end if;
when "SUB|K|R " => -- R(a) <= k - R(a)
result.alu_opsel := op1_sub_op2;
result.alu_op1_src_sel := const;
result.alu_op2_src_sel := reg_a;
result.reg_src_sel := alu_src;
result.alu_load := '1';
if iphase = 1 then
result.reg_we := '1';
end if;
when "SUBC|R|R " => -- R(a) <= R(a) + R(b)
result.alu_opsel := op1_subc_op2;
result.alu_op1_src_sel := reg_a;
result.alu_op2_src_sel := reg_b;
result.reg_src_sel := alu_src;
result.alu_load := '1';
if iphase = 1 then
result.reg_we := '1';
end if;
when "SUBC|R|K " => -- R(a) <= R(a) + k
result.alu_opsel := op1_subc_op2;
result.alu_op1_src_sel := reg_a;
result.alu_op2_src_sel := const;
result.reg_src_sel := alu_src;
result.alu_load := '1';
if iphase = 1 then
result.reg_we := '1';
end if;
when "SUBC|K|R " => -- R(a) <= K - R(a)
result.alu_opsel := op1_subc_op2;
result.alu_op1_src_sel := const;
result.alu_op2_src_sel := reg_a;
result.reg_src_sel := alu_src;
result.alu_load := '1';
if iphase = 1 then
result.reg_we := '1';
end if;
when "AND|R|R " => -- R(a) <= R(a) and R(b)
result.alu_opsel := op1_and_op2;
result.alu_op1_src_sel := reg_a;
result.alu_op2_src_sel := reg_b;
result.reg_src_sel := alu_src;
result.alu_load := '1';
if iphase = 1 then
result.reg_we := '1';
end if;
when "AND|R|K " => -- R(a) <= R(a) and k
result.alu_opsel := op1_and_op2;
result.alu_op1_src_sel := reg_a;
result.alu_op2_src_sel := const;
result.reg_src_sel := alu_src;
result.alu_load := '1';
if iphase = 1 then
result.reg_we := '1';
end if;
when "OR|R|R " => -- R(a) <= R(a) or R(b)
result.alu_opsel := op1_or_op2;
result.alu_op1_src_sel := reg_a;
result.alu_op2_src_sel := reg_b;
result.reg_src_sel := alu_src;
result.alu_load := '1';
if iphase = 1 then
result.reg_we := '1';
end if;
when "OR|R|K " => -- R(a) <= R(a) or R(b)
result.alu_opsel := op1_or_op2;
result.alu_op1_src_sel := reg_a;
result.alu_op2_src_sel := const;
result.reg_src_sel := alu_src;
result.alu_load := '1';
if iphase = 1 then
result.reg_we := '1';
end if;
when "XOR|R|R " => -- R(a) <= R(a) xor R(b)
result.alu_opsel := op1_xor_op2;
result.alu_op1_src_sel := reg_a;
result.alu_op2_src_sel := reg_b;
result.reg_src_sel := alu_src;
result.alu_load := '1';
if iphase = 1 then
result.reg_we := '1';
end if;
when "XOR|R|K " => -- R(a) <= R(a) xor R(b)
result.alu_opsel := op1_xor_op2;
result.alu_op1_src_sel := reg_a;
result.alu_op2_src_sel := const;
result.reg_src_sel := alu_src;
result.alu_load := '1';
if iphase = 1 then
result.reg_we := '1';
end if;
when "SWAP|R " => -- R(a) <= R(b)
result.reg_src_sel := alu_src;
result.alu_opsel := swap_op;
result.alu_op1_src_sel := reg_a;
result.alu_load := '1';
if iphase = 1 then
result.reg_we := '1';
end if;
when "SHL|R " => -- R(a) <= R(a) xor R(b)
result.reg_src_sel := alu_src;
result.alu_opsel := shl_op;
result.alu_op1_src_sel := reg_a;
result.alu_load := '1';
if iphase = 1 then
result.reg_we := '1';
end if;
when "SHR|R " => -- R(a) <= R(a) xor R(b)
result.reg_src_sel := alu_src;
result.alu_opsel := shr_op;
result.alu_op1_src_sel := reg_a;
result.alu_load := '1';
if iphase = 1 then
result.reg_we := '1';
end if;
when "ROL|R " => -- R(a) <= R(a) xor R(b)
result.reg_src_sel := alu_src;
result.alu_opsel := rol_op;
result.alu_op1_src_sel := reg_a;
result.alu_load := '1';
if iphase = 1 then
result.reg_we := '1';
end if;
when "ROR|R " => -- R(a) <= R(a) xor R(b)
result.reg_src_sel := alu_src;
result.alu_opsel := ror_op;
result.alu_op1_src_sel := reg_a;
result.alu_load := '1';
if iphase = 1 then
result.reg_we := '1';
end if;
when "ROLC|R " => -- R(a) <= R(a) xor R(b)
result.reg_src_sel := alu_src;
result.alu_opsel := rolc_op;
result.alu_op1_src_sel := reg_a;
result.alu_load := '1';
if iphase = 1 then
result.reg_we := '1';
end if;
when "RORC|R " => -- R(a) <= R(a) xor R(b)
result.reg_src_sel := alu_src;
result.alu_opsel := rorc_op;
result.alu_op1_src_sel := reg_a;
result.alu_load := '1';
if iphase = 1 then
result.reg_we := '1';
end if;
when "CMP|R|R " => --
result.alu_opsel := op1_sub_op2;
result.alu_op1_src_sel := reg_a;
result.alu_op2_src_sel := reg_b;
result.alu_load := '1';
when "CMP|R|K " => --
result.alu_opsel := op1_sub_op2;
result.alu_op1_src_sel := reg_a;
result.alu_op2_src_sel := const;
result.alu_load := '1';
when "JMP|K " => -- PC <= #addr
if iphase = 0 then
result.pc_load := '1';
end if;
when "JZ|K " => -- PC <= #addr, zero
if iphase = 0 then
if ze = '1' then
result.pc_load := '1';
end if;
end if;
when "JNZ|K " => -- PC <= #addr, !zero
if iphase = 0 then
if ze = '0' then
result.pc_load := '1';
end if;
end if;
when "JC|K " => -- PC <= #addr, carry
if iphase = 0 then
if cy = '1' then
result.pc_load := '1';
end if;
end if;
when "JNC|K " => -- PC <= #addr, !carry
if iphase = 0 then
if cy = '0' then
result.pc_load := '1';
end if;
end if;
when "JLT|K " => -- PC <= #addr, !carry
if iphase = 0 then
if cy = '1' then
result.pc_load := '1';
end if;
end if;
when "JGT|K " => --
if iphase = 0 then
if (cy or ze) = '0' then
result.pc_load := '1';
end if;
end if;
when "JLE|K " => --
if iphase = 0 then
if (cy xor ze) = '1' then
result.pc_load := '1';
end if;
end if;
when "JGE|K " => --
if iphase = 0 then
if (not cy or ze) = '1' then
result.pc_load := '1';
end if;
end if;
when "JEQ|K " => --
if iphase = 0 then
if ze = '1' then
result.pc_load := '1';
end if;
end if;
when "JNE|K " => --
if iphase = 0 then
if ze = '0' then
result.pc_load := '1';
end if;
end if;
when "PUSH|R " => -- push
if iphase = 0 then
result.stk_pushd := '1';
end if;
when "POP|R " => -- pop
result.reg_src_sel := stk_src;
if iphase = 0 then
result.stk_popd := '1';
elsif iphase = 1 then
result.reg_we := '1';
end if;
when "CALL|K " => -- call
if iphase = 0 then
result.pc_load := '1';
result.stk_push := '1';
end if;
when "RET " => -- return
if iphase = 0 then
result.pc_load := '1';
result.stk_pop := '1';
end if;
when "RETI " => -- return
result.pc_inc := '0';
result.int_exit := '1';
when others => null; -- nop
end case;
return result;
end idecoder;
function gen_murom return murom_t is
variable result : murom_t;
variable opcode : opcode_t;
variable iphase : iphase_t;
variable addr : unsigned(MUCODE_ADDR_WIDTH-1 downto 0);
variable status : cpu_status_t;
variable pos : integer := 0;
begin
for i in 0 to 2**addr'length-1 loop
addr := to_unsigned(i, addr'length);
opcode := addr(opcode'length-1 downto 0);
pos := opcode'length;
iphase := 0;
if addr(pos) = '1' then
iphase := 1;
end if;
pos := pos + 1;
status.alu.zero := addr(pos);
pos := pos + 1;
status.alu.carry := addr(pos);
result(i) := idecoder(opcode, iphase, status);
end loop;
return result;
end gen_murom;
function get_muromaddr (opcode : opcode_t; iphase : iphase_t; status : cpu_status_t) return unsigned is
variable addr : unsigned(MUCODE_ADDR_WIDTH-1 downto 0);
begin
addr := status.alu.carry & status.alu.zero & to_unsigned(iphase, 1) & opcode;
return addr;
end get_muromaddr;
-------------------------------------------------------------
function MIN (X, Y: INTEGER) return INTEGER is
variable res : integer := X;
begin
if Y < X then
res := Y;
end if;
return res;
end MIN;
-------------------------------------------------------------
function MAX (X, Y: INTEGER) return INTEGER is
variable res : integer := X;
begin
if Y > X then
res := Y;
end if;
return res;
end MAX;
end cpu_pkg;
+87
View File
@@ -0,0 +1,87 @@
--------------------------------------------------------------------------
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
-- This file: The datapath controller
--
-- Copyright (C) 2007 J. Ahrensfeld
--
-- 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/>.
--
-- For questions and ideas, please contact the author at jens@jayfield.org
--
--------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
use work.cpu_pkg.all;
entity dpath_ctrl is
Generic (
use_rom : boolean := true
);
Port (
inst_in : in inst_t;
iphase_in : in iphase_t;
status_in : in cpu_status_t;
ctrl_out : out dpath_ctrl_out_t;
idout : out inst_addr_t;
ddout : out dmem_data_t
);
end dpath_ctrl;
architecture Behavioral of dpath_ctrl is
signal opcode : opcode_t;
signal ctrl_lines : ctrl_lines_t;
signal dbg_iname : instr_name_t;
begin
idout <= inst_in(IMEM_ADDR_WIDTH-1 downto 0);
ddout <= inst_in(REG_SIZE_BITS+DMEM_DATA_WIDTH-1 downto REG_SIZE_BITS);
opcode <= inst_in(IMEM_DATA_WIDTH-1 downto IMEM_DATA_WIDTH-INST_OPCODE_WIDTH);
ctrl_out.reg_a_ptr <= inst_in(reg_ptr_t'length-1 downto 0);
ctrl_out.reg_b_ptr <= inst_in(2*(reg_ptr_t'length)-1 downto reg_ptr_t'length);
ctrl_out.lines <= ctrl_lines;
-- pragma translate_off
dbg_iname <= instr_name_array(to_integer(opcode));
-- pragma translate_on
gen_ctrl_rom:
if use_rom = true generate
i_dec:
process(opcode, iphase_in, status_in)
constant rom_data : murom_t := gen_murom;
variable addr : unsigned(MUCODE_ADDR_WIDTH-1 downto 0);
begin
addr := get_muromaddr(opcode, iphase_in, status_in);
ctrl_lines <= rom_data(to_integer(addr));
end process;
end generate;
gen_ctrl:
if use_rom = false generate
i_dec:
process (opcode, iphase_in, status_in)
begin
ctrl_lines <= idecoder(opcode, iphase_in, status_in);
end process;
end generate;
end Behavioral;
+138
View File
@@ -0,0 +1,138 @@
--------------------------------------------------------------------------
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
-- This file: Interrupt controller
--
-- Copyright (C) 2007 J. Ahrensfeld
--
-- 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/>.
--
-- For questions and ideas, please contact the author at jens@jayfield.org
--
--------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
use work.cpu_pkg.all;
entity int_ctrl is
Port (
rst : in STD_LOGIC;
clk : in STD_LOGIC;
ctrl_in : in int_ctrl_in_t;
int_in : in STD_LOGIC;
int_exit : in STD_LOGIC;
iphase_in : in iphase_t;
pc_addr_out : out inst_addr_t;
int_ack_out : out STD_LOGIC;
stat_save_out : out STD_LOGIC;
stat_rest_out : out STD_LOGIC;
pc_load_out : out STD_LOGIC;
stk_push_out : out STD_LOGIC;
stk_pop_out : out STD_LOGIC
);
end int_ctrl;
architecture Behavioral of int_ctrl is
type int_state_t is (int_idle, int_inject, int_active, int_release);
signal int_state, int_state_next : int_state_t;
signal pc_load, int_ack, stk_push, stk_pop : STD_LOGIC;
signal int_request : std_logic;
begin
int_ack_out <= int_ack;
pc_load_out <= pc_load;
stk_push_out <= stk_push;
stk_pop_out <= stk_pop;
-----------------------------------------------------------------------
irg_ctrl_fsm:
process (int_state, iphase_in, int_request, int_exit)
begin
pc_addr_out <= to_unsigned(1, inst_addr_t'length);
int_state_next <= int_state;
int_ack <= '0';
pc_load <= '0';
stk_push <= '0';
stk_pop <= '0';
case int_state is
when int_idle =>
if int_request = '1' and iphase_in = 1 then
int_state_next <= int_inject;
end if;
when int_inject =>
if iphase_in = 0 then
int_ack <= '1';
pc_load <= '1';
elsif iphase_in = 1 then
stk_push <= '1';
int_state_next <= int_active;
end if;
when int_active =>
if int_exit = '1' and iphase_in = 1 then
int_state_next <= int_release;
end if;
when int_release =>
if iphase_in = 0 then
stk_pop <= '1';
pc_load <= '1';
elsif iphase_in = 1 then
int_state_next <= int_idle;
end if;
when others =>
int_state_next <= int_idle;
end case;
end process;
irq_ctrl_states:
process (rst, clk, int_state_next)
begin
if rst = '1' then
int_state <= int_idle;
elsif rising_edge(clk) then
int_state <= int_state_next;
end if;
end process;
-----------------------------------------------------------------------
pin_sample:
process (clk)
begin
if rising_edge(clk) then
int_request <= '0';
if ctrl_in.enable = '1' then
int_request <= int_in;
end if;
end if;
end process;
-----------------------------------------------------------------------
stat_save_restore:
process (clk, stk_push, stk_pop)
begin
if rising_edge(clk) then
stat_save_out <= stk_push;
stat_rest_out <= stk_pop;
end if;
end process;
end Behavioral;
+70
View File
@@ -0,0 +1,70 @@
--------------------------------------------------------------------------
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
-- This file: Programm counter
--
-- Copyright (C) 2007 J. Ahrensfeld
--
-- 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/>.
--
-- For questions and ideas, please contact the author at jens@jayfield.org
--
--------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
use work.cpu_pkg.all;
entity pc is
Port (
rst : in STD_LOGIC;
clk : in STD_LOGIC;
inc : in STD_LOGIC;
load : in STD_LOGIC;
pc_in : in inst_addr_t;
pc_out : out inst_addr_t;
pc_next : out inst_addr_t
);
end pc;
architecture Behavioral of pc is
begin
proc_pc:
process(rst, clk, inc, load, pc_in)
variable vpc, vpc_reg: inst_addr_t;
begin
if rst = '1' then
vpc_reg := (others => '0');
elsif rising_edge(clk) then
if inc = '1' or load = '1' then
vpc_reg := vpc;
elsif inc = '0' then
pc_next <= vpc;
end if;
end if;
if load = '1' then
vpc := pc_in;
else
vpc := vpc_reg + 1;
end if;
pc_out <= vpc_reg;
end process;
end Behavioral;
+81
View File
@@ -0,0 +1,81 @@
--------------------------------------------------------------------------
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
-- This file: On-Chip work registers
--
-- Copyright (C) 2007 J. Ahrensfeld
--
-- 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/>.
--
-- For questions and ideas, please contact the author at jens@jayfield.org
--
--------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
use work.cpu_pkg.all;
entity reg_dual is
Generic (
addr_width : integer := 3;
data_width : integer := 8
);
Port (
clk : in STD_LOGIC;
we_a : in STD_LOGIC;
ptr_a : in reg_ptr_t;
ptr_b : in reg_ptr_t;
din_a : in unsigned (data_width-1 downto 0);
dout_a : out unsigned (data_width-1 downto 0);
dout_b : out unsigned (data_width-1 downto 0)
);
end reg_dual;
architecture Behavioral of reg_dual is
constant depth : integer := 2**addr_width;
type mem_t is array (0 to depth-1) of unsigned (data_width-1 downto 0);
signal addr_a, addr_b : unsigned (addr_width-1 downto 0) := (others => '0');
signal mem : mem_t;
begin
addr_a <= TO_01(ptr_a(addr_width-1 downto 0));
addr_b <= TO_01(ptr_b(addr_width-1 downto 0));
reg_in_ab:
process(clk)
begin
if rising_edge(clk) then
if we_a = '1' then
mem(to_integer(addr_a)) <= din_a;
end if;
end if;
end process;
reg_out_a:
process(mem, addr_a)
begin
dout_a <= TO_01(mem(to_integer(addr_a)));
end process;
reg_out_b:
process(mem, addr_b)
begin
dout_b <= TO_01(mem(to_integer(addr_b)));
end process;
end Behavioral;
+73
View File
@@ -0,0 +1,73 @@
--------------------------------------------------------------------------
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
-- This file: The call/return/data stack
--
-- Copyright (C) 2007 J. Ahrensfeld
--
-- 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/>.
--
-- For questions and ideas, please contact the author at jens@jayfield.org
--
--------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
use work.cpu_pkg.all;
entity stack_ctrl is
Generic (
addr_width : integer := 3
);
Port (
rst : in STD_LOGIC;
clk : in STD_LOGIC;
push : in STD_LOGIC;
pop : in STD_LOGIC;
ptr_out : out unsigned (addr_width-1 downto 0);
din : in inst_addr_t;
dout : out inst_addr_t;
mem_we : out STD_LOGIC
);
end stack_ctrl;
architecture Behavioral of stack_ctrl is
signal ptr : unsigned (addr_width-1 downto 0);
begin
ptr_out <= ptr;
stk_ptr:
process(rst, clk, ptr, push, pop)
begin
if rst = '1' then
ptr <= (others => '0');
dout <= (others => '0');
mem_we <= '0';
elsif rising_edge(clk) then
mem_we <= push;
if push = '1' then
ptr <= ptr + 1;
dout <= din;
elsif pop = '1' then
ptr <= ptr - 1;
end if;
end if;
end process;
end Behavioral;
+106
View File
@@ -0,0 +1,106 @@
-------------------------------------------------------------------------
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
-- This file: cpu_embedded using cpu_core and rom
--
-- Copyright (C) 2007 J. Ahrensfeld
--
-- 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/>.
--
-- For questions and ideas, please contact the author at jens@jayfield.org
--
--------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
use work.cpu_pkg.all;
entity cpu_embedded is
Port (
rst : in STD_LOGIC;
clk : in STD_LOGIC;
ce : in STD_LOGIC;
int_in : in STD_LOGIC;
int_ack : out STD_LOGIC;
xmem_we : out STD_LOGIC;
xmem_re : out STD_LOGIC;
xmem_din : in unsigned (DMEM_DATA_WIDTH-1 downto 0);
xmem_dout : out unsigned (DMEM_DATA_WIDTH-1 downto 0);
xmem_addr : out unsigned (DMEM_ADDR_WIDTH-1 downto 0);
io_sel : out STD_LOGIC
);
end cpu_embedded;
architecture rtl of cpu_embedded is
signal irom_data : unsigned (IMEM_DATA_WIDTH-1 downto 0);
signal irom_addr : unsigned (IMEM_ADDR_WIDTH-1 downto 0);
COMPONENT cpu
Port (
rst : in STD_LOGIC;
clk : in STD_LOGIC;
ce : in STD_LOGIC;
int_in : in STD_LOGIC;
int_ack : out STD_LOGIC;
xmem_we : out STD_LOGIC;
xmem_re : out STD_LOGIC;
instr_din : in unsigned (IMEM_DATA_WIDTH-1 downto 0);
instr_addr : out unsigned (IMEM_ADDR_WIDTH-1 downto 0);
xmem_din : in unsigned (DMEM_DATA_WIDTH-1 downto 0);
xmem_dout : out unsigned (DMEM_DATA_WIDTH-1 downto 0);
xmem_addr : out unsigned (DMEM_DATA_WIDTH-1 downto 0);
io_sel : out STD_LOGIC
);
END COMPONENT;
COMPONENT irom
Port (
clk : in STD_LOGIC;
ce : in STD_LOGIC;
addr : in inst_addr_t;
dout : out inst_t
);
END COMPONENT;
begin
inst_cpu: cpu
PORT MAP(
rst => rst,
clk => clk,
ce => ce,
int_in => int_in,
int_ack => int_ack,
xmem_we => xmem_we,
xmem_re => xmem_re,
instr_din => irom_data,
instr_addr => irom_addr,
xmem_din => xmem_din,
xmem_dout => xmem_dout,
xmem_addr => xmem_addr,
io_sel => io_sel
);
inst_irom: irom
PORT MAP(
clk => clk,
ce => ce,
addr => irom_addr,
dout => irom_data
);
end rtl;
+79
View File
@@ -0,0 +1,79 @@
-------------------------------------------------------------------------
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
-- This file: The ROM file for use in your VHDL design
--
-- Copyright (C) 2007 J. Ahrensfeld
--
-- 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/>.
--
-- For questions and ideas, please contact the author at jens@jayfield.org
--
--------------------------------------------------------------------------
LIBRARY ieee;
use IEEE.STD_LOGIC_1164.ALL;
USE ieee.numeric_std.ALL;
library work;
use work.cpu_pkg.all;
-- JASM_ROM_INSERT_HERE
ENTITY irom IS
Port (
clk : in STD_LOGIC;
ce : in STD_LOGIC;
addr : in inst_addr_t;
dout : out inst_t
);
END irom;
ARCHITECTURE dctest OF irom IS
type imem_rom_t is array (0 to 17) of inst_t;
-- Assembled from dctest.jsm
constant imem_rom : imem_rom_t :=
(
"110000" & X"010", -- 0x000: JMP 0x010
"110000" & X"011", -- 0x001: JMP 0x011
"000000" & X"000", -- 0x002:
"000000" & X"000", -- 0x003:
"000000" & X"000", -- 0x004:
"000000" & X"000", -- 0x005:
"000000" & X"000", -- 0x006:
"000000" & X"000", -- 0x007:
"000000" & X"000", -- 0x008:
"000000" & X"000", -- 0x009:
"000000" & X"000", -- 0x00A:
"000000" & X"000", -- 0x00B:
"000000" & X"000", -- 0x00C:
"000000" & X"000", -- 0x00D:
"000000" & X"000", -- 0x00E:
"000000" & X"000", -- 0x00F:
"110000" & X"010", -- 0x010: JMP 0x010
"111111" & X"000" -- 0x011: RETI
);
begin
PROM_READ:
process(clk, ce)
begin
if rising_edge(clk) and ce = '1' then
dout <= imem_rom(to_integer(addr));
end if;
end process;
end dctest;
File diff suppressed because it is too large Load Diff
+317
View File
@@ -0,0 +1,317 @@
-------------------------------------------------------------------------
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
-- This file: The ROM file for use in your VHDL design
--
-- Copyright (C) 2007 J. Ahrensfeld
--
-- 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/>.
--
-- For questions and ideas, please contact the author at jens@jayfield.org
--
--------------------------------------------------------------------------
LIBRARY ieee;
use IEEE.STD_LOGIC_1164.ALL;
USE ieee.numeric_std.ALL;
library work;
use work.cpu_pkg.all;
-- JASM_ROM_INSERT_HERE
ENTITY xrom IS
Port (
clk : in STD_LOGIC;
ce : in STD_LOGIC;
addr : in dmem_addr_t;
dout : out dmem_data_t
);
END xrom;
ARCHITECTURE dctest OF xrom IS
type xmem_rom_t is array (0 to 255) of dmem_data_t;
-- Assembled from dctest.jsm
constant xmem_rom : xmem_rom_t :=
(
X"00", -- 0x00
X"00", -- 0x01
X"00", -- 0x02
X"00", -- 0x03
X"01", -- 0x04
X"12", -- 0x05
X"41", -- 0x06
X"00", -- 0x07
X"00", -- 0x08
X"00", -- 0x09
X"00", -- 0x0A
X"00", -- 0x0B
X"00", -- 0x0C
X"00", -- 0x0D
X"00", -- 0x0E
X"00", -- 0x0F
X"00", -- 0x10
X"00", -- 0x11
X"00", -- 0x12
X"00", -- 0x13
X"00", -- 0x14
X"00", -- 0x15
X"00", -- 0x16
X"48", -- 0x17
X"61", -- 0x18
X"6C", -- 0x19
X"6C", -- 0x1A
X"6F", -- 0x1B
X"0D", -- 0x1C
X"0A", -- 0x1D
X"00", -- 0x1E
X"4A", -- 0x1F
X"65", -- 0x20
X"6E", -- 0x21
X"73", -- 0x22
X"00", -- 0x23
X"57", -- 0x24
X"65", -- 0x25
X"6C", -- 0x26
X"63", -- 0x27
X"6F", -- 0x28
X"6D", -- 0x29
X"65", -- 0x2A
X"20", -- 0x2B
X"74", -- 0x2C
X"6F", -- 0x2D
X"20", -- 0x2E
X"4A", -- 0x2F
X"41", -- 0x30
X"53", -- 0x31
X"4D", -- 0x32
X"20", -- 0x33
X"43", -- 0x34
X"50", -- 0x35
X"55", -- 0x36
X"00", -- 0x37
X"52", -- 0x38
X"65", -- 0x39
X"61", -- 0x3A
X"64", -- 0x3B
X"79", -- 0x3C
X"00", -- 0x3D
X"54", -- 0x3E
X"65", -- 0x3F
X"73", -- 0x40
X"74", -- 0x41
X"69", -- 0x42
X"6E", -- 0x43
X"67", -- 0x44
X"00", -- 0x45
X"50", -- 0x46
X"61", -- 0x47
X"73", -- 0x48
X"73", -- 0x49
X"65", -- 0x4A
X"64", -- 0x4B
X"00", -- 0x4C
X"45", -- 0x4D
X"72", -- 0x4E
X"72", -- 0x4F
X"6F", -- 0x50
X"72", -- 0x51
X"00", -- 0x52
X"0D", -- 0x53
X"0A", -- 0x54
X"00", -- 0x55
X"00", -- 0x56
X"00", -- 0x57
X"00", -- 0x58
X"00", -- 0x59
X"00", -- 0x5A
X"00", -- 0x5B
X"00", -- 0x5C
X"00", -- 0x5D
X"00", -- 0x5E
X"00", -- 0x5F
X"00", -- 0x60
X"00", -- 0x61
X"00", -- 0x62
X"00", -- 0x63
X"00", -- 0x64
X"00", -- 0x65
X"00", -- 0x66
X"00", -- 0x67
X"00", -- 0x68
X"00", -- 0x69
X"00", -- 0x6A
X"00", -- 0x6B
X"00", -- 0x6C
X"00", -- 0x6D
X"00", -- 0x6E
X"00", -- 0x6F
X"00", -- 0x70
X"00", -- 0x71
X"00", -- 0x72
X"00", -- 0x73
X"00", -- 0x74
X"00", -- 0x75
X"00", -- 0x76
X"00", -- 0x77
X"00", -- 0x78
X"00", -- 0x79
X"00", -- 0x7A
X"00", -- 0x7B
X"00", -- 0x7C
X"00", -- 0x7D
X"00", -- 0x7E
X"00", -- 0x7F
X"00", -- 0x80
X"00", -- 0x81
X"00", -- 0x82
X"00", -- 0x83
X"00", -- 0x84
X"00", -- 0x85
X"00", -- 0x86
X"00", -- 0x87
X"00", -- 0x88
X"00", -- 0x89
X"00", -- 0x8A
X"00", -- 0x8B
X"00", -- 0x8C
X"00", -- 0x8D
X"00", -- 0x8E
X"00", -- 0x8F
X"00", -- 0x90
X"00", -- 0x91
X"00", -- 0x92
X"00", -- 0x93
X"00", -- 0x94
X"00", -- 0x95
X"00", -- 0x96
X"00", -- 0x97
X"00", -- 0x98
X"00", -- 0x99
X"00", -- 0x9A
X"00", -- 0x9B
X"00", -- 0x9C
X"00", -- 0x9D
X"00", -- 0x9E
X"00", -- 0x9F
X"00", -- 0xA0
X"00", -- 0xA1
X"00", -- 0xA2
X"00", -- 0xA3
X"00", -- 0xA4
X"00", -- 0xA5
X"00", -- 0xA6
X"00", -- 0xA7
X"00", -- 0xA8
X"00", -- 0xA9
X"00", -- 0xAA
X"00", -- 0xAB
X"00", -- 0xAC
X"00", -- 0xAD
X"00", -- 0xAE
X"00", -- 0xAF
X"00", -- 0xB0
X"00", -- 0xB1
X"00", -- 0xB2
X"00", -- 0xB3
X"00", -- 0xB4
X"00", -- 0xB5
X"00", -- 0xB6
X"00", -- 0xB7
X"00", -- 0xB8
X"00", -- 0xB9
X"00", -- 0xBA
X"00", -- 0xBB
X"00", -- 0xBC
X"00", -- 0xBD
X"00", -- 0xBE
X"00", -- 0xBF
X"00", -- 0xC0
X"00", -- 0xC1
X"00", -- 0xC2
X"00", -- 0xC3
X"00", -- 0xC4
X"00", -- 0xC5
X"00", -- 0xC6
X"00", -- 0xC7
X"00", -- 0xC8
X"00", -- 0xC9
X"00", -- 0xCA
X"00", -- 0xCB
X"00", -- 0xCC
X"00", -- 0xCD
X"00", -- 0xCE
X"00", -- 0xCF
X"00", -- 0xD0
X"00", -- 0xD1
X"00", -- 0xD2
X"00", -- 0xD3
X"00", -- 0xD4
X"00", -- 0xD5
X"00", -- 0xD6
X"00", -- 0xD7
X"00", -- 0xD8
X"00", -- 0xD9
X"00", -- 0xDA
X"00", -- 0xDB
X"00", -- 0xDC
X"00", -- 0xDD
X"00", -- 0xDE
X"00", -- 0xDF
X"00", -- 0xE0
X"00", -- 0xE1
X"00", -- 0xE2
X"00", -- 0xE3
X"00", -- 0xE4
X"00", -- 0xE5
X"00", -- 0xE6
X"00", -- 0xE7
X"00", -- 0xE8
X"00", -- 0xE9
X"00", -- 0xEA
X"00", -- 0xEB
X"00", -- 0xEC
X"00", -- 0xED
X"00", -- 0xEE
X"00", -- 0xEF
X"00", -- 0xF0
X"00", -- 0xF1
X"00", -- 0xF2
X"00", -- 0xF3
X"00", -- 0xF4
X"00", -- 0xF5
X"00", -- 0xF6
X"00", -- 0xF7
X"00", -- 0xF8
X"00", -- 0xF9
X"00", -- 0xFA
X"00", -- 0xFB
X"00", -- 0xFC
X"00", -- 0xFD
X"00", -- 0xFE
X"00" -- 0xFF
);
begin
PROM_READ:
process(clk, ce)
begin
if rising_edge(clk) and ce = '1' then
dout <= xmem_rom(to_integer(addr));
end if;
end process;
end dctest;
+413
View File
@@ -0,0 +1,413 @@
-------------------------------------------------------------------------
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
-- This file: loadable ROM
--
-- Copyright (C) 2007 J. Ahrensfeld
--
-- 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/>.
--
-- For questions and ideas, please contact the author at jens@jayfield.org
--
--------------------------------------------------------------------------
LIBRARY ieee;
use IEEE.STD_LOGIC_1164.ALL;
USE ieee.numeric_std.ALL;
library UNISIM;
use UNISIM.VComponents.all;
library work;
use work.cpu_pkg.all;
ENTITY xrom IS
Port (
clk : in STD_LOGIC;
ce : in STD_LOGIC;
addr : in dmem_addr_t;
dout : out dmem_data_t
);
END xrom;
ARCHITECTURE loadable OF xrom IS
-- JASM_ROM_INSERT_HERE
-- Assembled from dctest.jsm
type xmem_rom_t is array (0 to 255) of dmem_data_t;
signal xmem_rom : xmem_rom_t :=
(
X"00", -- 0x00
X"00", -- 0x01
X"00", -- 0x02
X"00", -- 0x03
X"01", -- 0x04
X"12", -- 0x05
X"41", -- 0x06
X"00", -- 0x07
X"00", -- 0x08
X"00", -- 0x09
X"00", -- 0x0A
X"00", -- 0x0B
X"00", -- 0x0C
X"00", -- 0x0D
X"00", -- 0x0E
X"00", -- 0x0F
X"00", -- 0x10
X"00", -- 0x11
X"00", -- 0x12
X"00", -- 0x13
X"00", -- 0x14
X"00", -- 0x15
X"00", -- 0x16
X"48", -- 0x17
X"61", -- 0x18
X"6C", -- 0x19
X"6C", -- 0x1A
X"6F", -- 0x1B
X"0D", -- 0x1C
X"0A", -- 0x1D
X"00", -- 0x1E
X"4A", -- 0x1F
X"65", -- 0x20
X"6E", -- 0x21
X"73", -- 0x22
X"00", -- 0x23
X"57", -- 0x24
X"65", -- 0x25
X"6C", -- 0x26
X"63", -- 0x27
X"6F", -- 0x28
X"6D", -- 0x29
X"65", -- 0x2A
X"20", -- 0x2B
X"74", -- 0x2C
X"6F", -- 0x2D
X"20", -- 0x2E
X"4A", -- 0x2F
X"41", -- 0x30
X"53", -- 0x31
X"4D", -- 0x32
X"20", -- 0x33
X"43", -- 0x34
X"50", -- 0x35
X"55", -- 0x36
X"00", -- 0x37
X"52", -- 0x38
X"65", -- 0x39
X"61", -- 0x3A
X"64", -- 0x3B
X"79", -- 0x3C
X"00", -- 0x3D
X"54", -- 0x3E
X"65", -- 0x3F
X"73", -- 0x40
X"74", -- 0x41
X"69", -- 0x42
X"6E", -- 0x43
X"67", -- 0x44
X"00", -- 0x45
X"50", -- 0x46
X"61", -- 0x47
X"73", -- 0x48
X"73", -- 0x49
X"65", -- 0x4A
X"64", -- 0x4B
X"00", -- 0x4C
X"45", -- 0x4D
X"72", -- 0x4E
X"72", -- 0x4F
X"6F", -- 0x50
X"72", -- 0x51
X"00", -- 0x52
X"0D", -- 0x53
X"0A", -- 0x54
X"00", -- 0x55
X"00", -- 0x56
X"00", -- 0x57
X"00", -- 0x58
X"00", -- 0x59
X"00", -- 0x5A
X"00", -- 0x5B
X"00", -- 0x5C
X"00", -- 0x5D
X"00", -- 0x5E
X"00", -- 0x5F
X"00", -- 0x60
X"00", -- 0x61
X"00", -- 0x62
X"00", -- 0x63
X"00", -- 0x64
X"00", -- 0x65
X"00", -- 0x66
X"00", -- 0x67
X"00", -- 0x68
X"00", -- 0x69
X"00", -- 0x6A
X"00", -- 0x6B
X"00", -- 0x6C
X"00", -- 0x6D
X"00", -- 0x6E
X"00", -- 0x6F
X"00", -- 0x70
X"00", -- 0x71
X"00", -- 0x72
X"00", -- 0x73
X"00", -- 0x74
X"00", -- 0x75
X"00", -- 0x76
X"00", -- 0x77
X"00", -- 0x78
X"00", -- 0x79
X"00", -- 0x7A
X"00", -- 0x7B
X"00", -- 0x7C
X"00", -- 0x7D
X"00", -- 0x7E
X"00", -- 0x7F
X"00", -- 0x80
X"00", -- 0x81
X"00", -- 0x82
X"00", -- 0x83
X"00", -- 0x84
X"00", -- 0x85
X"00", -- 0x86
X"00", -- 0x87
X"00", -- 0x88
X"00", -- 0x89
X"00", -- 0x8A
X"00", -- 0x8B
X"00", -- 0x8C
X"00", -- 0x8D
X"00", -- 0x8E
X"00", -- 0x8F
X"00", -- 0x90
X"00", -- 0x91
X"00", -- 0x92
X"00", -- 0x93
X"00", -- 0x94
X"00", -- 0x95
X"00", -- 0x96
X"00", -- 0x97
X"00", -- 0x98
X"00", -- 0x99
X"00", -- 0x9A
X"00", -- 0x9B
X"00", -- 0x9C
X"00", -- 0x9D
X"00", -- 0x9E
X"00", -- 0x9F
X"00", -- 0xA0
X"00", -- 0xA1
X"00", -- 0xA2
X"00", -- 0xA3
X"00", -- 0xA4
X"00", -- 0xA5
X"00", -- 0xA6
X"00", -- 0xA7
X"00", -- 0xA8
X"00", -- 0xA9
X"00", -- 0xAA
X"00", -- 0xAB
X"00", -- 0xAC
X"00", -- 0xAD
X"00", -- 0xAE
X"00", -- 0xAF
X"00", -- 0xB0
X"00", -- 0xB1
X"00", -- 0xB2
X"00", -- 0xB3
X"00", -- 0xB4
X"00", -- 0xB5
X"00", -- 0xB6
X"00", -- 0xB7
X"00", -- 0xB8
X"00", -- 0xB9
X"00", -- 0xBA
X"00", -- 0xBB
X"00", -- 0xBC
X"00", -- 0xBD
X"00", -- 0xBE
X"00", -- 0xBF
X"00", -- 0xC0
X"00", -- 0xC1
X"00", -- 0xC2
X"00", -- 0xC3
X"00", -- 0xC4
X"00", -- 0xC5
X"00", -- 0xC6
X"00", -- 0xC7
X"00", -- 0xC8
X"00", -- 0xC9
X"00", -- 0xCA
X"00", -- 0xCB
X"00", -- 0xCC
X"00", -- 0xCD
X"00", -- 0xCE
X"00", -- 0xCF
X"00", -- 0xD0
X"00", -- 0xD1
X"00", -- 0xD2
X"00", -- 0xD3
X"00", -- 0xD4
X"00", -- 0xD5
X"00", -- 0xD6
X"00", -- 0xD7
X"00", -- 0xD8
X"00", -- 0xD9
X"00", -- 0xDA
X"00", -- 0xDB
X"00", -- 0xDC
X"00", -- 0xDD
X"00", -- 0xDE
X"00", -- 0xDF
X"00", -- 0xE0
X"00", -- 0xE1
X"00", -- 0xE2
X"00", -- 0xE3
X"00", -- 0xE4
X"00", -- 0xE5
X"00", -- 0xE6
X"00", -- 0xE7
X"00", -- 0xE8
X"00", -- 0xE9
X"00", -- 0xEA
X"00", -- 0xEB
X"00", -- 0xEC
X"00", -- 0xED
X"00", -- 0xEE
X"00", -- 0xEF
X"00", -- 0xF0
X"00", -- 0xF1
X"00", -- 0xF2
X"00", -- 0xF3
X"00", -- 0xF4
X"00", -- 0xF5
X"00", -- 0xF6
X"00", -- 0xF7
X"00", -- 0xF8
X"00", -- 0xF9
X"00", -- 0xFA
X"00", -- 0xFB
X"00", -- 0xFC
X"00", -- 0xFD
X"00", -- 0xFE
X"00" -- 0xFF
);
signal jtag_ld_clk : STD_LOGIC;
signal jtag_ld_we : STD_LOGIC;
signal jtag_ld_addr : dmem_addr_t;
signal jtag_ld_dout : dmem_data_t;
signal jtag_ld_din : dmem_data_t;
signal bs_rst, bs_sel, bs_shift, bs_tdi, bs_tdo : std_logic;
signal bs_capture, bs_clk0, bs_clk1, bs_update0, bs_update1 : std_logic;
signal user_regi, user_rego : unsigned (15 downto 0);
constant id : unsigned (15 downto 0) := X"BEEF";
begin
--------------------------------------------------------------------------
-- Virtex-4: JTAG Loader
--------------------------------------------------------------------------
i00_BUFG : BUFG
port map
(
O => bs_clk1,
I => bs_clk0
);
i01_BUFG : BUFG
port map
(
O => bs_update1,
I => bs_update0
);
BSCAN_VIRTEX4_inst2 : BSCAN_VIRTEX4
generic map
(
JTAG_CHAIN => 2 -- Value to set BSCAN site of device. Possible values: (1,2,3 or 4)
)
port map
(
CAPTURE => bs_capture, -- CAPTURE output from TAP controller
DRCK => bs_clk0, -- Data register output for USER functions
RESET => bs_rst, -- Reset output from TAP controller
SEL => bs_sel, -- USER active output
SHIFT => bs_shift, -- SHIFT output from TAP controller
TDI => bs_tdi, -- TDI output from TAP controller
UPDATE => bs_update0, -- UPDATE output from TAP controller
TDO => bs_tdo -- Data input for USER function
);
jtag_ld_addr <= user_regi(user_regi'left downto user_regi'left-dmem_data_t'length+1);
jtag_ld_din <= user_regi(dmem_data_t'left downto 0);
jtag_ld_clk <= bs_update1;
jtag_ld_we <= bs_sel;
sipo:
process (bs_rst, bs_clk1, bs_tdi, bs_shift)
begin
if bs_rst = '1' then
user_regi <= (others => '0');
elsif rising_edge(bs_clk1) then
if bs_shift = '1' then
user_regi <= bs_tdi & user_regi(user_regi'left downto 1);
end if;
end if;
end process;
piso:
process (bs_rst, bs_clk1, bs_shift, user_rego)
begin
bs_tdo <= user_rego(0);
if bs_rst = '1' then
user_rego <= (others => '0');
elsif rising_edge(bs_clk1) then
if bs_shift = '1' then
user_rego <= user_rego(0) & user_rego(user_rego'left downto 1);
else
user_rego <= (user_rego'left downto dmem_data_t'length => '0') & jtag_ld_dout;
-- user_rego <= id;
end if;
end if;
end process;
--------------------------------------------------------------------------
-- ROM Read/Write
--------------------------------------------------------------------------
PROM_READ:
process(clk, ce)
begin
if rising_edge(clk) and ce = '1' then
dout <= xmem_rom(to_integer(addr));
end if;
end process;
PROM_WRITE:
process(jtag_ld_clk, jtag_ld_we)
begin
if rising_edge(jtag_ld_clk) then
if jtag_ld_we = '1' then
xmem_rom(to_integer(jtag_ld_addr)) <= jtag_ld_din;
else
jtag_ld_dout <= xmem_rom(to_integer(jtag_ld_addr));
end if;
end if;
end process;
--------------------------------------------------------------------------
end loadable;
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+317
View File
@@ -0,0 +1,317 @@
-------------------------------------------------------------------------
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
-- This file: The ROM file for use in your VHDL design
--
-- Copyright (C) 2007 J. Ahrensfeld
--
-- 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/>.
--
-- For questions and ideas, please contact the author at jens@jayfield.org
--
--------------------------------------------------------------------------
LIBRARY ieee;
use IEEE.STD_LOGIC_1164.ALL;
USE ieee.numeric_std.ALL;
library work;
use work.cpu_pkg.all;
-- JASM_ROM_INSERT_HERE
ENTITY xrom IS
Port (
clk : in STD_LOGIC;
ce : in STD_LOGIC;
addr : in dmem_addr_t;
dout : out dmem_data_t
);
END xrom;
ARCHITECTURE itest OF xrom IS
type xmem_rom_t is array (0 to 255) of dmem_data_t;
-- Assembled from itest.jsm
constant xmem_rom : xmem_rom_t :=
(
X"48", -- 0x00
X"61", -- 0x01
X"6C", -- 0x02
X"6C", -- 0x03
X"6F", -- 0x04
X"00", -- 0x05
X"00", -- 0x06
X"00", -- 0x07
X"00", -- 0x08
X"00", -- 0x09
X"00", -- 0x0A
X"00", -- 0x0B
X"00", -- 0x0C
X"00", -- 0x0D
X"00", -- 0x0E
X"00", -- 0x0F
X"00", -- 0x10
X"00", -- 0x11
X"00", -- 0x12
X"00", -- 0x13
X"00", -- 0x14
X"00", -- 0x15
X"00", -- 0x16
X"00", -- 0x17
X"00", -- 0x18
X"00", -- 0x19
X"00", -- 0x1A
X"00", -- 0x1B
X"00", -- 0x1C
X"00", -- 0x1D
X"00", -- 0x1E
X"00", -- 0x1F
X"00", -- 0x20
X"00", -- 0x21
X"00", -- 0x22
X"00", -- 0x23
X"00", -- 0x24
X"00", -- 0x25
X"00", -- 0x26
X"00", -- 0x27
X"00", -- 0x28
X"00", -- 0x29
X"00", -- 0x2A
X"00", -- 0x2B
X"00", -- 0x2C
X"00", -- 0x2D
X"00", -- 0x2E
X"00", -- 0x2F
X"00", -- 0x30
X"00", -- 0x31
X"00", -- 0x32
X"00", -- 0x33
X"00", -- 0x34
X"00", -- 0x35
X"00", -- 0x36
X"00", -- 0x37
X"00", -- 0x38
X"00", -- 0x39
X"00", -- 0x3A
X"00", -- 0x3B
X"00", -- 0x3C
X"00", -- 0x3D
X"00", -- 0x3E
X"00", -- 0x3F
X"00", -- 0x40
X"00", -- 0x41
X"00", -- 0x42
X"00", -- 0x43
X"00", -- 0x44
X"00", -- 0x45
X"00", -- 0x46
X"00", -- 0x47
X"00", -- 0x48
X"00", -- 0x49
X"00", -- 0x4A
X"00", -- 0x4B
X"00", -- 0x4C
X"00", -- 0x4D
X"00", -- 0x4E
X"00", -- 0x4F
X"00", -- 0x50
X"00", -- 0x51
X"00", -- 0x52
X"00", -- 0x53
X"00", -- 0x54
X"00", -- 0x55
X"00", -- 0x56
X"00", -- 0x57
X"00", -- 0x58
X"00", -- 0x59
X"00", -- 0x5A
X"00", -- 0x5B
X"00", -- 0x5C
X"00", -- 0x5D
X"00", -- 0x5E
X"00", -- 0x5F
X"00", -- 0x60
X"00", -- 0x61
X"00", -- 0x62
X"00", -- 0x63
X"00", -- 0x64
X"00", -- 0x65
X"00", -- 0x66
X"00", -- 0x67
X"00", -- 0x68
X"00", -- 0x69
X"00", -- 0x6A
X"00", -- 0x6B
X"00", -- 0x6C
X"00", -- 0x6D
X"00", -- 0x6E
X"00", -- 0x6F
X"00", -- 0x70
X"00", -- 0x71
X"00", -- 0x72
X"00", -- 0x73
X"00", -- 0x74
X"00", -- 0x75
X"00", -- 0x76
X"00", -- 0x77
X"00", -- 0x78
X"00", -- 0x79
X"00", -- 0x7A
X"00", -- 0x7B
X"00", -- 0x7C
X"00", -- 0x7D
X"00", -- 0x7E
X"00", -- 0x7F
X"00", -- 0x80
X"00", -- 0x81
X"00", -- 0x82
X"00", -- 0x83
X"00", -- 0x84
X"00", -- 0x85
X"00", -- 0x86
X"00", -- 0x87
X"00", -- 0x88
X"00", -- 0x89
X"00", -- 0x8A
X"00", -- 0x8B
X"00", -- 0x8C
X"00", -- 0x8D
X"00", -- 0x8E
X"00", -- 0x8F
X"00", -- 0x90
X"00", -- 0x91
X"00", -- 0x92
X"00", -- 0x93
X"00", -- 0x94
X"00", -- 0x95
X"00", -- 0x96
X"00", -- 0x97
X"00", -- 0x98
X"00", -- 0x99
X"00", -- 0x9A
X"00", -- 0x9B
X"00", -- 0x9C
X"00", -- 0x9D
X"00", -- 0x9E
X"00", -- 0x9F
X"00", -- 0xA0
X"00", -- 0xA1
X"00", -- 0xA2
X"00", -- 0xA3
X"00", -- 0xA4
X"00", -- 0xA5
X"00", -- 0xA6
X"00", -- 0xA7
X"00", -- 0xA8
X"00", -- 0xA9
X"00", -- 0xAA
X"00", -- 0xAB
X"00", -- 0xAC
X"00", -- 0xAD
X"00", -- 0xAE
X"00", -- 0xAF
X"00", -- 0xB0
X"00", -- 0xB1
X"00", -- 0xB2
X"00", -- 0xB3
X"00", -- 0xB4
X"00", -- 0xB5
X"00", -- 0xB6
X"00", -- 0xB7
X"00", -- 0xB8
X"00", -- 0xB9
X"00", -- 0xBA
X"00", -- 0xBB
X"00", -- 0xBC
X"00", -- 0xBD
X"00", -- 0xBE
X"00", -- 0xBF
X"00", -- 0xC0
X"00", -- 0xC1
X"00", -- 0xC2
X"00", -- 0xC3
X"00", -- 0xC4
X"00", -- 0xC5
X"00", -- 0xC6
X"00", -- 0xC7
X"00", -- 0xC8
X"00", -- 0xC9
X"00", -- 0xCA
X"00", -- 0xCB
X"00", -- 0xCC
X"00", -- 0xCD
X"00", -- 0xCE
X"00", -- 0xCF
X"00", -- 0xD0
X"00", -- 0xD1
X"00", -- 0xD2
X"00", -- 0xD3
X"00", -- 0xD4
X"00", -- 0xD5
X"00", -- 0xD6
X"00", -- 0xD7
X"00", -- 0xD8
X"00", -- 0xD9
X"00", -- 0xDA
X"00", -- 0xDB
X"00", -- 0xDC
X"00", -- 0xDD
X"00", -- 0xDE
X"00", -- 0xDF
X"00", -- 0xE0
X"00", -- 0xE1
X"00", -- 0xE2
X"00", -- 0xE3
X"00", -- 0xE4
X"00", -- 0xE5
X"00", -- 0xE6
X"00", -- 0xE7
X"00", -- 0xE8
X"00", -- 0xE9
X"00", -- 0xEA
X"00", -- 0xEB
X"00", -- 0xEC
X"00", -- 0xED
X"00", -- 0xEE
X"00", -- 0xEF
X"00", -- 0xF0
X"00", -- 0xF1
X"00", -- 0xF2
X"00", -- 0xF3
X"00", -- 0xF4
X"00", -- 0xF5
X"00", -- 0xF6
X"00", -- 0xF7
X"00", -- 0xF8
X"00", -- 0xF9
X"00", -- 0xFA
X"00", -- 0xFB
X"00", -- 0xFC
X"00", -- 0xFD
X"00", -- 0xFE
X"00" -- 0xFF
);
begin
PROM_READ:
process(clk, ce)
begin
if rising_edge(clk) and ce = '1' then
dout <= xmem_rom(to_integer(addr));
end if;
end process;
end itest;
+413
View File
@@ -0,0 +1,413 @@
-------------------------------------------------------------------------
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
-- This file: loadable ROM
--
-- Copyright (C) 2007 J. Ahrensfeld
--
-- 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/>.
--
-- For questions and ideas, please contact the author at jens@jayfield.org
--
--------------------------------------------------------------------------
LIBRARY ieee;
use IEEE.STD_LOGIC_1164.ALL;
USE ieee.numeric_std.ALL;
library UNISIM;
use UNISIM.VComponents.all;
library work;
use work.cpu_pkg.all;
ENTITY xrom IS
Port (
clk : in STD_LOGIC;
ce : in STD_LOGIC;
addr : in dmem_addr_t;
dout : out dmem_data_t
);
END xrom;
ARCHITECTURE loadable OF xrom IS
-- JASM_ROM_INSERT_HERE
-- Assembled from itest.jsm
type xmem_rom_t is array (0 to 255) of dmem_data_t;
signal xmem_rom : xmem_rom_t :=
(
X"48", -- 0x00
X"61", -- 0x01
X"6C", -- 0x02
X"6C", -- 0x03
X"6F", -- 0x04
X"00", -- 0x05
X"00", -- 0x06
X"00", -- 0x07
X"00", -- 0x08
X"00", -- 0x09
X"00", -- 0x0A
X"00", -- 0x0B
X"00", -- 0x0C
X"00", -- 0x0D
X"00", -- 0x0E
X"00", -- 0x0F
X"00", -- 0x10
X"00", -- 0x11
X"00", -- 0x12
X"00", -- 0x13
X"00", -- 0x14
X"00", -- 0x15
X"00", -- 0x16
X"00", -- 0x17
X"00", -- 0x18
X"00", -- 0x19
X"00", -- 0x1A
X"00", -- 0x1B
X"00", -- 0x1C
X"00", -- 0x1D
X"00", -- 0x1E
X"00", -- 0x1F
X"00", -- 0x20
X"00", -- 0x21
X"00", -- 0x22
X"00", -- 0x23
X"00", -- 0x24
X"00", -- 0x25
X"00", -- 0x26
X"00", -- 0x27
X"00", -- 0x28
X"00", -- 0x29
X"00", -- 0x2A
X"00", -- 0x2B
X"00", -- 0x2C
X"00", -- 0x2D
X"00", -- 0x2E
X"00", -- 0x2F
X"00", -- 0x30
X"00", -- 0x31
X"00", -- 0x32
X"00", -- 0x33
X"00", -- 0x34
X"00", -- 0x35
X"00", -- 0x36
X"00", -- 0x37
X"00", -- 0x38
X"00", -- 0x39
X"00", -- 0x3A
X"00", -- 0x3B
X"00", -- 0x3C
X"00", -- 0x3D
X"00", -- 0x3E
X"00", -- 0x3F
X"00", -- 0x40
X"00", -- 0x41
X"00", -- 0x42
X"00", -- 0x43
X"00", -- 0x44
X"00", -- 0x45
X"00", -- 0x46
X"00", -- 0x47
X"00", -- 0x48
X"00", -- 0x49
X"00", -- 0x4A
X"00", -- 0x4B
X"00", -- 0x4C
X"00", -- 0x4D
X"00", -- 0x4E
X"00", -- 0x4F
X"00", -- 0x50
X"00", -- 0x51
X"00", -- 0x52
X"00", -- 0x53
X"00", -- 0x54
X"00", -- 0x55
X"00", -- 0x56
X"00", -- 0x57
X"00", -- 0x58
X"00", -- 0x59
X"00", -- 0x5A
X"00", -- 0x5B
X"00", -- 0x5C
X"00", -- 0x5D
X"00", -- 0x5E
X"00", -- 0x5F
X"00", -- 0x60
X"00", -- 0x61
X"00", -- 0x62
X"00", -- 0x63
X"00", -- 0x64
X"00", -- 0x65
X"00", -- 0x66
X"00", -- 0x67
X"00", -- 0x68
X"00", -- 0x69
X"00", -- 0x6A
X"00", -- 0x6B
X"00", -- 0x6C
X"00", -- 0x6D
X"00", -- 0x6E
X"00", -- 0x6F
X"00", -- 0x70
X"00", -- 0x71
X"00", -- 0x72
X"00", -- 0x73
X"00", -- 0x74
X"00", -- 0x75
X"00", -- 0x76
X"00", -- 0x77
X"00", -- 0x78
X"00", -- 0x79
X"00", -- 0x7A
X"00", -- 0x7B
X"00", -- 0x7C
X"00", -- 0x7D
X"00", -- 0x7E
X"00", -- 0x7F
X"00", -- 0x80
X"00", -- 0x81
X"00", -- 0x82
X"00", -- 0x83
X"00", -- 0x84
X"00", -- 0x85
X"00", -- 0x86
X"00", -- 0x87
X"00", -- 0x88
X"00", -- 0x89
X"00", -- 0x8A
X"00", -- 0x8B
X"00", -- 0x8C
X"00", -- 0x8D
X"00", -- 0x8E
X"00", -- 0x8F
X"00", -- 0x90
X"00", -- 0x91
X"00", -- 0x92
X"00", -- 0x93
X"00", -- 0x94
X"00", -- 0x95
X"00", -- 0x96
X"00", -- 0x97
X"00", -- 0x98
X"00", -- 0x99
X"00", -- 0x9A
X"00", -- 0x9B
X"00", -- 0x9C
X"00", -- 0x9D
X"00", -- 0x9E
X"00", -- 0x9F
X"00", -- 0xA0
X"00", -- 0xA1
X"00", -- 0xA2
X"00", -- 0xA3
X"00", -- 0xA4
X"00", -- 0xA5
X"00", -- 0xA6
X"00", -- 0xA7
X"00", -- 0xA8
X"00", -- 0xA9
X"00", -- 0xAA
X"00", -- 0xAB
X"00", -- 0xAC
X"00", -- 0xAD
X"00", -- 0xAE
X"00", -- 0xAF
X"00", -- 0xB0
X"00", -- 0xB1
X"00", -- 0xB2
X"00", -- 0xB3
X"00", -- 0xB4
X"00", -- 0xB5
X"00", -- 0xB6
X"00", -- 0xB7
X"00", -- 0xB8
X"00", -- 0xB9
X"00", -- 0xBA
X"00", -- 0xBB
X"00", -- 0xBC
X"00", -- 0xBD
X"00", -- 0xBE
X"00", -- 0xBF
X"00", -- 0xC0
X"00", -- 0xC1
X"00", -- 0xC2
X"00", -- 0xC3
X"00", -- 0xC4
X"00", -- 0xC5
X"00", -- 0xC6
X"00", -- 0xC7
X"00", -- 0xC8
X"00", -- 0xC9
X"00", -- 0xCA
X"00", -- 0xCB
X"00", -- 0xCC
X"00", -- 0xCD
X"00", -- 0xCE
X"00", -- 0xCF
X"00", -- 0xD0
X"00", -- 0xD1
X"00", -- 0xD2
X"00", -- 0xD3
X"00", -- 0xD4
X"00", -- 0xD5
X"00", -- 0xD6
X"00", -- 0xD7
X"00", -- 0xD8
X"00", -- 0xD9
X"00", -- 0xDA
X"00", -- 0xDB
X"00", -- 0xDC
X"00", -- 0xDD
X"00", -- 0xDE
X"00", -- 0xDF
X"00", -- 0xE0
X"00", -- 0xE1
X"00", -- 0xE2
X"00", -- 0xE3
X"00", -- 0xE4
X"00", -- 0xE5
X"00", -- 0xE6
X"00", -- 0xE7
X"00", -- 0xE8
X"00", -- 0xE9
X"00", -- 0xEA
X"00", -- 0xEB
X"00", -- 0xEC
X"00", -- 0xED
X"00", -- 0xEE
X"00", -- 0xEF
X"00", -- 0xF0
X"00", -- 0xF1
X"00", -- 0xF2
X"00", -- 0xF3
X"00", -- 0xF4
X"00", -- 0xF5
X"00", -- 0xF6
X"00", -- 0xF7
X"00", -- 0xF8
X"00", -- 0xF9
X"00", -- 0xFA
X"00", -- 0xFB
X"00", -- 0xFC
X"00", -- 0xFD
X"00", -- 0xFE
X"00" -- 0xFF
);
signal jtag_ld_clk : STD_LOGIC;
signal jtag_ld_we : STD_LOGIC;
signal jtag_ld_addr : dmem_addr_t;
signal jtag_ld_dout : dmem_data_t;
signal jtag_ld_din : dmem_data_t;
signal bs_rst, bs_sel, bs_shift, bs_tdi, bs_tdo : std_logic;
signal bs_capture, bs_clk0, bs_clk1, bs_update0, bs_update1 : std_logic;
signal user_regi, user_rego : unsigned (15 downto 0);
constant id : unsigned (15 downto 0) := X"BEEF";
begin
--------------------------------------------------------------------------
-- Virtex-4: JTAG Loader
--------------------------------------------------------------------------
i00_BUFG : BUFG
port map
(
O => bs_clk1,
I => bs_clk0
);
i01_BUFG : BUFG
port map
(
O => bs_update1,
I => bs_update0
);
BSCAN_VIRTEX4_inst2 : BSCAN_VIRTEX4
generic map
(
JTAG_CHAIN => 2 -- Value to set BSCAN site of device. Possible values: (1,2,3 or 4)
)
port map
(
CAPTURE => bs_capture, -- CAPTURE output from TAP controller
DRCK => bs_clk0, -- Data register output for USER functions
RESET => bs_rst, -- Reset output from TAP controller
SEL => bs_sel, -- USER active output
SHIFT => bs_shift, -- SHIFT output from TAP controller
TDI => bs_tdi, -- TDI output from TAP controller
UPDATE => bs_update0, -- UPDATE output from TAP controller
TDO => bs_tdo -- Data input for USER function
);
jtag_ld_addr <= user_regi(user_regi'left downto user_regi'left-dmem_data_t'length+1);
jtag_ld_din <= user_regi(dmem_data_t'left downto 0);
jtag_ld_clk <= bs_update1;
jtag_ld_we <= bs_sel;
sipo:
process (bs_rst, bs_clk1, bs_tdi, bs_shift)
begin
if bs_rst = '1' then
user_regi <= (others => '0');
elsif rising_edge(bs_clk1) then
if bs_shift = '1' then
user_regi <= bs_tdi & user_regi(user_regi'left downto 1);
end if;
end if;
end process;
piso:
process (bs_rst, bs_clk1, bs_shift, user_rego)
begin
bs_tdo <= user_rego(0);
if bs_rst = '1' then
user_rego <= (others => '0');
elsif rising_edge(bs_clk1) then
if bs_shift = '1' then
user_rego <= user_rego(0) & user_rego(user_rego'left downto 1);
else
user_rego <= (user_rego'left downto dmem_data_t'length => '0') & jtag_ld_dout;
-- user_rego <= id;
end if;
end if;
end process;
--------------------------------------------------------------------------
-- ROM Read/Write
--------------------------------------------------------------------------
PROM_READ:
process(clk, ce)
begin
if rising_edge(clk) and ce = '1' then
dout <= xmem_rom(to_integer(addr));
end if;
end process;
PROM_WRITE:
process(jtag_ld_clk, jtag_ld_we)
begin
if rising_edge(jtag_ld_clk) then
if jtag_ld_we = '1' then
xmem_rom(to_integer(jtag_ld_addr)) <= jtag_ld_din;
else
jtag_ld_dout <= xmem_rom(to_integer(jtag_ld_addr));
end if;
end if;
end process;
--------------------------------------------------------------------------
end loadable;
+88
View File
@@ -0,0 +1,88 @@
-------------------------------------------------------------------------
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
-- This file: The ROM file for use in your VHDL design
--
-- Copyright (C) 2007 J. Ahrensfeld
--
-- 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/>.
--
-- For questions and ideas, please contact the author at jens@jayfield.org
--
--------------------------------------------------------------------------
LIBRARY ieee;
use IEEE.STD_LOGIC_1164.ALL;
USE ieee.numeric_std.ALL;
library work;
use work.cpu_pkg.all;
-- JASM_ROM_INSERT_HERE
ENTITY irom IS
Port (
clk : in STD_LOGIC;
ce : in STD_LOGIC;
addr : in inst_addr_t;
dout : out inst_t
);
END irom;
ARCHITECTURE mul8x8 OF irom IS
type imem_rom_t is array (0 to 26) of inst_t;
-- Assembled from mul8x8.jsm
constant imem_rom : imem_rom_t :=
(
"110000" & X"001", -- 0x000: JMP 0x001
"000011" & X"450", -- 0x001: MOV R00, 0x45
"000011" & X"F51", -- 0x002: MOV R01, 0xF5
"111011" & X"005", -- 0x003: CALL 0x005
"110000" & X"004", -- 0x004: JMP 0x004
"111100" & X"002", -- 0x005: PUSH R02
"111100" & X"003", -- 0x006: PUSH R03
"111100" & X"004", -- 0x007: PUSH R04
"000010" & X"014", -- 0x008: MOV R04, R01
"000011" & X"001", -- 0x009: MOV R01, 0x00
"000011" & X"002", -- 0x00A: MOV R02, 0x00
"000011" & X"003", -- 0x00B: MOV R03, 0x00
"001111" & X"014", -- 0x00C: CMP R04, 0x01
"111001" & X"015", -- 0x00D: JEQ 0x015
"011111" & X"004", -- 0x00E: SHR R04
"110100" & X"012", -- 0x00F: JNC 0x012
"010000" & X"002", -- 0x010: ADD R02, R00
"010010" & X"013", -- 0x011: ADDC R03, R01
"011110" & X"000", -- 0x012: SHL R00
"100010" & X"001", -- 0x013: ROLC R01
"110000" & X"00C", -- 0x014: JMP 0x00C
"010000" & X"020", -- 0x015: ADD R00, R02
"010010" & X"031", -- 0x016: ADDC R01, R03
"111101" & X"004", -- 0x017: POP R04
"111101" & X"003", -- 0x018: POP R03
"111101" & X"002", -- 0x019: POP R02
"111110" & X"000" -- 0x01A: RET
);
begin
PROM_READ:
process(clk, ce)
begin
if rising_edge(clk) and ce = '1' then
dout <= imem_rom(to_integer(addr));
end if;
end process;
end mul8x8;
File diff suppressed because it is too large Load Diff
+317
View File
@@ -0,0 +1,317 @@
-------------------------------------------------------------------------
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
-- This file: The ROM file for use in your VHDL design
--
-- Copyright (C) 2007 J. Ahrensfeld
--
-- 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/>.
--
-- For questions and ideas, please contact the author at jens@jayfield.org
--
--------------------------------------------------------------------------
LIBRARY ieee;
use IEEE.STD_LOGIC_1164.ALL;
USE ieee.numeric_std.ALL;
library work;
use work.cpu_pkg.all;
-- JASM_ROM_INSERT_HERE
ENTITY xrom IS
Port (
clk : in STD_LOGIC;
ce : in STD_LOGIC;
addr : in dmem_addr_t;
dout : out dmem_data_t
);
END xrom;
ARCHITECTURE mul8x8 OF xrom IS
type xmem_rom_t is array (0 to 255) of dmem_data_t;
-- Assembled from mul8x8.jsm
constant xmem_rom : xmem_rom_t :=
(
X"00", -- 0x00
X"00", -- 0x01
X"00", -- 0x02
X"00", -- 0x03
X"00", -- 0x04
X"00", -- 0x05
X"00", -- 0x06
X"00", -- 0x07
X"00", -- 0x08
X"00", -- 0x09
X"00", -- 0x0A
X"00", -- 0x0B
X"00", -- 0x0C
X"00", -- 0x0D
X"00", -- 0x0E
X"00", -- 0x0F
X"00", -- 0x10
X"00", -- 0x11
X"00", -- 0x12
X"00", -- 0x13
X"00", -- 0x14
X"00", -- 0x15
X"00", -- 0x16
X"00", -- 0x17
X"00", -- 0x18
X"00", -- 0x19
X"00", -- 0x1A
X"00", -- 0x1B
X"00", -- 0x1C
X"00", -- 0x1D
X"00", -- 0x1E
X"00", -- 0x1F
X"00", -- 0x20
X"00", -- 0x21
X"00", -- 0x22
X"00", -- 0x23
X"00", -- 0x24
X"00", -- 0x25
X"00", -- 0x26
X"00", -- 0x27
X"00", -- 0x28
X"00", -- 0x29
X"00", -- 0x2A
X"00", -- 0x2B
X"00", -- 0x2C
X"00", -- 0x2D
X"00", -- 0x2E
X"00", -- 0x2F
X"00", -- 0x30
X"00", -- 0x31
X"00", -- 0x32
X"00", -- 0x33
X"00", -- 0x34
X"00", -- 0x35
X"00", -- 0x36
X"00", -- 0x37
X"00", -- 0x38
X"00", -- 0x39
X"00", -- 0x3A
X"00", -- 0x3B
X"00", -- 0x3C
X"00", -- 0x3D
X"00", -- 0x3E
X"00", -- 0x3F
X"00", -- 0x40
X"00", -- 0x41
X"00", -- 0x42
X"00", -- 0x43
X"00", -- 0x44
X"00", -- 0x45
X"00", -- 0x46
X"00", -- 0x47
X"00", -- 0x48
X"00", -- 0x49
X"00", -- 0x4A
X"00", -- 0x4B
X"00", -- 0x4C
X"00", -- 0x4D
X"00", -- 0x4E
X"00", -- 0x4F
X"00", -- 0x50
X"00", -- 0x51
X"00", -- 0x52
X"00", -- 0x53
X"00", -- 0x54
X"00", -- 0x55
X"00", -- 0x56
X"00", -- 0x57
X"00", -- 0x58
X"00", -- 0x59
X"00", -- 0x5A
X"00", -- 0x5B
X"00", -- 0x5C
X"00", -- 0x5D
X"00", -- 0x5E
X"00", -- 0x5F
X"00", -- 0x60
X"00", -- 0x61
X"00", -- 0x62
X"00", -- 0x63
X"00", -- 0x64
X"00", -- 0x65
X"00", -- 0x66
X"00", -- 0x67
X"00", -- 0x68
X"00", -- 0x69
X"00", -- 0x6A
X"00", -- 0x6B
X"00", -- 0x6C
X"00", -- 0x6D
X"00", -- 0x6E
X"00", -- 0x6F
X"00", -- 0x70
X"00", -- 0x71
X"00", -- 0x72
X"00", -- 0x73
X"00", -- 0x74
X"00", -- 0x75
X"00", -- 0x76
X"00", -- 0x77
X"00", -- 0x78
X"00", -- 0x79
X"00", -- 0x7A
X"00", -- 0x7B
X"00", -- 0x7C
X"00", -- 0x7D
X"00", -- 0x7E
X"00", -- 0x7F
X"00", -- 0x80
X"00", -- 0x81
X"00", -- 0x82
X"00", -- 0x83
X"00", -- 0x84
X"00", -- 0x85
X"00", -- 0x86
X"00", -- 0x87
X"00", -- 0x88
X"00", -- 0x89
X"00", -- 0x8A
X"00", -- 0x8B
X"00", -- 0x8C
X"00", -- 0x8D
X"00", -- 0x8E
X"00", -- 0x8F
X"00", -- 0x90
X"00", -- 0x91
X"00", -- 0x92
X"00", -- 0x93
X"00", -- 0x94
X"00", -- 0x95
X"00", -- 0x96
X"00", -- 0x97
X"00", -- 0x98
X"00", -- 0x99
X"00", -- 0x9A
X"00", -- 0x9B
X"00", -- 0x9C
X"00", -- 0x9D
X"00", -- 0x9E
X"00", -- 0x9F
X"00", -- 0xA0
X"00", -- 0xA1
X"00", -- 0xA2
X"00", -- 0xA3
X"00", -- 0xA4
X"00", -- 0xA5
X"00", -- 0xA6
X"00", -- 0xA7
X"00", -- 0xA8
X"00", -- 0xA9
X"00", -- 0xAA
X"00", -- 0xAB
X"00", -- 0xAC
X"00", -- 0xAD
X"00", -- 0xAE
X"00", -- 0xAF
X"00", -- 0xB0
X"00", -- 0xB1
X"00", -- 0xB2
X"00", -- 0xB3
X"00", -- 0xB4
X"00", -- 0xB5
X"00", -- 0xB6
X"00", -- 0xB7
X"00", -- 0xB8
X"00", -- 0xB9
X"00", -- 0xBA
X"00", -- 0xBB
X"00", -- 0xBC
X"00", -- 0xBD
X"00", -- 0xBE
X"00", -- 0xBF
X"00", -- 0xC0
X"00", -- 0xC1
X"00", -- 0xC2
X"00", -- 0xC3
X"00", -- 0xC4
X"00", -- 0xC5
X"00", -- 0xC6
X"00", -- 0xC7
X"00", -- 0xC8
X"00", -- 0xC9
X"00", -- 0xCA
X"00", -- 0xCB
X"00", -- 0xCC
X"00", -- 0xCD
X"00", -- 0xCE
X"00", -- 0xCF
X"00", -- 0xD0
X"00", -- 0xD1
X"00", -- 0xD2
X"00", -- 0xD3
X"00", -- 0xD4
X"00", -- 0xD5
X"00", -- 0xD6
X"00", -- 0xD7
X"00", -- 0xD8
X"00", -- 0xD9
X"00", -- 0xDA
X"00", -- 0xDB
X"00", -- 0xDC
X"00", -- 0xDD
X"00", -- 0xDE
X"00", -- 0xDF
X"00", -- 0xE0
X"00", -- 0xE1
X"00", -- 0xE2
X"00", -- 0xE3
X"00", -- 0xE4
X"00", -- 0xE5
X"00", -- 0xE6
X"00", -- 0xE7
X"00", -- 0xE8
X"00", -- 0xE9
X"00", -- 0xEA
X"00", -- 0xEB
X"00", -- 0xEC
X"00", -- 0xED
X"00", -- 0xEE
X"00", -- 0xEF
X"00", -- 0xF0
X"00", -- 0xF1
X"00", -- 0xF2
X"00", -- 0xF3
X"00", -- 0xF4
X"00", -- 0xF5
X"00", -- 0xF6
X"00", -- 0xF7
X"00", -- 0xF8
X"00", -- 0xF9
X"00", -- 0xFA
X"00", -- 0xFB
X"00", -- 0xFC
X"00", -- 0xFD
X"00", -- 0xFE
X"00" -- 0xFF
);
begin
PROM_READ:
process(clk, ce)
begin
if rising_edge(clk) and ce = '1' then
dout <= xmem_rom(to_integer(addr));
end if;
end process;
end mul8x8;
+413
View File
@@ -0,0 +1,413 @@
-------------------------------------------------------------------------
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
-- This file: loadable ROM
--
-- Copyright (C) 2007 J. Ahrensfeld
--
-- 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/>.
--
-- For questions and ideas, please contact the author at jens@jayfield.org
--
--------------------------------------------------------------------------
LIBRARY ieee;
use IEEE.STD_LOGIC_1164.ALL;
USE ieee.numeric_std.ALL;
library UNISIM;
use UNISIM.VComponents.all;
library work;
use work.cpu_pkg.all;
ENTITY xrom IS
Port (
clk : in STD_LOGIC;
ce : in STD_LOGIC;
addr : in dmem_addr_t;
dout : out dmem_data_t
);
END xrom;
ARCHITECTURE loadable OF xrom IS
-- JASM_ROM_INSERT_HERE
-- Assembled from mul8x8.jsm
type xmem_rom_t is array (0 to 255) of dmem_data_t;
signal xmem_rom : xmem_rom_t :=
(
X"00", -- 0x00
X"00", -- 0x01
X"00", -- 0x02
X"00", -- 0x03
X"00", -- 0x04
X"00", -- 0x05
X"00", -- 0x06
X"00", -- 0x07
X"00", -- 0x08
X"00", -- 0x09
X"00", -- 0x0A
X"00", -- 0x0B
X"00", -- 0x0C
X"00", -- 0x0D
X"00", -- 0x0E
X"00", -- 0x0F
X"00", -- 0x10
X"00", -- 0x11
X"00", -- 0x12
X"00", -- 0x13
X"00", -- 0x14
X"00", -- 0x15
X"00", -- 0x16
X"00", -- 0x17
X"00", -- 0x18
X"00", -- 0x19
X"00", -- 0x1A
X"00", -- 0x1B
X"00", -- 0x1C
X"00", -- 0x1D
X"00", -- 0x1E
X"00", -- 0x1F
X"00", -- 0x20
X"00", -- 0x21
X"00", -- 0x22
X"00", -- 0x23
X"00", -- 0x24
X"00", -- 0x25
X"00", -- 0x26
X"00", -- 0x27
X"00", -- 0x28
X"00", -- 0x29
X"00", -- 0x2A
X"00", -- 0x2B
X"00", -- 0x2C
X"00", -- 0x2D
X"00", -- 0x2E
X"00", -- 0x2F
X"00", -- 0x30
X"00", -- 0x31
X"00", -- 0x32
X"00", -- 0x33
X"00", -- 0x34
X"00", -- 0x35
X"00", -- 0x36
X"00", -- 0x37
X"00", -- 0x38
X"00", -- 0x39
X"00", -- 0x3A
X"00", -- 0x3B
X"00", -- 0x3C
X"00", -- 0x3D
X"00", -- 0x3E
X"00", -- 0x3F
X"00", -- 0x40
X"00", -- 0x41
X"00", -- 0x42
X"00", -- 0x43
X"00", -- 0x44
X"00", -- 0x45
X"00", -- 0x46
X"00", -- 0x47
X"00", -- 0x48
X"00", -- 0x49
X"00", -- 0x4A
X"00", -- 0x4B
X"00", -- 0x4C
X"00", -- 0x4D
X"00", -- 0x4E
X"00", -- 0x4F
X"00", -- 0x50
X"00", -- 0x51
X"00", -- 0x52
X"00", -- 0x53
X"00", -- 0x54
X"00", -- 0x55
X"00", -- 0x56
X"00", -- 0x57
X"00", -- 0x58
X"00", -- 0x59
X"00", -- 0x5A
X"00", -- 0x5B
X"00", -- 0x5C
X"00", -- 0x5D
X"00", -- 0x5E
X"00", -- 0x5F
X"00", -- 0x60
X"00", -- 0x61
X"00", -- 0x62
X"00", -- 0x63
X"00", -- 0x64
X"00", -- 0x65
X"00", -- 0x66
X"00", -- 0x67
X"00", -- 0x68
X"00", -- 0x69
X"00", -- 0x6A
X"00", -- 0x6B
X"00", -- 0x6C
X"00", -- 0x6D
X"00", -- 0x6E
X"00", -- 0x6F
X"00", -- 0x70
X"00", -- 0x71
X"00", -- 0x72
X"00", -- 0x73
X"00", -- 0x74
X"00", -- 0x75
X"00", -- 0x76
X"00", -- 0x77
X"00", -- 0x78
X"00", -- 0x79
X"00", -- 0x7A
X"00", -- 0x7B
X"00", -- 0x7C
X"00", -- 0x7D
X"00", -- 0x7E
X"00", -- 0x7F
X"00", -- 0x80
X"00", -- 0x81
X"00", -- 0x82
X"00", -- 0x83
X"00", -- 0x84
X"00", -- 0x85
X"00", -- 0x86
X"00", -- 0x87
X"00", -- 0x88
X"00", -- 0x89
X"00", -- 0x8A
X"00", -- 0x8B
X"00", -- 0x8C
X"00", -- 0x8D
X"00", -- 0x8E
X"00", -- 0x8F
X"00", -- 0x90
X"00", -- 0x91
X"00", -- 0x92
X"00", -- 0x93
X"00", -- 0x94
X"00", -- 0x95
X"00", -- 0x96
X"00", -- 0x97
X"00", -- 0x98
X"00", -- 0x99
X"00", -- 0x9A
X"00", -- 0x9B
X"00", -- 0x9C
X"00", -- 0x9D
X"00", -- 0x9E
X"00", -- 0x9F
X"00", -- 0xA0
X"00", -- 0xA1
X"00", -- 0xA2
X"00", -- 0xA3
X"00", -- 0xA4
X"00", -- 0xA5
X"00", -- 0xA6
X"00", -- 0xA7
X"00", -- 0xA8
X"00", -- 0xA9
X"00", -- 0xAA
X"00", -- 0xAB
X"00", -- 0xAC
X"00", -- 0xAD
X"00", -- 0xAE
X"00", -- 0xAF
X"00", -- 0xB0
X"00", -- 0xB1
X"00", -- 0xB2
X"00", -- 0xB3
X"00", -- 0xB4
X"00", -- 0xB5
X"00", -- 0xB6
X"00", -- 0xB7
X"00", -- 0xB8
X"00", -- 0xB9
X"00", -- 0xBA
X"00", -- 0xBB
X"00", -- 0xBC
X"00", -- 0xBD
X"00", -- 0xBE
X"00", -- 0xBF
X"00", -- 0xC0
X"00", -- 0xC1
X"00", -- 0xC2
X"00", -- 0xC3
X"00", -- 0xC4
X"00", -- 0xC5
X"00", -- 0xC6
X"00", -- 0xC7
X"00", -- 0xC8
X"00", -- 0xC9
X"00", -- 0xCA
X"00", -- 0xCB
X"00", -- 0xCC
X"00", -- 0xCD
X"00", -- 0xCE
X"00", -- 0xCF
X"00", -- 0xD0
X"00", -- 0xD1
X"00", -- 0xD2
X"00", -- 0xD3
X"00", -- 0xD4
X"00", -- 0xD5
X"00", -- 0xD6
X"00", -- 0xD7
X"00", -- 0xD8
X"00", -- 0xD9
X"00", -- 0xDA
X"00", -- 0xDB
X"00", -- 0xDC
X"00", -- 0xDD
X"00", -- 0xDE
X"00", -- 0xDF
X"00", -- 0xE0
X"00", -- 0xE1
X"00", -- 0xE2
X"00", -- 0xE3
X"00", -- 0xE4
X"00", -- 0xE5
X"00", -- 0xE6
X"00", -- 0xE7
X"00", -- 0xE8
X"00", -- 0xE9
X"00", -- 0xEA
X"00", -- 0xEB
X"00", -- 0xEC
X"00", -- 0xED
X"00", -- 0xEE
X"00", -- 0xEF
X"00", -- 0xF0
X"00", -- 0xF1
X"00", -- 0xF2
X"00", -- 0xF3
X"00", -- 0xF4
X"00", -- 0xF5
X"00", -- 0xF6
X"00", -- 0xF7
X"00", -- 0xF8
X"00", -- 0xF9
X"00", -- 0xFA
X"00", -- 0xFB
X"00", -- 0xFC
X"00", -- 0xFD
X"00", -- 0xFE
X"00" -- 0xFF
);
signal jtag_ld_clk : STD_LOGIC;
signal jtag_ld_we : STD_LOGIC;
signal jtag_ld_addr : dmem_addr_t;
signal jtag_ld_dout : dmem_data_t;
signal jtag_ld_din : dmem_data_t;
signal bs_rst, bs_sel, bs_shift, bs_tdi, bs_tdo : std_logic;
signal bs_capture, bs_clk0, bs_clk1, bs_update0, bs_update1 : std_logic;
signal user_regi, user_rego : unsigned (15 downto 0);
constant id : unsigned (15 downto 0) := X"BEEF";
begin
--------------------------------------------------------------------------
-- Virtex-4: JTAG Loader
--------------------------------------------------------------------------
i00_BUFG : BUFG
port map
(
O => bs_clk1,
I => bs_clk0
);
i01_BUFG : BUFG
port map
(
O => bs_update1,
I => bs_update0
);
BSCAN_VIRTEX4_inst2 : BSCAN_VIRTEX4
generic map
(
JTAG_CHAIN => 2 -- Value to set BSCAN site of device. Possible values: (1,2,3 or 4)
)
port map
(
CAPTURE => bs_capture, -- CAPTURE output from TAP controller
DRCK => bs_clk0, -- Data register output for USER functions
RESET => bs_rst, -- Reset output from TAP controller
SEL => bs_sel, -- USER active output
SHIFT => bs_shift, -- SHIFT output from TAP controller
TDI => bs_tdi, -- TDI output from TAP controller
UPDATE => bs_update0, -- UPDATE output from TAP controller
TDO => bs_tdo -- Data input for USER function
);
jtag_ld_addr <= user_regi(user_regi'left downto user_regi'left-dmem_data_t'length+1);
jtag_ld_din <= user_regi(dmem_data_t'left downto 0);
jtag_ld_clk <= bs_update1;
jtag_ld_we <= bs_sel;
sipo:
process (bs_rst, bs_clk1, bs_tdi, bs_shift)
begin
if bs_rst = '1' then
user_regi <= (others => '0');
elsif rising_edge(bs_clk1) then
if bs_shift = '1' then
user_regi <= bs_tdi & user_regi(user_regi'left downto 1);
end if;
end if;
end process;
piso:
process (bs_rst, bs_clk1, bs_shift, user_rego)
begin
bs_tdo <= user_rego(0);
if bs_rst = '1' then
user_rego <= (others => '0');
elsif rising_edge(bs_clk1) then
if bs_shift = '1' then
user_rego <= user_rego(0) & user_rego(user_rego'left downto 1);
else
user_rego <= (user_rego'left downto dmem_data_t'length => '0') & jtag_ld_dout;
-- user_rego <= id;
end if;
end if;
end process;
--------------------------------------------------------------------------
-- ROM Read/Write
--------------------------------------------------------------------------
PROM_READ:
process(clk, ce)
begin
if rising_edge(clk) and ce = '1' then
dout <= xmem_rom(to_integer(addr));
end if;
end process;
PROM_WRITE:
process(jtag_ld_clk, jtag_ld_we)
begin
if rising_edge(jtag_ld_clk) then
if jtag_ld_we = '1' then
xmem_rom(to_integer(jtag_ld_addr)) <= jtag_ld_din;
else
jtag_ld_dout <= xmem_rom(to_integer(jtag_ld_addr));
end if;
end if;
end process;
--------------------------------------------------------------------------
end loadable;
+89
View File
@@ -0,0 +1,89 @@
-------------------------------------------------------------------------
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
-- This file: The ROM file for use in your VHDL design
--
-- Copyright (C) 2007 J. Ahrensfeld
--
-- 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/>.
--
-- For questions and ideas, please contact the author at jens@jayfield.org
--
--------------------------------------------------------------------------
LIBRARY ieee;
use IEEE.STD_LOGIC_1164.ALL;
USE ieee.numeric_std.ALL;
library work;
use work.cpu_pkg.all;
-- JASM_ROM_INSERT_HERE
ENTITY irom IS
Port (
clk : in STD_LOGIC;
ce : in STD_LOGIC;
addr : in inst_addr_t;
dout : out inst_t
);
END irom;
ARCHITECTURE reti_issue OF irom IS
type imem_rom_t is array (0 to 27) of inst_t;
-- Assembled from reti_issue.jsm
constant imem_rom : imem_rom_t :=
(
"110000" & X"002", -- 0x000: JMP 0x002
"111111" & X"000", -- 0x001: RETI
"000011" & X"050", -- 0x002: MOV R00, 0x05
"100110" & X"030", -- 0x003: COUT (0x03), R00
"000011" & X"000", -- 0x004: MOV R00, 0x00
"000000" & X"000", -- 0x005: NOP
"010001" & X"010", -- 0x006: INC R00
"000000" & X"000", -- 0x007: NOP
"111011" & X"01B", -- 0x008: CALL 0x01B
"000000" & X"000", -- 0x009: NOP
"111100" & X"003", -- 0x00A: PUSH R03
"000000" & X"000", -- 0x00B: NOP
"111100" & X"002", -- 0x00C: PUSH R02
"000000" & X"000", -- 0x00D: NOP
"111100" & X"001", -- 0x00E: PUSH R01
"000000" & X"000", -- 0x00F: NOP
"111100" & X"000", -- 0x010: PUSH R00
"000000" & X"000", -- 0x011: NOP
"111101" & X"000", -- 0x012: POP R00
"000000" & X"000", -- 0x013: NOP
"111101" & X"001", -- 0x014: POP R01
"000000" & X"000", -- 0x015: NOP
"111101" & X"002", -- 0x016: POP R02
"000000" & X"000", -- 0x017: NOP
"111101" & X"003", -- 0x018: POP R03
"000000" & X"000", -- 0x019: NOP
"110000" & X"005", -- 0x01A: JMP 0x005
"111110" & X"000" -- 0x01B: RET
);
begin
PROM_READ:
process(clk, ce)
begin
if rising_edge(clk) and ce = '1' then
dout <= imem_rom(to_integer(addr));
end if;
end process;
end reti_issue;
File diff suppressed because it is too large Load Diff
+317
View File
@@ -0,0 +1,317 @@
-------------------------------------------------------------------------
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
-- This file: The ROM file for use in your VHDL design
--
-- Copyright (C) 2007 J. Ahrensfeld
--
-- 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/>.
--
-- For questions and ideas, please contact the author at jens@jayfield.org
--
--------------------------------------------------------------------------
LIBRARY ieee;
use IEEE.STD_LOGIC_1164.ALL;
USE ieee.numeric_std.ALL;
library work;
use work.cpu_pkg.all;
-- JASM_ROM_INSERT_HERE
ENTITY xrom IS
Port (
clk : in STD_LOGIC;
ce : in STD_LOGIC;
addr : in dmem_addr_t;
dout : out dmem_data_t
);
END xrom;
ARCHITECTURE reti_issue OF xrom IS
type xmem_rom_t is array (0 to 255) of dmem_data_t;
-- Assembled from reti_issue.jsm
constant xmem_rom : xmem_rom_t :=
(
X"00", -- 0x00
X"00", -- 0x01
X"00", -- 0x02
X"00", -- 0x03
X"00", -- 0x04
X"00", -- 0x05
X"00", -- 0x06
X"00", -- 0x07
X"00", -- 0x08
X"00", -- 0x09
X"00", -- 0x0A
X"00", -- 0x0B
X"00", -- 0x0C
X"00", -- 0x0D
X"00", -- 0x0E
X"00", -- 0x0F
X"00", -- 0x10
X"00", -- 0x11
X"00", -- 0x12
X"00", -- 0x13
X"00", -- 0x14
X"00", -- 0x15
X"00", -- 0x16
X"00", -- 0x17
X"00", -- 0x18
X"00", -- 0x19
X"00", -- 0x1A
X"00", -- 0x1B
X"00", -- 0x1C
X"00", -- 0x1D
X"00", -- 0x1E
X"00", -- 0x1F
X"00", -- 0x20
X"00", -- 0x21
X"00", -- 0x22
X"00", -- 0x23
X"00", -- 0x24
X"00", -- 0x25
X"00", -- 0x26
X"00", -- 0x27
X"00", -- 0x28
X"00", -- 0x29
X"00", -- 0x2A
X"00", -- 0x2B
X"00", -- 0x2C
X"00", -- 0x2D
X"00", -- 0x2E
X"00", -- 0x2F
X"00", -- 0x30
X"00", -- 0x31
X"00", -- 0x32
X"00", -- 0x33
X"00", -- 0x34
X"00", -- 0x35
X"00", -- 0x36
X"00", -- 0x37
X"00", -- 0x38
X"00", -- 0x39
X"00", -- 0x3A
X"00", -- 0x3B
X"00", -- 0x3C
X"00", -- 0x3D
X"00", -- 0x3E
X"00", -- 0x3F
X"00", -- 0x40
X"00", -- 0x41
X"00", -- 0x42
X"00", -- 0x43
X"00", -- 0x44
X"00", -- 0x45
X"00", -- 0x46
X"00", -- 0x47
X"00", -- 0x48
X"00", -- 0x49
X"00", -- 0x4A
X"00", -- 0x4B
X"00", -- 0x4C
X"00", -- 0x4D
X"00", -- 0x4E
X"00", -- 0x4F
X"00", -- 0x50
X"00", -- 0x51
X"00", -- 0x52
X"00", -- 0x53
X"00", -- 0x54
X"00", -- 0x55
X"00", -- 0x56
X"00", -- 0x57
X"00", -- 0x58
X"00", -- 0x59
X"00", -- 0x5A
X"00", -- 0x5B
X"00", -- 0x5C
X"00", -- 0x5D
X"00", -- 0x5E
X"00", -- 0x5F
X"00", -- 0x60
X"00", -- 0x61
X"00", -- 0x62
X"00", -- 0x63
X"00", -- 0x64
X"00", -- 0x65
X"00", -- 0x66
X"00", -- 0x67
X"00", -- 0x68
X"00", -- 0x69
X"00", -- 0x6A
X"00", -- 0x6B
X"00", -- 0x6C
X"00", -- 0x6D
X"00", -- 0x6E
X"00", -- 0x6F
X"00", -- 0x70
X"00", -- 0x71
X"00", -- 0x72
X"00", -- 0x73
X"00", -- 0x74
X"00", -- 0x75
X"00", -- 0x76
X"00", -- 0x77
X"00", -- 0x78
X"00", -- 0x79
X"00", -- 0x7A
X"00", -- 0x7B
X"00", -- 0x7C
X"00", -- 0x7D
X"00", -- 0x7E
X"00", -- 0x7F
X"00", -- 0x80
X"00", -- 0x81
X"00", -- 0x82
X"00", -- 0x83
X"00", -- 0x84
X"00", -- 0x85
X"00", -- 0x86
X"00", -- 0x87
X"00", -- 0x88
X"00", -- 0x89
X"00", -- 0x8A
X"00", -- 0x8B
X"00", -- 0x8C
X"00", -- 0x8D
X"00", -- 0x8E
X"00", -- 0x8F
X"00", -- 0x90
X"00", -- 0x91
X"00", -- 0x92
X"00", -- 0x93
X"00", -- 0x94
X"00", -- 0x95
X"00", -- 0x96
X"00", -- 0x97
X"00", -- 0x98
X"00", -- 0x99
X"00", -- 0x9A
X"00", -- 0x9B
X"00", -- 0x9C
X"00", -- 0x9D
X"00", -- 0x9E
X"00", -- 0x9F
X"00", -- 0xA0
X"00", -- 0xA1
X"00", -- 0xA2
X"00", -- 0xA3
X"00", -- 0xA4
X"00", -- 0xA5
X"00", -- 0xA6
X"00", -- 0xA7
X"00", -- 0xA8
X"00", -- 0xA9
X"00", -- 0xAA
X"00", -- 0xAB
X"00", -- 0xAC
X"00", -- 0xAD
X"00", -- 0xAE
X"00", -- 0xAF
X"00", -- 0xB0
X"00", -- 0xB1
X"00", -- 0xB2
X"00", -- 0xB3
X"00", -- 0xB4
X"00", -- 0xB5
X"00", -- 0xB6
X"00", -- 0xB7
X"00", -- 0xB8
X"00", -- 0xB9
X"00", -- 0xBA
X"00", -- 0xBB
X"00", -- 0xBC
X"00", -- 0xBD
X"00", -- 0xBE
X"00", -- 0xBF
X"00", -- 0xC0
X"00", -- 0xC1
X"00", -- 0xC2
X"00", -- 0xC3
X"00", -- 0xC4
X"00", -- 0xC5
X"00", -- 0xC6
X"00", -- 0xC7
X"00", -- 0xC8
X"00", -- 0xC9
X"00", -- 0xCA
X"00", -- 0xCB
X"00", -- 0xCC
X"00", -- 0xCD
X"00", -- 0xCE
X"00", -- 0xCF
X"00", -- 0xD0
X"00", -- 0xD1
X"00", -- 0xD2
X"00", -- 0xD3
X"00", -- 0xD4
X"00", -- 0xD5
X"00", -- 0xD6
X"00", -- 0xD7
X"00", -- 0xD8
X"00", -- 0xD9
X"00", -- 0xDA
X"00", -- 0xDB
X"00", -- 0xDC
X"00", -- 0xDD
X"00", -- 0xDE
X"00", -- 0xDF
X"00", -- 0xE0
X"00", -- 0xE1
X"00", -- 0xE2
X"00", -- 0xE3
X"00", -- 0xE4
X"00", -- 0xE5
X"00", -- 0xE6
X"00", -- 0xE7
X"00", -- 0xE8
X"00", -- 0xE9
X"00", -- 0xEA
X"00", -- 0xEB
X"00", -- 0xEC
X"00", -- 0xED
X"00", -- 0xEE
X"00", -- 0xEF
X"00", -- 0xF0
X"00", -- 0xF1
X"00", -- 0xF2
X"00", -- 0xF3
X"00", -- 0xF4
X"00", -- 0xF5
X"00", -- 0xF6
X"00", -- 0xF7
X"00", -- 0xF8
X"00", -- 0xF9
X"00", -- 0xFA
X"00", -- 0xFB
X"00", -- 0xFC
X"00", -- 0xFD
X"00", -- 0xFE
X"00" -- 0xFF
);
begin
PROM_READ:
process(clk, ce)
begin
if rising_edge(clk) and ce = '1' then
dout <= xmem_rom(to_integer(addr));
end if;
end process;
end reti_issue;
+413
View File
@@ -0,0 +1,413 @@
-------------------------------------------------------------------------
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
-- This file: loadable ROM
--
-- Copyright (C) 2007 J. Ahrensfeld
--
-- 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/>.
--
-- For questions and ideas, please contact the author at jens@jayfield.org
--
--------------------------------------------------------------------------
LIBRARY ieee;
use IEEE.STD_LOGIC_1164.ALL;
USE ieee.numeric_std.ALL;
library UNISIM;
use UNISIM.VComponents.all;
library work;
use work.cpu_pkg.all;
ENTITY xrom IS
Port (
clk : in STD_LOGIC;
ce : in STD_LOGIC;
addr : in dmem_addr_t;
dout : out dmem_data_t
);
END xrom;
ARCHITECTURE loadable OF xrom IS
-- JASM_ROM_INSERT_HERE
-- Assembled from reti_issue.jsm
type xmem_rom_t is array (0 to 255) of dmem_data_t;
signal xmem_rom : xmem_rom_t :=
(
X"00", -- 0x00
X"00", -- 0x01
X"00", -- 0x02
X"00", -- 0x03
X"00", -- 0x04
X"00", -- 0x05
X"00", -- 0x06
X"00", -- 0x07
X"00", -- 0x08
X"00", -- 0x09
X"00", -- 0x0A
X"00", -- 0x0B
X"00", -- 0x0C
X"00", -- 0x0D
X"00", -- 0x0E
X"00", -- 0x0F
X"00", -- 0x10
X"00", -- 0x11
X"00", -- 0x12
X"00", -- 0x13
X"00", -- 0x14
X"00", -- 0x15
X"00", -- 0x16
X"00", -- 0x17
X"00", -- 0x18
X"00", -- 0x19
X"00", -- 0x1A
X"00", -- 0x1B
X"00", -- 0x1C
X"00", -- 0x1D
X"00", -- 0x1E
X"00", -- 0x1F
X"00", -- 0x20
X"00", -- 0x21
X"00", -- 0x22
X"00", -- 0x23
X"00", -- 0x24
X"00", -- 0x25
X"00", -- 0x26
X"00", -- 0x27
X"00", -- 0x28
X"00", -- 0x29
X"00", -- 0x2A
X"00", -- 0x2B
X"00", -- 0x2C
X"00", -- 0x2D
X"00", -- 0x2E
X"00", -- 0x2F
X"00", -- 0x30
X"00", -- 0x31
X"00", -- 0x32
X"00", -- 0x33
X"00", -- 0x34
X"00", -- 0x35
X"00", -- 0x36
X"00", -- 0x37
X"00", -- 0x38
X"00", -- 0x39
X"00", -- 0x3A
X"00", -- 0x3B
X"00", -- 0x3C
X"00", -- 0x3D
X"00", -- 0x3E
X"00", -- 0x3F
X"00", -- 0x40
X"00", -- 0x41
X"00", -- 0x42
X"00", -- 0x43
X"00", -- 0x44
X"00", -- 0x45
X"00", -- 0x46
X"00", -- 0x47
X"00", -- 0x48
X"00", -- 0x49
X"00", -- 0x4A
X"00", -- 0x4B
X"00", -- 0x4C
X"00", -- 0x4D
X"00", -- 0x4E
X"00", -- 0x4F
X"00", -- 0x50
X"00", -- 0x51
X"00", -- 0x52
X"00", -- 0x53
X"00", -- 0x54
X"00", -- 0x55
X"00", -- 0x56
X"00", -- 0x57
X"00", -- 0x58
X"00", -- 0x59
X"00", -- 0x5A
X"00", -- 0x5B
X"00", -- 0x5C
X"00", -- 0x5D
X"00", -- 0x5E
X"00", -- 0x5F
X"00", -- 0x60
X"00", -- 0x61
X"00", -- 0x62
X"00", -- 0x63
X"00", -- 0x64
X"00", -- 0x65
X"00", -- 0x66
X"00", -- 0x67
X"00", -- 0x68
X"00", -- 0x69
X"00", -- 0x6A
X"00", -- 0x6B
X"00", -- 0x6C
X"00", -- 0x6D
X"00", -- 0x6E
X"00", -- 0x6F
X"00", -- 0x70
X"00", -- 0x71
X"00", -- 0x72
X"00", -- 0x73
X"00", -- 0x74
X"00", -- 0x75
X"00", -- 0x76
X"00", -- 0x77
X"00", -- 0x78
X"00", -- 0x79
X"00", -- 0x7A
X"00", -- 0x7B
X"00", -- 0x7C
X"00", -- 0x7D
X"00", -- 0x7E
X"00", -- 0x7F
X"00", -- 0x80
X"00", -- 0x81
X"00", -- 0x82
X"00", -- 0x83
X"00", -- 0x84
X"00", -- 0x85
X"00", -- 0x86
X"00", -- 0x87
X"00", -- 0x88
X"00", -- 0x89
X"00", -- 0x8A
X"00", -- 0x8B
X"00", -- 0x8C
X"00", -- 0x8D
X"00", -- 0x8E
X"00", -- 0x8F
X"00", -- 0x90
X"00", -- 0x91
X"00", -- 0x92
X"00", -- 0x93
X"00", -- 0x94
X"00", -- 0x95
X"00", -- 0x96
X"00", -- 0x97
X"00", -- 0x98
X"00", -- 0x99
X"00", -- 0x9A
X"00", -- 0x9B
X"00", -- 0x9C
X"00", -- 0x9D
X"00", -- 0x9E
X"00", -- 0x9F
X"00", -- 0xA0
X"00", -- 0xA1
X"00", -- 0xA2
X"00", -- 0xA3
X"00", -- 0xA4
X"00", -- 0xA5
X"00", -- 0xA6
X"00", -- 0xA7
X"00", -- 0xA8
X"00", -- 0xA9
X"00", -- 0xAA
X"00", -- 0xAB
X"00", -- 0xAC
X"00", -- 0xAD
X"00", -- 0xAE
X"00", -- 0xAF
X"00", -- 0xB0
X"00", -- 0xB1
X"00", -- 0xB2
X"00", -- 0xB3
X"00", -- 0xB4
X"00", -- 0xB5
X"00", -- 0xB6
X"00", -- 0xB7
X"00", -- 0xB8
X"00", -- 0xB9
X"00", -- 0xBA
X"00", -- 0xBB
X"00", -- 0xBC
X"00", -- 0xBD
X"00", -- 0xBE
X"00", -- 0xBF
X"00", -- 0xC0
X"00", -- 0xC1
X"00", -- 0xC2
X"00", -- 0xC3
X"00", -- 0xC4
X"00", -- 0xC5
X"00", -- 0xC6
X"00", -- 0xC7
X"00", -- 0xC8
X"00", -- 0xC9
X"00", -- 0xCA
X"00", -- 0xCB
X"00", -- 0xCC
X"00", -- 0xCD
X"00", -- 0xCE
X"00", -- 0xCF
X"00", -- 0xD0
X"00", -- 0xD1
X"00", -- 0xD2
X"00", -- 0xD3
X"00", -- 0xD4
X"00", -- 0xD5
X"00", -- 0xD6
X"00", -- 0xD7
X"00", -- 0xD8
X"00", -- 0xD9
X"00", -- 0xDA
X"00", -- 0xDB
X"00", -- 0xDC
X"00", -- 0xDD
X"00", -- 0xDE
X"00", -- 0xDF
X"00", -- 0xE0
X"00", -- 0xE1
X"00", -- 0xE2
X"00", -- 0xE3
X"00", -- 0xE4
X"00", -- 0xE5
X"00", -- 0xE6
X"00", -- 0xE7
X"00", -- 0xE8
X"00", -- 0xE9
X"00", -- 0xEA
X"00", -- 0xEB
X"00", -- 0xEC
X"00", -- 0xED
X"00", -- 0xEE
X"00", -- 0xEF
X"00", -- 0xF0
X"00", -- 0xF1
X"00", -- 0xF2
X"00", -- 0xF3
X"00", -- 0xF4
X"00", -- 0xF5
X"00", -- 0xF6
X"00", -- 0xF7
X"00", -- 0xF8
X"00", -- 0xF9
X"00", -- 0xFA
X"00", -- 0xFB
X"00", -- 0xFC
X"00", -- 0xFD
X"00", -- 0xFE
X"00" -- 0xFF
);
signal jtag_ld_clk : STD_LOGIC;
signal jtag_ld_we : STD_LOGIC;
signal jtag_ld_addr : dmem_addr_t;
signal jtag_ld_dout : dmem_data_t;
signal jtag_ld_din : dmem_data_t;
signal bs_rst, bs_sel, bs_shift, bs_tdi, bs_tdo : std_logic;
signal bs_capture, bs_clk0, bs_clk1, bs_update0, bs_update1 : std_logic;
signal user_regi, user_rego : unsigned (15 downto 0);
constant id : unsigned (15 downto 0) := X"BEEF";
begin
--------------------------------------------------------------------------
-- Virtex-4: JTAG Loader
--------------------------------------------------------------------------
i00_BUFG : BUFG
port map
(
O => bs_clk1,
I => bs_clk0
);
i01_BUFG : BUFG
port map
(
O => bs_update1,
I => bs_update0
);
BSCAN_VIRTEX4_inst2 : BSCAN_VIRTEX4
generic map
(
JTAG_CHAIN => 2 -- Value to set BSCAN site of device. Possible values: (1,2,3 or 4)
)
port map
(
CAPTURE => bs_capture, -- CAPTURE output from TAP controller
DRCK => bs_clk0, -- Data register output for USER functions
RESET => bs_rst, -- Reset output from TAP controller
SEL => bs_sel, -- USER active output
SHIFT => bs_shift, -- SHIFT output from TAP controller
TDI => bs_tdi, -- TDI output from TAP controller
UPDATE => bs_update0, -- UPDATE output from TAP controller
TDO => bs_tdo -- Data input for USER function
);
jtag_ld_addr <= user_regi(user_regi'left downto user_regi'left-dmem_data_t'length+1);
jtag_ld_din <= user_regi(dmem_data_t'left downto 0);
jtag_ld_clk <= bs_update1;
jtag_ld_we <= bs_sel;
sipo:
process (bs_rst, bs_clk1, bs_tdi, bs_shift)
begin
if bs_rst = '1' then
user_regi <= (others => '0');
elsif rising_edge(bs_clk1) then
if bs_shift = '1' then
user_regi <= bs_tdi & user_regi(user_regi'left downto 1);
end if;
end if;
end process;
piso:
process (bs_rst, bs_clk1, bs_shift, user_rego)
begin
bs_tdo <= user_rego(0);
if bs_rst = '1' then
user_rego <= (others => '0');
elsif rising_edge(bs_clk1) then
if bs_shift = '1' then
user_rego <= user_rego(0) & user_rego(user_rego'left downto 1);
else
user_rego <= (user_rego'left downto dmem_data_t'length => '0') & jtag_ld_dout;
-- user_rego <= id;
end if;
end if;
end process;
--------------------------------------------------------------------------
-- ROM Read/Write
--------------------------------------------------------------------------
PROM_READ:
process(clk, ce)
begin
if rising_edge(clk) and ce = '1' then
dout <= xmem_rom(to_integer(addr));
end if;
end process;
PROM_WRITE:
process(jtag_ld_clk, jtag_ld_we)
begin
if rising_edge(jtag_ld_clk) then
if jtag_ld_we = '1' then
xmem_rom(to_integer(jtag_ld_addr)) <= jtag_ld_din;
else
jtag_ld_dout <= xmem_rom(to_integer(jtag_ld_addr));
end if;
end if;
end process;
--------------------------------------------------------------------------
end loadable;
+126
View File
@@ -0,0 +1,126 @@
-------------------------------------------------------------------------
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
-- This file: testbench for embedded cpu with rom
--
-- Copyright (C) 2007 J. Ahrensfeld
--
-- 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/>.
--
-- For questions and ideas, please contact the author at jens@jayfield.org
--
--------------------------------------------------------------------------
LIBRARY ieee;
use IEEE.STD_LOGIC_1164.ALL;
USE ieee.numeric_std.ALL;
use std.textio.all; -- Imports the standard textio package.
library work;
use work.cpu_pkg.all;
ENTITY tb_cpu_embedded IS
END tb_cpu_embedded;
ARCHITECTURE behavior OF tb_cpu_embedded IS
COMPONENT cpu_embedded
Port (
rst : in STD_LOGIC;
clk : in STD_LOGIC;
ce : in STD_LOGIC;
int_in : in STD_LOGIC;
int_ack : out STD_LOGIC;
xmem_we : out STD_LOGIC;
xmem_re : out STD_LOGIC;
xmem_din : in unsigned (DMEM_DATA_WIDTH-1 downto 0);
xmem_dout : out unsigned (DMEM_DATA_WIDTH-1 downto 0);
xmem_addr : out unsigned (DMEM_ADDR_WIDTH-1 downto 0);
io_sel : out STD_LOGIC
);
END COMPONENT;
constant CLK_PERIOD : time := 10 ns;
type sram_t is array (integer range <>) of dmem_data_t;
signal rst : std_logic := '1';
signal clk : std_logic := '1';
signal ce : std_logic := '0';
signal int_in : std_logic := '0';
signal int_ack : std_logic;
signal xmem_din : dmem_data_t := (others => '-');
signal xmem_dout : dmem_data_t;
signal xmem_addr : dmem_addr_t;
signal xmem_we : std_logic;
signal xmem_re : std_logic;
signal io_sel : std_logic;
signal sram : sram_t(0 to 2**dmem_addr_t'length-1);
BEGIN
uut: cpu_embedded
PORT MAP(
rst => rst,
clk => clk,
ce => ce,
int_in => int_in,
int_ack => int_ack,
xmem_we => xmem_we,
xmem_re => xmem_re,
xmem_din => xmem_din,
xmem_dout => xmem_dout,
xmem_addr => xmem_addr,
io_sel => io_sel
);
CLK_GEN: process
begin
wait for CLK_PERIOD/2;
clk <= not clk;
end process;
STIMULUS: process
begin
wait for 3*CLK_PERIOD;
rst <= '0';
wait for 2*CLK_PERIOD;
wait until rising_edge(clk);
ce <= '1';
wait for 1000*CLK_PERIOD;
assert false report "Test finished" severity error;
wait;
end process;
SRAM_RW: process(rst, clk, xmem_addr, xmem_dout, xmem_we)
begin
if (rst = '1') then
xmem_din <= X"00";
elsif rising_edge(clk) then
if io_sel = '0' then
if xmem_we = '1' then
sram(to_integer(xmem_addr)) <= xmem_dout;
end if;
xmem_din <= to_01(sram(to_integer(xmem_addr)));
else
xmem_din <= X"FF";
end if;
end if;
end process;
END;
+200
View File
@@ -0,0 +1,200 @@
-------------------------------------------------------------------------
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
-- This file: Formal test of correct function of JCPU,
-- also writes 'opc.lst' for JASM-assembler
--
-- Copyright (C) 2007 J. Ahrensfeld
--
-- 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/>.
--
-- For questions and ideas, please contact the author at jens@jayfield.org
--
--------------------------------------------------------------------------
LIBRARY ieee;
use IEEE.STD_LOGIC_1164.ALL;
USE ieee.numeric_std.ALL;
use std.textio.all; -- Imports the standard textio package.
library work;
use work.cpu_pkg.all;
use work.PCK_FIO.all;
ENTITY tb_cpu IS
END tb_cpu;
ARCHITECTURE behavior OF tb_cpu IS
COMPONENT cpu
Generic (
use_instr_register : boolean;
use_ctrl_rom : boolean
);
Port (
rst : in STD_LOGIC;
clk : in STD_LOGIC;
ce : in STD_LOGIC;
int_in : in STD_LOGIC;
int_ack : out STD_LOGIC;
xmem_we : out STD_LOGIC;
xmem_re : out STD_LOGIC;
instr_din : in unsigned (IMEM_DATA_WIDTH-1 downto 0);
instr_addr : out unsigned (IMEM_ADDR_WIDTH-1 downto 0);
xmem_din : in unsigned (DMEM_DATA_WIDTH-1 downto 0);
xmem_dout : out unsigned (DMEM_DATA_WIDTH-1 downto 0);
xmem_addr : out unsigned (DMEM_DATA_WIDTH-1 downto 0);
io_sel : out STD_LOGIC
);
END COMPONENT;
COMPONENT irom
Port (
clk : in STD_LOGIC;
ce : in STD_LOGIC;
addr : in inst_addr_t;
dout : out inst_t
);
END COMPONENT;
constant CLK_PERIOD : time := 10 ns;
type prom_t is array (integer range <>) of inst_t;
type sram_t is array (integer range <>) of dmem_data_t;
signal rst : std_logic := '1';
signal clk : std_logic := '1';
signal ce : std_logic := '0';
signal int_in : std_logic := '0';
signal int_ack : std_logic;
signal irom_data : unsigned (IMEM_DATA_WIDTH-1 downto 0) := (others => '-');
signal irom_addr : unsigned (IMEM_ADDR_WIDTH-1 downto 0);
signal xmem_din : dmem_data_t := (others => '-');
signal xmem_dout : dmem_data_t;
signal xmem_addr : unsigned (DMEM_DATA_WIDTH-1 downto 0);
signal xmem_we : std_logic;
signal xmem_re : std_logic;
signal io_sel : std_logic;
signal sram : sram_t(0 to 2**DMEM_DATA_WIDTH-1);
type reg_t is record
revision : dmem_data_t;
testid : dmem_data_t;
interrupt : std_logic;
end record;
signal reg : reg_t;
BEGIN
int_in <= reg.interrupt;
uut: cpu
GENERIC MAP
(
use_instr_register => false,
use_ctrl_rom => true
)
PORT MAP(
rst => rst,
clk => clk,
ce => ce,
int_in => int_in,
int_ack => int_ack,
xmem_we => xmem_we,
xmem_re => xmem_re,
instr_din => irom_data,
instr_addr => irom_addr,
xmem_din => xmem_din,
xmem_dout => xmem_dout,
xmem_addr => xmem_addr,
io_sel => io_sel
);
the_irom: irom
PORT MAP(
clk => clk,
ce => ce,
addr => irom_addr,
dout => irom_data
);
CLK_GEN: process
begin
wait for CLK_PERIOD/2;
clk <= not clk;
end process;
STIMULUS: process
file RESULT: text open write_mode is "../tools/opc.list";
variable L: line;
begin
for i in 0 to instr_name_array'length-1 loop
fprint(RESULT, L,"%d %s\n", fo(i), instr_name_array(i));
end loop;
wait for 3*CLK_PERIOD;
rst <= '0';
wait for 2*CLK_PERIOD;
wait until rising_edge(clk);
ce <= '1';
assert false report "Test finished" severity error;
wait;
end process;
SRAM_RW: process(rst, clk)
begin
if (rst = '1') then
reg.revision <= (others => '0');
reg.testid <= (others => '0');
reg.interrupt <= '0';
elsif rising_edge(clk) then
if int_ack = '1' then
-- reg.interrupt <= '0';
end if;
if xmem_we = '1' then
if io_sel = '0' then
sram(to_integer(xmem_addr)) <= xmem_dout;
else
case xmem_addr is
when X"00" =>
reg.revision <= xmem_dout;
when X"01" =>
reg.testid <= xmem_dout;
when X"02" =>
reg.interrupt <= xmem_dout(0);
when others => null;
end case;
end if;
else
if io_sel = '0' then
xmem_din <= to_01(sram(to_integer(xmem_addr)));
else
case xmem_addr is
when X"00" =>
xmem_din <= reg.revision;
when X"01" =>
xmem_din <= reg.testid;
when others =>
xmem_din <= X"BC";
end case;
end if;
end if;
end if;
end process;
END;
+10
View File
@@ -0,0 +1,10 @@
vhdl work "W:\vhdl\lib\CPUs\JCpu\src\core\cpu_pkg.vhd"
vhdl work "W:\vhdl\lib\CPUs\JCpu\src\core\stack_ctrl.vhd"
vhdl work "W:\vhdl\lib\CPUs\JCpu\src\core\reg_dual.vhd"
vhdl work "W:\vhdl\lib\CPUs\JCpu\src\core\pc.vhd"
vhdl work "W:\vhdl\lib\CPUs\JCpu\src\core\int_ctrl.vhd"
vhdl work "W:\vhdl\lib\CPUs\JCpu\src\core\dpath_ctrl.vhd"
vhdl work "W:\vhdl\lib\CPUs\JCpu\src\core\chipreg.vhd"
vhdl work "W:\vhdl\lib\CPUs\JCpu\src\core\chipram.vhd"
vhdl work "W:\vhdl\lib\CPUs\JCpu\src\core\alu.vhd"
vhdl work "W:\vhdl\lib\CPUs\JCpu\src\core\cpu.vhd"
+42
View File
@@ -0,0 +1,42 @@
#!/usr/bin/env ruby
str1 = %Q!lbl: dc "Hallo", ", ", 0, 1, " der","Jens"!
i=0;
def get_stri_lit (str)
res = [""];
state = "out"
j = 0;
k = 0;
for i in (0..str.length-1)
c = str[i];
nstate = state
case state
when "out"
if c == "\""[0]
nstate = "in"
end
when "in"
if c == "\""[0]
nstate = "out"
if j > 0
k = k + 1;
res[k] = ""
end
else
res[k] = res[k] + format("%c", c);
j = j + 1;
end
end
state = nstate
end;
return res
end
get_stri_lit(str1).each do |word|
puts word
end
+46
View File
@@ -0,0 +1,46 @@
#!/usr/bin/env ruby
# ----------------------------------------------------------------------
# Project: JCPU, a portable 8-bit RISC CPU written in VHDL
# This file: Insertion of code fragments into templates
#
# Copyright (C) 2007 J. Ahrensfeld
#
# 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/>.
#
# For questions and ideas, please contact the author at jens@jayfield.org
#
# ---------------------------------------------------------------------
arg = $*
rom_filename = arg[0].to_s
tpl_filename = arg[1].to_s
subst_pattern = "JASM_ROM_INSERT_HERE"
# --------------------------------------------------------
# Open file
# --------------------------------------------------------
romfile = File.open(rom_filename, "r")
tplfile = File.open(tpl_filename, "r")
re = Regexp.new(subst_pattern)
while (line = tplfile.gets)
puts line
line.scan(re).each do |word|
romfile.each do |raw_line|
puts raw_line
end
end
end
+32
View File
@@ -0,0 +1,32 @@
-------------------------------------------------------------------------
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
-- This file: The ROM file for use in your VHDL design
--
-- Copyright (C) 2007 J. Ahrensfeld
--
-- 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/>.
--
-- For questions and ideas, please contact the author at jens@jayfield.org
--
--------------------------------------------------------------------------
LIBRARY ieee;
use IEEE.STD_LOGIC_1164.ALL;
USE ieee.numeric_std.ALL;
library work;
use work.cpu_pkg.all;
-- JASM_ROM_INSERT_HERE
+151
View File
@@ -0,0 +1,151 @@
-------------------------------------------------------------------------
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
-- This file: loadable ROM
--
-- Copyright (C) 2007 J. Ahrensfeld
--
-- 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/>.
--
-- For questions and ideas, please contact the author at jens@jayfield.org
--
--------------------------------------------------------------------------
LIBRARY ieee;
use IEEE.STD_LOGIC_1164.ALL;
USE ieee.numeric_std.ALL;
library UNISIM;
use UNISIM.VComponents.all;
library work;
use work.cpu_pkg.all;
ENTITY irom IS
Port (
clk : in STD_LOGIC;
ce : in STD_LOGIC;
addr : in inst_addr_t;
dout : out inst_t
);
END irom;
ARCHITECTURE loadable OF irom IS
-- JASM_ROM_INSERT_HERE
signal jtag_ld_clk : STD_LOGIC;
signal jtag_ld_we : STD_LOGIC;
signal jtag_ld_addr : inst_addr_t;
signal jtag_ld_dout : inst_t;
signal jtag_ld_din : inst_t;
signal bs_rst, bs_sel, bs_shift, bs_tdi, bs_tdo : std_logic;
signal bs_capture, bs_clk0, bs_clk1, bs_update0, bs_update1 : std_logic;
signal user_regi, user_rego : unsigned (31 downto 0);
constant id : unsigned (31 downto 0) := X"BABE" & X"BEEF";
begin
--------------------------------------------------------------------------
-- Virtex-4: JTAG Loader
--------------------------------------------------------------------------
i00_BUFG : BUFG
port map
(
O => bs_clk1,
I => bs_clk0
);
i01_BUFG : BUFG
port map
(
O => bs_update1,
I => bs_update0
);
BSCAN_VIRTEX4_inst1 : BSCAN_VIRTEX4
generic map
(
JTAG_CHAIN => 1 -- Value to set BSCAN site of device. Possible values: (1,2,3 or 4)
)
port map
(
CAPTURE => bs_capture, -- CAPTURE output from TAP controller
DRCK => bs_clk0, -- Data register output for USER functions
RESET => bs_rst, -- Reset output from TAP controller
SEL => bs_sel, -- USER active output
SHIFT => bs_shift, -- SHIFT output from TAP controller
TDI => bs_tdi, -- TDI output from TAP controller
UPDATE => bs_update0, -- UPDATE output from TAP controller
TDO => bs_tdo -- Data input for USER function
);
jtag_ld_addr <= user_regi(user_regi'left downto user_regi'left-inst_addr_t'length+1);
jtag_ld_din <= user_regi(inst_t'length-1 downto 0);
jtag_ld_clk <= bs_update1;
jtag_ld_we <= bs_sel;
sipo:
process (bs_rst, bs_clk1, bs_tdi, bs_shift)
begin
if bs_rst = '1' then
user_regi <= (others => '0');
elsif rising_edge(bs_clk1) then
if bs_shift = '1' then
user_regi <= bs_tdi & user_regi(user_regi'left downto 1);
end if;
end if;
end process;
piso:
process (bs_rst, bs_clk1, bs_shift, user_rego)
begin
bs_tdo <= user_rego(0);
if bs_rst = '1' then
user_rego <= (others => '0');
elsif rising_edge(bs_clk1) then
if bs_shift = '1' then
user_rego <= user_rego(0) & user_rego(user_rego'left downto 1);
else
user_rego <= (user_rego'left downto inst_t'length => '0') & jtag_ld_dout;
-- user_rego <= id;
end if;
end if;
end process;
--------------------------------------------------------------------------
-- ROM Read/Write
--------------------------------------------------------------------------
PROM_READ:
process(clk, ce)
begin
if rising_edge(clk) and ce = '1' then
dout <= imem_rom(to_integer(addr));
end if;
end process;
PROM_WRITE:
process(jtag_ld_clk, jtag_ld_we)
begin
if rising_edge(jtag_ld_clk) then
if jtag_ld_we = '1' then
imem_rom(to_integer(jtag_ld_addr)) <= jtag_ld_din;
else
jtag_ld_dout <= imem_rom(to_integer(jtag_ld_addr));
end if;
end if;
end process;
--------------------------------------------------------------------------
end loadable;
+494
View File
@@ -0,0 +1,494 @@
#!/usr/bin/env ruby
# ----------------------------------------------------------------------
# Project: JCPU, a portable 8-bit RISC CPU written in VHDL
# This file: A small assembler for the JCPU
# Copyright (C) 2007 J. Ahrensfeld
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
# This library 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
# Lesser General Public License for more details.
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
# For questions and ideas, please contact the author at jens@jayfield.org
# ---------------------------------------------------------------------
arg = $*
MAX_SIZE_ROM = 1024
PROJECT_NAME = arg.to_s.gsub(/\..*/, "")
ENTITY_NAME = "rom"
ENTITY_DATA_TYPE = "inst_t"
ENTITY_ADDR_TYPE = "inst_addr_t"
OPC_LIST_NAME = "/cygdrive/w/vhdl/lib/CPUs/JCpu/tools/opc.list"
# --------------------------------------------------------
# Open file
# --------------------------------------------------------
filename = arg.to_s
if !File.exists?(filename)
STDERR.puts "#{filename} does not exist"
exit 1
end
# --------------------------------------------------------
# Pass 1
# --------------------------------------------------------
lc = 0 # Line counter
pc = 0 # Program counter
chip_dc = [0,0,0,0] # chip data counter
xmem_dc = 0 # xmem data counter
curr_segment = "UNDEF";
page = 0
label_list=[[],[]]
instr_list=[nil]
file = File.open(filename, "r")
file.each do |raw_line|
lc += 1
# Make all upper case
iline = "#{raw_line}".strip.upcase
# Remove comments
iline = iline.gsub(/;.*/, "")
# Split instruction at spaces
iline_member = iline.split(" ")
if iline_member[0] == nil
next
end
mc = 0;
label = nil
clean_line = nil
if (iline_member[0] =~ /\w+:/)
mc += 1
label = iline_member[0].delete(":")
if label_list.rindex(label) != nil
STDERR.puts format("Error in line %d: Duplicate label \"%s\" found", lc, label)
exit 1
end
end
case iline_member[mc]
when nil
value = format("0x%3.3X",pc)
when "EQU"
if 0 == (iline_member[mc+1] =~ /\d+/)
value = format("0x%2.2X",eval(iline_member[mc+1..iline_member.nitems].to_s))
else
value = iline_member[mc+1]
end
when "ORG", "CODE"
pc = eval(iline_member[mc+1..iline_member.nitems].to_s)
value = format("0x%3.3X",pc)
when "CDATA", "CMEM"
if iline_member[mc+1] == nil
STDERR.puts format("Error in line %d: CDATA needs argument!", lc)
exit 1
end
curr_segment = "CMEM";
page = iline_member[mc+1].to_i(16)
when "XDATA", "XMEM"
curr_segment = "XMEM";
when "DC"
len = 0;
iline.split("DC")[1].delete("0x").scan(/[0-9A-Fa-f]+/).each do |byte|
len += 1
end
if curr_segment == "CMEM"
STDERR.puts format("Error in line %d: CDATA cannot be initialized!", lc)
exit 1
else
value = format("0x%2.2X",xmem_dc)
puts format("Found DC defining %d bytes at 0x%4.4X in %s", len, xmem_dc, curr_segment);
xmem_dc += len
end
when "DB"
len = iline_member[mc+1].to_i
if curr_segment == "CMEM"
value = format("0x%2.2X",chip_dc[page])
puts format("Found DB reserving %d bytes at 0x%4.4X in %s(%d)", len, chip_dc[page], curr_segment, page);
chip_dc[page] += len
else
value = format("0x%2.2X",xmem_dc)
puts format("Found DB reserving %d bytes at 0x%4.4X in %s", len, xmem_dc, curr_segment);
xmem_dc += len
end
else
op_line = iline_member[mc+1..iline_member.nitems].to_s
value = format("0x%3.3X",pc)
opc = iline_member[mc]
if iline_member[mc+1] != nil
op1 = op_line.gsub(/,+.*$/, "")
end
if iline_member[mc+2] != nil
op2 = op_line.scan(/,.+$/).to_s.delete(", ")
end
if instr_list[pc] == nil
instr_list[pc] = [lc, pc, opc , op1 , op2]
pc += 1
else
STDERR.puts format("Error in line %d: Overlapping sections at %3.3X", lc, pc)
exit 1
end
end;
# Push labels
if label
label_list = label_list + [label, value]
end
end
file.close
# --------------------------------------------------------
def instr(opcode)
return format("\"%6.6B\" & X\"%3.3X\"",opcode ,0)
end
def tcl_bits(pc, opcode)
return format("%10.10B%6.6B%12.12B",pc, opcode ,0)
end
def instr_k(opcode, k)
return format("\"%6.6B\" & X\"%3.3X\"",opcode ,k)
end
def tcl_bits_k(pc, opcode, k)
return format("%10.10B%6.6B%12.12B",pc, opcode ,k)
end
def instr_r(opcode, r)
return format("\"%6.6B\" & X\"%2.2X%X\"",opcode ,0, r)
end
def tcl_bits_r(pc, opcode, r)
return format("%10.10B%6.6B%8.8B%4.4B",pc, opcode ,0,r)
end
def instr_kr(opcode, k, r)
return format("\"%6.6B\" & X\"%2.2X%X\"",opcode,k, r)
end
def tcl_bits_kr(pc, opcode, k, r)
return format("%10.10B%6.6B%8.8B%4.4B",pc, opcode, k, r)
end
def instr_rk(opcode, r, k)
return format("\"%6.6B\" & X\"%2.2X%X\"",opcode,k, r)
end
def tcl_bits_rk(pc, opcode, r, k)
return format("%10.10B%6.6B%8.8B%4.4B",pc, opcode, k, r)
end
def instr_rr(opcode, ra, rb)
return format("\"%6.6B\" & X\"%X%X%X\"",opcode,0, rb, ra)
end
def tcl_bits_rr(pc, opcode, ra, rb)
return format("%10.10B%6.6B%4.4B%4.4B%4.4B",pc, opcode, 0, rb, ra)
end
# --------------------------------------------------------
# Read mnemonic set
# --------------------------------------------------------
filename = OPC_LIST_NAME
if !File.exists?(filename)
STDERR.puts "#{filename} does not exist"
exit 1
end
mnemo_list = []
num_opcodes = 0
file = File.open(filename, "r")
file.each do |raw_line|
mnemo_list[num_opcodes] = raw_line.split(" ")[1]
num_opcodes += 1
end
# --------------------------------------------------------
# Pass 2
# --------------------------------------------------------
pc = 0
opc_start = 2
num_errors = 0
vhdl_trans_list = [nil]
vhdl_comment_list = [nil]
vhdl_tcl_list = [nil]
instr_list.each do |instruct|
# puts instruct
if instruct == nil
vhdl_trans_list[pc] = format("\"%6.6B\" & X\"%3.3X\"",0 ,0)
vhdl_comment_list[pc] = format("0x%3.3X:", pc)
vhdl_tcl_list[pc] = tcl_bits(pc, 0)
pc += 1
next
end
# determine arglen of instruction
ilen = 0
if instruct[opc_start+1] == nil
arglen = 0
elsif instruct[opc_start+2] == nil
arglen = 1
elsif instruct[opc_start+3] == nil
arglen = 2
end
# Symbol substitution
error = false
for i in (1..3)
subst_pos = opc_start+i
if instruct[subst_pos] == nil
next
end
expr_token = ""
expr_subst = nil
is_direct = true;
# instruct[subst_pos] = instruct[subst_pos].delete(" ")
# checks R0 .. R16, Mnemonics
instr_str = instruct[subst_pos]
if 0 == (instr_str =~ /\(.+\)/)
instr_str = instr_str.delete("()")
is_direct = false;
end
expr_token = instr_str.split(/\+|\-|\*|\//)[0]
if (0 != (expr_token =~ /R[0-9]+/)) && (0 != (expr_token =~ /\d+/))
idx = label_list.rindex(expr_token)
if idx != nil
expr_subst = label_list[idx+1]
instruct[subst_pos] = instruct[subst_pos].gsub(expr_token, expr_subst)
else
STDERR.puts format("Error in line %d: Symbol \"%s\" not found", instruct[0], expr_token)
error = true
end
end
if expr_subst != nil
if 0 == (expr_subst =~ /\d+/)
if is_direct == true
instruct[subst_pos] = format("0x%2.2X", eval(instruct[subst_pos]))
else
instruct[subst_pos] = format("(0x%2.2X)", eval(instruct[subst_pos]))
end
else
if 0 != (expr_subst =~ /R[0-9]+/)
STDERR.puts format("Error in line %d: Invalid expression \"%s\"", instruct[0], expr_subst)
error = true
end
end
end
end
# Parse operands
reg = [0,0]
kk = 0
format = instruct[opc_start]
for i in (0..1)
if instruct[opc_start+i+1] =~ Regexp.new("R[0-9]+")
# Check indirect addressing
reg[i] = instruct[opc_start+i+1].delete("R()").to_i
format += "|R"
if reg[i] > 15
STDERR.puts format("Error in line %d: Invalid register \"R%d\" specified", instruct[0], reg[i])
error = true
end
else
if instruct[opc_start+i+1] =~ Regexp.new("[0-9A-F]+")
kk = instruct[opc_start+i+1].delete("()").to_i(16)
format += "|K"
end
end
if instruct[opc_start+i+1] =~ Regexp.new("\\(.+\\)")
format += "i";
end
end
# Output instruction
opcode = mnemo_list.rindex(format).to_i
mnemo = instruct[2];
case format
when "NOP", "HALT", "RET", "RETI"
vhdl_trans_list[pc] = instr(opcode)
vhdl_tcl_list[pc] = tcl_bits(pc, opcode)
minstr_comment = format("0x%3.3X: %s", pc, mnemo)
when "MOVC|R|Ri", "MOVX|R|Ri"
vhdl_trans_list[pc] = instr_rr(opcode, reg[0], reg[1]);
vhdl_tcl_list[pc] = tcl_bits_rr(pc, opcode, reg[0], reg[1])
minstr_comment = format("0x%3.3X: %s R%2.2d, (R%2.2d)", pc, mnemo, reg[0], reg[1])
when "MOV|R|R", "SUB|R|R", "ADD|R|R", "AND|R|R", "OR|R|R", "XOR|R|R", "CMP|R|R"
vhdl_trans_list[pc] = instr_rr(opcode, reg[0], reg[1]);
vhdl_tcl_list[pc] = tcl_bits_rr(pc, opcode, reg[0], reg[1])
minstr_comment = format("0x%3.3X: %s R%2.2d, R%2.2d", pc, mnemo, reg[0], reg[1])
when "MOVC|Ri|R", "MOVX|Ri|R"
vhdl_trans_list[pc] = instr_rr(opcode, reg[1], reg[0]);
vhdl_tcl_list[pc] = tcl_bits_rr(pc, opcode, reg[1], reg[0])
minstr_comment = format("0x%3.3X: %s (R%2.2d), R%2.2d", pc, mnemo, reg[1], reg[0])
when "MOVC|Ri|K", "MOVX|Ri|K", "COUT|Ri|K", "XOUT|Ri|K"
vhdl_trans_list[pc] = instr_rk(opcode, reg[0], kk);
vhdl_tcl_list[pc] = tcl_bits_rk(pc, opcode, reg[0], kk)
minstr_comment = format("0x%3.3X: %s (R%2.2d), 0x%2.2X", pc, mnemo, reg[0], kk)
when "MOVC|R|Ki", "MOVX|R|Ki", "CIN|R|Ki", "XIN|R|Ki"
vhdl_trans_list[pc] = instr_rk(opcode, reg[0], kk);
vhdl_tcl_list[pc] = tcl_bits_rk(pc, opcode, reg[0], kk)
minstr_comment = format("0x%3.3X: %s R%2.2d, (0x%2.2X)", pc, mnemo, reg[0], kk)
when "MOV|R|K", "SUB|R|K", "ADD|R|K", "AND|R|K", "OR|R|K", "XOR|R|K", "CMP|R|K"
vhdl_trans_list[pc] = instr_rk(opcode, reg[0], kk);
vhdl_tcl_list[pc] = tcl_bits_rk(pc, opcode, reg[0], kk)
minstr_comment = format("0x%3.3X: %s R%2.2d, 0x%2.2X", pc, mnemo, reg[0], kk)
when "MOVC|Ki|R", "MOVC|Ki|R", "MOVX|Ki|R", "MOVX|Ki|R", "COUT|Ki|R", "XOUT|Ki|R"
vhdl_trans_list[pc] = instr_kr(opcode, kk, reg[1]);
vhdl_tcl_list[pc] = tcl_bits_kr(pc, opcode, kk, reg[1])
minstr_comment = format("0x%3.3X: %s (0x%2.2X), R%2.2d", pc, mnemo, kk, reg[1])
when "CALL|K", "JMP|K", "JNZ|K", "JZ|K","JNC|K", "JC|K", "JLT|K", "JGT|K", "JLE|K", "JGE|K", "JEQ|K", "JNE|K"
vhdl_trans_list[pc] = instr_k(opcode, kk)
vhdl_tcl_list[pc] = tcl_bits_k(pc, opcode, kk)
minstr_comment = format("0x%3.3X: %s 0x%3.3X", pc, mnemo, kk)
when "PUSH|R", "POP|R", "SHR|R", "SHL|R", "ROR|R", "ROL|R", "RORC|R", "ROLC|R"
vhdl_trans_list[pc] = instr_r(opcode, reg[0])
vhdl_tcl_list[pc] = tcl_bits_r(pc, opcode, reg[0])
minstr_comment = format("0x%3.3X: %s R%2.2d", pc, mnemo, reg[0])
when "TST|R"
kk = 0
minstr_comment = format("0x%3.3X: %s R%2.2d", pc, mnemo, reg[0])
opcode = mnemo_list.rindex("CMP|R|K").to_i
vhdl_trans_list[pc] = instr_rk(opcode, reg[0], kk);
vhdl_tcl_list[pc] = tcl_bits_rk(pc, opcode, reg[0], kk)
when "INC|R"
kk = 1
minstr_comment = format("0x%3.3X: %s R%2.2d", pc, mnemo, reg[0])
opcode = mnemo_list.rindex("ADD|R|K").to_i
vhdl_trans_list[pc] = instr_rk(opcode, reg[0], kk);
vhdl_tcl_list[pc] = tcl_bits_rk(pc, opcode, reg[0], kk)
when "DEC|R"
kk = 1
minstr_comment = format("0x%3.3X: %s R%2.2d", pc, mnemo, reg[0])
opcode = mnemo_list.rindex("SUB|R|K").to_i
vhdl_trans_list[pc] = instr_rk(opcode, reg[0], kk);
vhdl_tcl_list[pc] = tcl_bits_rk(pc, opcode, reg[0], kk)
else
STDERR.puts format("Error in line %d: Not yet implemented %s", instruct[0], format)
error = true
end
if error
num_errors += 1
break
end
vhdl_comment_list[pc] = minstr_comment
puts vhdl_trans_list[pc] + " -- " + minstr_comment
pc += 1
end
# --------------------------------------------------------
# Output ROM file
# --------------------------------------------------------
if num_errors == 0
filename = format("rom_%s.vhdl.snip", PROJECT_NAME)
file = File.open(filename, "w")
file.puts format("ENTITY %s IS\n", ENTITY_NAME)
file.puts format("\tPort (\n")
file.puts format("\tclk\t\t\t: in STD_LOGIC;\n")
file.puts format("\tce\t\t\t: in STD_LOGIC;\n")
file.puts format("\taddr\t\t: in %s;\n", ENTITY_ADDR_TYPE)
file.puts format("\tdout\t\t: out %s\n", ENTITY_DATA_TYPE)
file.puts format("\t);\n")
file.puts format("END %s;\n", ENTITY_NAME)
file.puts format("\n")
file.puts format("ARCHITECTURE %s OF %s IS \n", PROJECT_NAME, ENTITY_NAME)
file.puts format("\n")
file.puts format("\ttype instruction_rom_t is array (0 to %d) of %s;\n", pc-1, ENTITY_DATA_TYPE)
file.puts format("\n")
file.puts format("\tconstant instruction_rom : instruction_rom_t :=\n")
file.puts format("\t(\n");
for i in (0..pc-2)
file.puts "\t\t" + vhdl_trans_list[i] + ", -- " + vhdl_comment_list[i] + "\n"
end;
file.puts "\t\t" + vhdl_trans_list[pc-1] + " -- " + vhdl_comment_list[pc-1] + "\n"
file.puts format("\t);\n")
file.puts format("\n")
file.puts format("begin")
file.puts format("\n")
file.puts format("PROM_READ:")
file.puts format("\tprocess(clk, ce)\n")
file.puts format("\tbegin\n")
file.puts format("\t\tif rising_edge(clk) and ce = '1' then\n")
file.puts format("\t\t\tdout <= instruction_rom(to_integer(addr));\n")
file.puts format("\t\tend if;\n")
file.puts format("\tend process;\n")
file.puts format("\n")
file.puts format("end %s;\n", PROJECT_NAME)
puts format("ROM file written to \"%s\"\n",filename)
file.close
end
if num_errors == 0
filename = format("preinit_%s.vhdl.snip", PROJECT_NAME)
file = File.open(filename, "w")
file.puts format("\tsignal instruction_rom : instruction_rom_t :=\n")
file.puts format("\t(\n");
for i in (0..pc-2)
file.puts "\t\t" + vhdl_trans_list[i] + ", -- " + vhdl_comment_list[i] + "\n"
end;
if pc < (MAX_SIZE_ROM-1)
file.puts "\t\t" + vhdl_trans_list[pc-1] + ", -- " + vhdl_comment_list[pc-1] + "\n"
for i in (pc..(MAX_SIZE_ROM-2))
file.puts "\t\t" + instr(0) + ",\n"
end;
file.puts "\t\t" + instr(0) + "\n"
else
file.puts "\t\t" + vhdl_trans_list[pc-1] + " -- " + vhdl_comment_list[pc-1] + "\n"
end
file.puts format("\t);\n")
puts format("PREINIT file written to \"%s\"\n",filename)
file.close
end
if num_errors == 0
filename = format("rom_%s.tcl.snip", PROJECT_NAME)
file = File.open(filename, "w")
for i in (0..pc-1)
# Chipscope 8.1
# file.puts format("jtag_shiftdr $handle -buffer \"%s\" -endstate RTI -device $devid", vhdl_tcl_list[i].reverse);
# Chipscope 9.1
file.puts format("\# %s", vhdl_comment_list[i])
file.puts format("::chipscope::csejtag_tap shift_device_dr $handle $devid $CSEJTAG_SHIFT_READWRITE $CSEJTAG_RUN_TEST_IDLE 0 %d \"%8.8X\"\n\n", vhdl_tcl_list[i].length, vhdl_tcl_list[i].to_i(2));
end;
puts format("TCL snippet written to \"%s\"\n",filename)
file.close
end
# --------------------------------------------------------
# Output final statistics
# --------------------------------------------------------
if num_errors == 0
puts "Program uses #{pc} instruction addresses"
puts "No errors found"
exit 0
else
puts "#{num_errors} errors found"
exit 1
end
+814
View File
@@ -0,0 +1,814 @@
#!/usr/bin/env ruby
# ----------------------------------------------------------------------
# Project: JCPU, a portable 8-bit RISC CPU written in VHDL
# This file: A small assembler for the JCPU
#
# Copyright (C) 2007 J. Ahrensfeld
#
# 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/>.
#
# For questions and ideas, please contact the author at jens@jayfield.org
#
# ---------------------------------------------------------------------
arg = $*
FILE_SUFFIX = "jsm"
IROM_MAX_SIZE = 1024
IROM_ENTITY_NAME = "irom"
IROM_DATA_TYPE = "inst_t"
IROM_ADDR_TYPE = "inst_addr_t"
XROM_MAX_SIZE = 256
XROM_DATA_TYPE = "dmem_data_t"
XROM_ADDR_TYPE = "dmem_addr_t"
XROM_ENTITY_NAME = "xrom"
OPC_LIST_NAME = "/cygdrive/w/vhdl/lib/CPUs/JCpu/tools/opc.list"
# --------------------------------------------------------
class Parser
def curr_segment
@curr_segment
end
def curr_segment=(arg)
@curr_segment=arg
end
def add_label(labelname, addr)
@label_list = @label_list + [labelname, addr]
end
def getLabelIdByName(label)
return @label_list.rindex(label)
end
def getLabelNameById(id)
return @label_list[id]
end
def put_instr(name, lc, opc , op1 , op2)
if get_instr != nil
STDERR.puts format("Error in line %d: Overlapping sections at %3.3X", lc, @pc)
exit 1
end
@instr_list[@pc] = [lc, @pc, opc , op1 , op2, name]
end
def get_instr
return @instr_list[@pc]
end
def put_xmem(value, lc)
if get_xmem != nil
STDERR.puts format("Error in line %d: Overlapping sections at %3.3X (%s)", lc, xmem_dc, curr_segment)
exit 1
end
@xmem[xmem_dc] = value
@xmem_dc = xmem_dc + 1
end
def get_xmem
return @xmem[xmem_dc]
end
def xmem
return @xmem
end
def put_cmem(value, lc)
if get_cmem(page) != nil
STDERR.puts format("Error in line %d: Overlapping sections at %3.3X (%s)", lc, cmem_dc, curr_segment)
exit 1
end
@cmem[page][cmem_dc] = value
@cmem_dc[page] = cmem_dc + 1
end
def get_cmem(pg)
return @cmem[pg][cmem_dc]
end
def cmem(page)
return @cmem[page]
end
def cmem_dc=(addr)
@cmem_dc[page] = addr
end
def cmem_dc
@cmem_dc[page]
end
def xmem_dc=(addr)
@xmem_dc = addr
end
def xmem_dc
@xmem_dc
end
def page=(page)
@page = page;
end
def page
@page;
end
def pc=(pc)
@pc = pc;
if (pc > @pc_max)
@pc_max = pc
end
end
def pc
@pc;
end
def pc_max
@pc_max;
end
def instr_list
@instr_list
end
def label_list
@label_list
end
def initialize()
@pc_max = 0
@pc = 0 # Program counter
@cmem_dc = [0,0,0,0] # chip data counter
@xmem_dc = 0 # xmem data counter
@curr_segment = "UNDEF";
@page = 0
@label_list=[[],[]]
@instr_list=[nil]
@cmem = [[],[]];
@xmem = [];
end
def method_missing(name, *args)
puts "I don't know the method #{name}"
end
end
# --------------------------------------------------------
def parse(name, obj)
lc = 0 # Line counter
file = File.open(name, "r")
file.each do |raw_line|
lc += 1
# Make all upper case
iline = "#{raw_line}".strip
# Remove comments
iline = iline.gsub(/;.*/, "")
# Split instruction at spaces
iline_member = iline.split(" ")
if iline_member[0] == nil
next
end
mc = 0;
label = nil
clean_line = nil
if (iline_member[0] =~ /\w+:/)
mc += 1
label = iline_member[0].delete(":")
if obj.getLabelIdByName(label) != nil
STDERR.puts format("Error in line %d: Duplicate label \"%s\" found", lc, label)
exit 1
end
end
token = iline_member[mc]
if token
token = token.upcase
end
case token
when nil
if obj.curr_segment == "CMEM"
curr_addr = format("0x%3.3X",obj.cmem_dc)
elsif obj.curr_segment == "XMEM"
curr_addr = format("0x%3.3X",obj.xmem_dc)
elsif obj.curr_segment == "CODE"
curr_addr = format("0x%3.3X",obj.pc)
else
STDERR.puts format("Error in line %d: Undefined segment", lc)
exit 1
end
when "INCLUDE"
if iline_member[mc+1] == nil
STDERR.puts format("Error in line %d: %s needs argument!", lc, token)
exit 1
end
inc_name = iline_member[mc+1].delete("\"")
puts format("Inserting \"%s\" into \"%s\" at line %d", inc_name, name, lc);
parse(inc_name, obj)
when "EQU"
if iline_member[mc+1] == nil
STDERR.puts format("Error in line %d: %s needs argument!", lc, token)
exit 1
end
if 0 == (iline_member[mc+1] =~ /\d+/)
curr_addr = format("0x%2.2X",eval(iline_member[mc+1..iline_member.nitems].to_s))
else
curr_addr = iline_member[mc+1]
end
when "ORG"
if iline_member[mc+1] == nil
STDERR.puts format("Error in line %d: %s needs argument!", lc, token)
exit 1
end
offset = eval(iline_member[mc+1..iline_member.nitems].to_s)
case obj.curr_segment
when "CODE"
obj.pc = offset
curr_addr = format("0x%3.3X",obj.pc)
when "CMEM"
obj.cmem_dc = offset
when "XMEM"
obj.xmem_dc = offset
end
when "CODE"
curr_addr = format("0x%3.3X",obj.pc)
obj.curr_segment = "CODE";
when "CDATA", "CMEM"
if iline_member[mc+1] == nil
STDERR.puts format("Error in line %d: %s needs argument!", lc, token)
exit 1
end
obj.curr_segment = "CMEM";
obj.page = iline_member[mc+1].to_i(16)
when "XDATA", "XMEM"
obj.curr_segment = "XMEM";
when "DC"
len = 0;
if iline_member[mc+1] == nil
STDERR.puts format("Error in line %d: %s needs argument!", lc, token)
exit 1
end
if obj.curr_segment == "CMEM"
STDERR.puts format("Error in line %d: %s cannot be initialized!", lc, obj.curr_segment)
exit 1
elsif obj.curr_segment == "XMEM"
curr_addr = format("0x%2.2X",obj.xmem_dc)
dc_old = obj.xmem_dc;
val_array = raw_line.split(/dc|DC|Dc|dC/)[1].delete("\t").gsub(/;.*/, "").split(",")
# Parse string literals
val_array.each do |item|
if 0 == (item =~ /.*\".*\"/)
str = item.delete("\"")
puts item
for nn in (0..str.length-1)
if str[nn] > 31
obj.put_xmem(str[nn], lc);
puts "S: " + str[nn].to_s
len += 1
end
end;
else
argument = item
puts "B: " + argument
obj.put_xmem(eval(argument), lc);
len += 1
end
end
puts format("Found DC defining %d bytes at 0x%4.4X in %s", len, dc_old, obj.curr_segment);
else
STDERR.puts format("Error in line %d: Invalid segment %s for \"%s\"", lc, obj.curr_segment, token)
exit 1
end
when "DB"
if iline_member[mc+1] == nil
STDERR.puts format("Error in line %d: %s needs argument!", lc, token)
exit 1
end
len = eval(iline_member[mc+1]).to_i
if obj.curr_segment == "CMEM"
curr_addr = format("0x%2.2X",obj.cmem_dc)
puts format("Found DB reserving %d bytes at 0x%4.4X in %s(%d)", len, obj.cmem_dc, obj.curr_segment, obj.page);
for nn in (1..len)
obj.put_cmem(0, lc)
end
elsif obj.curr_segment == "XMEM"
curr_addr = format("0x%2.2X",obj.xmem_dc)
puts format("Found DB reserving %d bytes at 0x%4.4X in %s", len, obj.xmem_dc, obj.curr_segment);
for nn in (1..len)
obj.put_xmem(0, lc)
end
else
STDERR.puts format("Error in line %d: Invalid segment %s for \"%s\"", lc, obj.curr_segment, token)
exit 1
end
else
if obj.curr_segment != "CODE"
STDERR.puts format("Error in line %d: Invalid segment %s for \"%s\"", lc, obj.curr_segment, token)
exit 1
end
op_line = iline_member[mc+1..iline_member.nitems].to_s
curr_addr = format("0x%3.3X",obj.pc)
opc = token
if iline_member[mc+1] != nil
op1 = op_line.gsub(/,+.*$/, "")
end
if iline_member[mc+2] != nil
op2 = op_line.scan(/,.+$/).to_s.delete(", ")
end
obj.put_instr(name, lc, opc, op1, op2)
obj.pc = obj.pc + 1
end;
# Push labels
if label
obj.add_label(label, curr_addr)
end
end
file.close
return obj
end
# --------------------------------------------------------
# Instruction formatting
# --------------------------------------------------------
def instr(opcode)
return format("\"%6.6B\" & X\"%3.3X\"",opcode ,0)
end
def tcl_bits(pc, opcode)
return format("%12.12B%8.8B%12.12B",pc, opcode ,0)
end
def instr_k(opcode, k)
return format("\"%6.6B\" & X\"%3.3X\"",opcode ,k)
end
def tcl_bits_k(pc, opcode, k)
return format("%12.12B%8.8B%12.12B",pc, opcode ,k)
end
def instr_r(opcode, r)
return format("\"%6.6B\" & X\"%2.2X%X\"",opcode ,0, r)
end
def tcl_bits_r(pc, opcode, r)
return format("%12.12B%8.8B%8.8B%4.4B",pc, opcode ,0,r)
end
def instr_kr(opcode, k, r)
return format("\"%6.6B\" & X\"%2.2X%X\"",opcode,k, r)
end
def tcl_bits_kr(pc, opcode, k, r)
return format("%12.12B%8.8B%8.8B%4.4B",pc, opcode, k, r)
end
def instr_rk(opcode, r, k)
return format("\"%6.6B\" & X\"%2.2X%X\"",opcode,k, r)
end
def tcl_bits_rk(pc, opcode, r, k)
return format("%12.12B%8.8B%8.8B%4.4B",pc, opcode, k, r)
end
def instr_rr(opcode, ra, rb)
return format("\"%6.6B\" & X\"%X%X%X\"",opcode,0, rb, ra)
end
def tcl_bits_rr(pc, opcode, ra, rb)
return format("%12.12B%8.8B%4.4B%4.4B%4.4B",pc, opcode, 0, rb, ra)
end
# --------------------------------------------------------
# Open file
# --------------------------------------------------------
filename = arg.to_s
if !File.exists?(filename)
STDERR.puts "#{filename} does not exist"
exit 1
end
PROJECT_NAME = File.basename(filename, "." + FILE_SUFFIX)
# --------------------------------------------------------
# Pass 1
# --------------------------------------------------------
first_pass = Parser.new();
parse(filename, first_pass)
# --------------------------------------------------------
# Read mnemonic set
# --------------------------------------------------------
filename = OPC_LIST_NAME
if !File.exists?(filename)
STDERR.puts "#{filename} does not exist"
exit 1
end
mnemo_list = []
num_opcodes = 0
file = File.open(filename, "r")
file.each do |raw_line|
mnemo_list[num_opcodes] = raw_line.split(" ")[1]
num_opcodes += 1
end
# --------------------------------------------------------
# Pass 2
# --------------------------------------------------------
pc = 0
opc_start = 2
num_errors = 0
vhdl_trans_list = [nil]
vhdl_comment_list = [nil]
vhdl_tcl_list = [nil]
# ToDo: Use class-methods
label_list = first_pass.label_list
instr_list = first_pass.instr_list
instr_list.each do |instruct|
# puts instruct
if instruct == nil
vhdl_trans_list[pc] = format("\"%6.6B\" & X\"%3.3X\"",0 ,0)
vhdl_comment_list[pc] = format("0x%3.3X:", pc)
vhdl_tcl_list[pc] = tcl_bits(pc, 0)
pc += 1
next
end
# determine arglen of instruction
ilen = 0
if instruct[opc_start+1] == nil
arglen = 0
elsif instruct[opc_start+2] == nil
arglen = 1
elsif instruct[opc_start+3] == nil
arglen = 2
end
# Symbol substitution
error = false
for i in (1..2)
subst_pos = opc_start+i
if instruct[subst_pos] == nil
next
end
expr_token = ""
expr_subst = nil
is_direct = true;
# checks R0 .. R16, Mnemonics
instruct[subst_pos] = instruct[subst_pos].gsub(/'low/, "")
if (nil != (instruct[subst_pos] =~ /'high/))
instruct[subst_pos]= format("%s/256", instruct[subst_pos].gsub(/'high/, ""))
end
instr_str = instruct[subst_pos]
if 0 == (instr_str =~ /\(.+\)/)
instr_str = instr_str.delete("()")
is_direct = false;
end
expr_token = instr_str.split(/\+|\-|\*|\/|\||\&/)[0]
if (0 != (expr_token =~ /R[0-9]+/)) && (0 != (expr_token =~ /\d+/))
idx = label_list.rindex(expr_token)
if idx != nil
expr_subst = label_list[idx+1]
instruct[subst_pos] = instruct[subst_pos].gsub(expr_token, expr_subst)
else
STDERR.puts format("%s: Error in line %d: Symbol \"%s\" not found", instruct[5], instruct[0], expr_token)
error = true
end
end
if expr_subst != nil
if 0 == (expr_subst =~ /\d+/)
if is_direct == true
instruct[subst_pos] = format("0x%2.2X", eval(instruct[subst_pos]))
else
instruct[subst_pos] = format("(0x%2.2X)", eval(instruct[subst_pos]))
end
else
if 0 != (expr_subst =~ /R[0-9]+/)
STDERR.puts format("%s: Error in line %d: Invalid expression \"%s\"", instruct[5], instruct[0], expr_subst)
error = true
end
end
end
end
# Parse operands
reg = [0,0]
kk = 0
format = instruct[opc_start]
for i in (0..1)
if instruct[opc_start+i+1] =~ Regexp.new("R[0-9]+")
# Check indirect addressing
reg[i] = instruct[opc_start+i+1].delete("R()").to_i
format += "|R"
if reg[i] > 15
STDERR.puts format("%s: Error in line %d: Invalid register \"R%d\" specified", instruct[5], instruct[0], reg[i])
error = true
end
else
if instruct[opc_start+i+1] =~ Regexp.new("[0-9A-F]+")
kk = eval(instruct[opc_start+i+1].delete("()"))
format += "|K"
end
end
if instruct[opc_start+i+1] =~ Regexp.new("\\(.+\\)")
format += "i";
end
end
if error
num_errors += 1
break
end
# Output instruction
opcode = mnemo_list.rindex(format).to_i
mnemo = instruct[2];
case format
# Native instructions
when "NOP", "HALT", "RET", "RETI", "SETC"
vhdl_trans_list[pc] = instr(opcode)
vhdl_tcl_list[pc] = tcl_bits(pc, opcode)
minstr_comment = format("0x%3.3X: %s", pc, mnemo)
when "MOVC|R|Ri", "MOVX|R|Ri"
vhdl_trans_list[pc] = instr_rr(opcode, reg[0], reg[1]);
vhdl_tcl_list[pc] = tcl_bits_rr(pc, opcode, reg[0], reg[1])
minstr_comment = format("0x%3.3X: %s R%2.2d, (R%2.2d)", pc, mnemo, reg[0], reg[1])
when "MOV|R|R", "SUB|R|R", "SUBC|R|R", "ADD|R|R", "ADDC|R|R", "AND|R|R", "OR|R|R", "XOR|R|R", "CMP|R|R"
vhdl_trans_list[pc] = instr_rr(opcode, reg[0], reg[1]);
vhdl_tcl_list[pc] = tcl_bits_rr(pc, opcode, reg[0], reg[1])
minstr_comment = format("0x%3.3X: %s R%2.2d, R%2.2d", pc, mnemo, reg[0], reg[1])
when "MOVC|Ri|R", "MOVX|Ri|R"
vhdl_trans_list[pc] = instr_rr(opcode, reg[1], reg[0]);
vhdl_tcl_list[pc] = tcl_bits_rr(pc, opcode, reg[1], reg[0])
minstr_comment = format("0x%3.3X: %s (R%2.2d), R%2.2d", pc, mnemo, reg[1], reg[0])
when "MOVC|Ri|K", "MOVX|Ri|K", "COUT|Ri|K", "XOUT|Ri|K"
kk = kk % 256;
vhdl_trans_list[pc] = instr_rk(opcode, reg[0], kk);
vhdl_tcl_list[pc] = tcl_bits_rk(pc, opcode, reg[0], kk)
minstr_comment = format("0x%3.3X: %s (R%2.2d), 0x%2.2X", pc, mnemo, reg[0], kk)
when "MOVC|R|Ki", "MOVX|R|Ki", "CIN|R|Ki", "XIN|R|Ki"
vhdl_trans_list[pc] = instr_rk(opcode, reg[0], kk);
vhdl_tcl_list[pc] = tcl_bits_rk(pc, opcode, reg[0], kk)
minstr_comment = format("0x%3.3X: %s R%2.2d, (0x%2.2X)", pc, mnemo, reg[0], kk)
when "MOV|R|K", "SUB|R|K", "SUBC|R|K", "ADD|R|K", "ADDC|R|K", "AND|R|K", "OR|R|K", "XOR|R|K", "CMP|R|K"
kk = kk % 256;
vhdl_trans_list[pc] = instr_rk(opcode, reg[0], kk);
vhdl_tcl_list[pc] = tcl_bits_rk(pc, opcode, reg[0], kk)
minstr_comment = format("0x%3.3X: %s R%2.2d, 0x%2.2X", pc, mnemo, reg[0], kk)
when "SUB|K|R", "SUBC|K|R"
kk = kk % 256;
vhdl_trans_list[pc] = instr_kr(opcode, kk, reg[1]);
vhdl_tcl_list[pc] = tcl_bits_kr(pc, opcode, kk, reg[1])
minstr_comment = format("0x%3.3X: %s 0x%2.2d, R%2.2X", pc, mnemo, kk, reg[1])
when "MOVC|Ki|R", "MOVC|Ki|R", "MOVX|Ki|R", "MOVX|Ki|R", "COUT|Ki|R", "XOUT|Ki|R"
vhdl_trans_list[pc] = instr_kr(opcode, kk, reg[1]);
vhdl_tcl_list[pc] = tcl_bits_kr(pc, opcode, kk, reg[1])
minstr_comment = format("0x%3.3X: %s (0x%2.2X), R%2.2d", pc, mnemo, kk, reg[1])
when "CALL|K", "JMP|K", "JNZ|K", "JZ|K","JNC|K", "JC|K", "JLT|K", "JGT|K", "JLE|K", "JGE|K", "JEQ|K", "JNE|K"
vhdl_trans_list[pc] = instr_k(opcode, kk)
vhdl_tcl_list[pc] = tcl_bits_k(pc, opcode, kk)
minstr_comment = format("0x%3.3X: %s 0x%3.3X", pc, mnemo, kk)
when "PUSH|R", "POP|R", "SHR|R", "SHL|R", "ROR|R", "ROL|R", "RORC|R", "ROLC|R", "SWAP|R"
vhdl_trans_list[pc] = instr_r(opcode, reg[0])
vhdl_tcl_list[pc] = tcl_bits_r(pc, opcode, reg[0])
minstr_comment = format("0x%3.3X: %s R%2.2d", pc, mnemo, reg[0])
# Synthetic instructions
when "CLRC"
kk = 0;
minstr_comment = format("0x%3.3X: %s", pc, mnemo)
opcode = mnemo_list.rindex("SUB|R|K").to_i
vhdl_trans_list[pc] = instr_rk(opcode, reg[0], kk);
vhdl_tcl_list[pc] = tcl_bits_rk(pc, opcode, reg[0], kk)
when "TST|R"
kk = 0
minstr_comment = format("0x%3.3X: %s R%2.2d", pc, mnemo, reg[0])
opcode = mnemo_list.rindex("CMP|R|K").to_i
vhdl_trans_list[pc] = instr_rk(opcode, reg[0], kk);
vhdl_tcl_list[pc] = tcl_bits_rk(pc, opcode, reg[0], kk)
when "NEG|R"
kk = 0
minstr_comment = format("0x%3.3X: %s R%2.2d", pc, mnemo, reg[0])
opcode = mnemo_list.rindex("SUB|K|R").to_i
vhdl_trans_list[pc] = instr_rk(opcode, reg[0], kk);
vhdl_tcl_list[pc] = tcl_bits_rk(pc, opcode, reg[0], kk)
when "NOT|R"
kk = 0
minstr_comment = format("0x%3.3X: %s R%2.2d", pc, mnemo, reg[0])
opcode = mnemo_list.rindex("XOR|R|K").to_i
vhdl_trans_list[pc] = instr_rk(opcode, reg[0], kk);
vhdl_tcl_list[pc] = tcl_bits_rk(pc, opcode, reg[0], kk)
when "INC|R"
kk = 1
minstr_comment = format("0x%3.3X: %s R%2.2d", pc, mnemo, reg[0])
opcode = mnemo_list.rindex("ADD|R|K").to_i
vhdl_trans_list[pc] = instr_rk(opcode, reg[0], kk);
vhdl_tcl_list[pc] = tcl_bits_rk(pc, opcode, reg[0], kk)
when "DEC|R"
kk = 1
minstr_comment = format("0x%3.3X: %s R%2.2d", pc, mnemo, reg[0])
opcode = mnemo_list.rindex("SUB|R|K").to_i
vhdl_trans_list[pc] = instr_rk(opcode, reg[0], kk);
vhdl_tcl_list[pc] = tcl_bits_rk(pc, opcode, reg[0], kk)
else
STDERR.puts format("%s: Error in line %d: Not yet implemented %s", instruct[5], instruct[0], format)
error = true
end
if error
num_errors += 1
break
end
vhdl_comment_list[pc] = minstr_comment
puts vhdl_trans_list[pc] + " -- " + minstr_comment
pc += 1
end
# --------------------------------------------------------
# Output ROM file
# --------------------------------------------------------
if num_errors == 0
# I-ROM VHDL-ROM
filename = format("%s.irom.vhdl.snip", PROJECT_NAME)
file = File.open(filename, "w")
file.puts format("ENTITY %s IS\n", IROM_ENTITY_NAME)
file.puts format("\tPort (\n")
file.puts format("\tclk\t\t\t: in STD_LOGIC;\n")
file.puts format("\tce\t\t\t: in STD_LOGIC;\n")
file.puts format("\taddr\t\t: in %s;\n", IROM_ADDR_TYPE)
file.puts format("\tdout\t\t: out %s\n", IROM_DATA_TYPE)
file.puts format("\t);\n")
file.puts format("END %s;\n", IROM_ENTITY_NAME)
file.puts format("\n")
file.puts format("ARCHITECTURE %s OF %s IS \n", PROJECT_NAME, IROM_ENTITY_NAME)
file.puts format("\n")
file.puts format("\ttype imem_rom_t is array (0 to %d) of %s;\n", [IROM_MAX_SIZE, pc].min-1 , IROM_DATA_TYPE)
file.puts format("\n")
file.puts format("\t-- Assembled from %s.%s", PROJECT_NAME, FILE_SUFFIX)
file.puts format("\tconstant imem_rom : imem_rom_t :=\n")
file.puts format("\t(\n");
for i in (0..[IROM_MAX_SIZE, pc].min-2)
file.puts "\t\t" + vhdl_trans_list[i] + ", -- " + vhdl_comment_list[i] + "\n"
end;
file.puts "\t\t" + vhdl_trans_list[pc-1] + " -- " + vhdl_comment_list[pc-1] + "\n"
file.puts format("\t);\n")
file.puts format("\n")
file.puts format("begin")
file.puts format("\n")
file.puts format("PROM_READ:")
file.puts format("\tprocess(clk, ce)\n")
file.puts format("\tbegin\n")
file.puts format("\t\tif rising_edge(clk) and ce = '1' then\n")
file.puts format("\t\t\tdout <= imem_rom(to_integer(addr));\n")
file.puts format("\t\tend if;\n")
file.puts format("\tend process;\n")
file.puts format("\n")
file.puts format("end %s;\n", PROJECT_NAME)
puts format("I-ROM file written to \"%s\"\n",filename)
file.close
# I-ROM VHDL-ROM (loadable)
filename = format("%s.irom_ld.vhdl.snip", PROJECT_NAME)
file = File.open(filename, "w")
file.puts format("\n\t-- Assembled from %s.%s", PROJECT_NAME, FILE_SUFFIX)
file.puts format("\ttype imem_rom_t is array (0 to %d) of %s;\n", IROM_MAX_SIZE-1, IROM_DATA_TYPE)
file.puts format("\tsignal imem_rom : imem_rom_t :=\n")
file.puts format("\t(\n");
for i in (0..pc-2)
file.puts "\t\t" + vhdl_trans_list[i] + ", -- " + vhdl_comment_list[i] + "\n"
end;
if pc < (IROM_MAX_SIZE-1)
file.puts "\t\t" + vhdl_trans_list[pc-1] + ", -- " + vhdl_comment_list[pc-1] + "\n"
for i in (pc..(IROM_MAX_SIZE-2))
file.puts "\t\t" + instr(0) + ",\n"
end;
file.puts "\t\t" + instr(0) + "\n"
else
file.puts "\t\t" + vhdl_trans_list[pc-1] + " -- " + vhdl_comment_list[pc-1] + "\n"
end
file.puts format("\t);\n")
puts format("I-ROM (loadable) file written to \"%s\"\n",filename)
file.close
# I-ROM TCL-Loader
filename = format("%s.irom.tcl.snip", PROJECT_NAME)
file = File.open(filename, "w")
file.puts format("# Assembled from %s.%s", PROJECT_NAME, FILE_SUFFIX)
file.puts format("# ---------------------------------------------------------------");
file.puts format("# Shift the USER1 Instruction (b1111000010) into the Instruction Register of FPGA");
file.puts format("# User 1")
file.puts format("set result [::chipscope::csejtag_tap shift_device_ir $handle $devid $CSE_OP $CSE_ES 0 $irlength \"3C2\"]\n\n")
for i in (0..pc-1)
# Chipscope 8.1
# file.puts format("jtag_shiftdr $handle -buffer \"%s\" -endstate RTI -device $devid", vhdl_tcl_list[i].reverse);
# Chipscope 9.1
file.puts format("\# %s", vhdl_comment_list[i])
file.puts format("::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 %d \"%8.8X\"\n\n", vhdl_tcl_list[i].length, vhdl_tcl_list[i].to_i(2));
end;
puts format("I-ROM TCL-loader written to \"%s\"\n",filename)
file.close
# X-ROM VHDL-ROM
filename = format("%s.xrom.vhdl.snip", PROJECT_NAME)
file = File.open(filename, "w")
file.puts format("ENTITY %s IS\n", XROM_ENTITY_NAME)
file.puts format("\tPort (\n")
file.puts format("\tclk\t\t\t: in STD_LOGIC;\n")
file.puts format("\tce\t\t\t: in STD_LOGIC;\n")
file.puts format("\taddr\t\t: in %s;\n", XROM_ADDR_TYPE)
file.puts format("\tdout\t\t: out %s\n", XROM_DATA_TYPE)
file.puts format("\t);\n")
file.puts format("END %s;\n", XROM_ENTITY_NAME)
file.puts format("\n")
file.puts format("ARCHITECTURE %s OF %s IS \n", PROJECT_NAME, XROM_ENTITY_NAME)
file.puts format("\n")
file.puts format("\ttype xmem_rom_t is array (0 to %d) of %s;\n", XROM_MAX_SIZE-1, XROM_DATA_TYPE)
file.puts format("\n")
file.puts format("\t-- Assembled from %s.%s", PROJECT_NAME, FILE_SUFFIX)
file.puts format("\tconstant xmem_rom : xmem_rom_t :=\n")
file.puts format("\t(\n");
for i in (0..XROM_MAX_SIZE-2)
file.puts format("\t\tX\"%2.2X\", -- 0x%2.2X\n", first_pass.xmem[i], i)
end;
i = XROM_MAX_SIZE-1
file.puts format("\t\tX\"%2.2X\" -- 0x%2.2X\n", first_pass.xmem[i], i)
file.puts format("\t);\n")
file.puts format("\n")
file.puts format("begin")
file.puts format("\n")
file.puts format("PROM_READ:")
file.puts format("\tprocess(clk, ce)\n")
file.puts format("\tbegin\n")
file.puts format("\t\tif rising_edge(clk) and ce = '1' then\n")
file.puts format("\t\t\tdout <= xmem_rom(to_integer(addr));\n")
file.puts format("\t\tend if;\n")
file.puts format("\tend process;\n")
file.puts format("\n")
file.puts format("end %s;\n", PROJECT_NAME)
puts format("X-ROM file written to \"%s\"\n",filename)
file.close
# X-ROM VHDL-ROM (loadable)
filename = format("%s.xrom_ld.vhdl.snip", PROJECT_NAME)
file = File.open(filename, "w")
file.puts format("\n\t-- Assembled from %s.%s", PROJECT_NAME, FILE_SUFFIX)
file.puts format("\ttype xmem_rom_t is array (0 to %d) of %s;\n", XROM_MAX_SIZE-1, XROM_DATA_TYPE)
file.puts format("\tsignal xmem_rom : xmem_rom_t :=\n")
file.puts format("\t(\n");
for i in (0..XROM_MAX_SIZE-2)
file.puts format("\t\tX\"%2.2X\", -- 0x%2.2X\n", first_pass.xmem[i], i)
end;
i = XROM_MAX_SIZE-1
file.puts format("\t\tX\"%2.2X\" -- 0x%2.2X\n", first_pass.xmem[i], i)
file.puts format("\t);\n")
puts format("X-ROM (loadable) file written to \"%s\"\n",filename)
file.close
# X-ROM TCL-Loader
filename = format("%s.xrom.tcl.snip", PROJECT_NAME)
file = File.open(filename, "w")
file.puts format("# Assembled from %s.%s", PROJECT_NAME, FILE_SUFFIX)
file.puts format("# ---------------------------------------------------------------");
file.puts format("# Shift the USER2 Instruction (b1111000011) into the Instruction Register of FPGA");
file.puts format("# User 2")
file.puts format("set result [::chipscope::csejtag_tap shift_device_ir $handle $devid $CSE_OP $CSE_ES 0 $irlength \"3C3\"]\n\n")
for i in (0..first_pass.xmem.length-1)
# Chipscope 8.1
# file.puts format("jtag_shiftdr $handle -buffer \"%s\" -endstate RTI -device $devid", vhdl_tcl_list[i].reverse);
# Chipscope 9.1
file.puts format("::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 %d \"%2.2X%2.2X\"\n", 16, i, first_pass.xmem[i]);
end;
puts format("X-ROM TCL-loader written to \"%s\"\n",filename)
file.close
end
# --------------------------------------------------------
# Output final statistics
# --------------------------------------------------------
if num_errors == 0
puts "Program uses #{first_pass.pc_max} instruction addresses"
puts "No errors found"
exit 0
else
puts "#{num_errors} errors found"
exit 1
end
+72
View File
@@ -0,0 +1,72 @@
; -------------------------------------------------
; lcd.inc.jsm
; -------------------------------------------------
; needs xio-address equates for
; reg_cg_char_addr: equ 0xXX ; RW
; reg_cg_line_addr: equ 0xXX ; RW
; reg_cg_data: equ 0xXX ; RW
; reg_cg_ctrl: equ 0xXX ; WO
; needs delay.inc.jsm
; -------------------------------------------------
cg_clr_line: push R0
mov R0, 2
xout (reg_cg_ctrl), R0
pop R0
ret
; -------------------------------------------------
cg_clr_screen: push R0
mov R0, 1
xout (reg_cg_ctrl), R0
pop R0
ret
; -------------------------------------------------
; R0 : char address
; R1 : line address
cg_set_addr: call cg_wait_rdy
xout (reg_cg_line_addr), R1
xout (reg_cg_char_addr), R0
ret
; -------------------------------------------------
; R0 : character
cg_putchar: call cg_wait_rdy
xout (reg_cg_data), R0
ret
; -------------------------------------------------
; R1 : ptr to string
cg_puts: push R0
cg_p_lp: movx R0, (R1)
inc R1
tst R0
jz ex_cgp
call cg_putchar
jmp cg_p_lp
ex_cgp: pop R0
ret
; -------------------------------------------------
; R1 : ptr to string
cg_clr_puts: call cg_clr_line
call cg_puts
ret
; -------------------------------------------------
; R1 : ptr to string
cg_puts_clr: call cg_puts
call cg_clr_line
ret
; -------------------------------------------------
cg_wait_rdy: push R0
cg_wr_lp: xin R0, (reg_hwstat)
and R0, 0x02
jz cg_wr_lp
pop R0
ret
; -------------------------------------------------
+7
View File
@@ -0,0 +1,7 @@
; JCPU On-Chip register
cpu_revision: equ 0x00 ; RO
cpu_control: equ 0x01 ; R/W
cpu_status: equ 0x02 ; RO
cpu_int_ctrl: equ 0x03 ; RW
cpu_cmem_high: equ 0x04 ; RW
cpu_stack_high: equ 0x05 ; RW
+64
View File
@@ -0,0 +1,64 @@
; -------------------------------------------------
; Delays
; -------------------------------------------------
delay1s: push R15
mov R15, 10
loop1s: call delay100ms
dec R15
jnz loop1s
pop R15
ret
delay100ms: push R15
mov R15, 10
loop100ms: call delay10ms
dec R15
jnz loop100ms
pop R15
ret
delay10ms: push R15
mov R15, 10
loop10ms: call delay1ms
dec R15
jnz loop10ms
pop R15
ret
delay1ms: push R15
mov R15, 10
loop1ms: call delay100us
dec R15
jnz loop1ms
pop R15
ret
delay100us: push R15
mov R15, 10
loop100us: call delay10us
dec R15
jnz loop100us
pop R15
ret
delay10us: push R15
mov R15, 99
loop10us: nop
nop
nop
dec R15
jnz loop10us
pop R15
ret
delay1us: push R15
mov R15, 9
loop1us: nop
nop
nop
dec R15
jnz loop1us
pop R15
ret
; -------------------------------------------------
+208
View File
@@ -0,0 +1,208 @@
; -------------------------------------------------
; lcd.inc.jsm
; -------------------------------------------------
; needs xmem-address definition for
; - lcd_port (LCD-Base)
; needs delay.inc.jsm
; -------------------------------------------------
lcd_cmd: equ 0x00
lcd_rd: equ 0x20
lcd_data: equ 0x40
lcd_enable: equ 0x80
LCD_CMD_Z1: equ 0x80
LCD_CMD_Z2: equ 0xC0
LCD_CMD_CLEAR: equ 0x01
; -------------------------------------------------
; Init LCD
; -------------------------------------------------
LCD_init: mov R2, 0x00
mov R0, 0x03
call _write_lcd
call delay10ms
mov R2, 0x00
mov R0, 0x03
call _write_lcd
call delay10ms
mov R2, 0x00
mov R0, 0x02
call _write_lcd
call delay1ms
; 1. Function set: 4-Bit mode, two display lines
mov R0, 0x28
call LCD_writecmd
; 2. Display on, no cursor
mov R0, 0x0C
call LCD_writecmd
; 3. Cursor shift during write
mov R0, 0x06
call LCD_writecmd
; 4. Display clear
mov R0, 0x01
call LCD_writecmd
ret
; -------------------------------------------------
; LCD_waitbsy
; -------------------------------------------------
LCD_waitbsy: push R0
bsy_loop: call LCD_readstat
and R0, 0x80
jz ex_bsy
call delay1us
jmp bsy_loop
ex_bsy: pop R0
ret
; -------------------------------------------------
; LCD_writecmd
; -------------------------------------------------
; R0 = cmd
LCD_writeaddr:
LCD_writecmd: push R2
mov R2, lcd_cmd
call LCD_write
pop R2
ret
; -------------------------------------------------
; LCD_putsx
; -------------------------------------------------
; R1 = address of null-terminated string in XMEM
LCD_putsx: push R0
putsx_loop: movx R0, (R1)
inc R1
tst R0
jz putsx_ex
call LCD_writechar
jmp putsx_loop
putsx_ex: pop R0
ret
; -------------------------------------------------
; LCD_putsc
; -------------------------------------------------
; R1 = address of null-terminated string in CMEM
LCD_putsc: push R0
putsc_loop: movc R0, (R1)
inc R1
tst R0
jz putsc_ex
call LCD_writechar
jmp putsc_loop
putsc_ex: pop R0
ret
; -------------------------------------------------
; LCD_writechar
; -------------------------------------------------
; R0 = char
LCD_writedata:
LCD_writechar: push R2
mov R2, lcd_data
call LCD_write
pop R2
ret
; -------------------------------------------------
; LCD_write
; -------------------------------------------------
; R0 = input
; R2 = register
LCD_write: call LCD_waitbsy
push R0
swap R0
call _write_lcd
pop R0
call _write_lcd
ret
; -------------------------------------------------
; LCD_readstat
; -------------------------------------------------
; R0 = status
LCD_readstat: push R2
mov R2, lcd_cmd
call LCD_read
pop R2
ret
; -------------------------------------------------
; LCD_read
; -------------------------------------------------
; R0 = output
; R2 = register
LCD_read: call _read_lcd
swap R0
push R0
call _read_lcd
pop R2
or R0, R2
ret
; -------------------------------------------------
; _write
; -------------------------------------------------
; R0 = input
_write_lcd: push R1
and R0, 0x0F
mov R1, R0
or R1, R2
xout (lcd_port), R1
call delay1us
mov R1, R0
or R1, R2
or R1, lcd_enable
xout (lcd_port), R1
call delay1us
mov R1, R0
or R1, R2
xout (lcd_port), R1
call delay1us
or R1, lcd_rd
xout (lcd_port), R1
pop R1
ret
; -------------------------------------------------
; _read
; -------------------------------------------------
; R0 = output
_read_lcd: push R1
mov R1, lcd_rd
or R1, R2
xout (lcd_port), R1
call delay1us
mov R1, lcd_rd
or R1, R2
or R1, lcd_enable
xout (lcd_port), R1
call delay1us
xin R0, (lcd_port)
and R0, 0x0F
mov R1, lcd_rd
or R1, R2
xout (lcd_port), R1
call delay1us
pop R1
ret
+42
View File
@@ -0,0 +1,42 @@
; -------------------------------------------------
; mul8x8.inc.jsm
; -------------------------------------------------
; -------------------------------------------------
; Parameter:
; R0 : operand 1
; R1 : operand 2
; Return:
; R0 : product low
; R1 : product high
mul8x8: push R2
push R3
push R4
mov R4, R1
mov R1, 0
mov R2, 0
mov R3, 0
loop1: cmp R4, 0x01
jeq ende1
shr R4
jnc next1
add R2, R0
addc R3, R1
next1: shl R0
rolc R1
jmp loop1
ende1: add R0, R2
addc R1, R3
pop R4
pop R3
pop R2
ret
; -------------------------------------------------
+32
View File
@@ -0,0 +1,32 @@
; -------------------------------------------------
; uart.inc.jsm
; -------------------------------------------------
; needs xmem-address definition for
; - uart_status (Status register)
; - uart_data (Data register)
; -------------------------------------------------
; sout
; -------------------------------------------------
; R0 = input
sout: push R1
sout1: xin R1, (uart_status)
and R1, 0x02
jnz sout1
xout (uart_data), R0
pop R1
ret
; -------------------------------------------------
; sin
; -------------------------------------------------
; R0 = output
sin: push R1
sin1: xin R1, (uart_status)
and R1, 0x10
jnz sin1
xin R0, (uart_data)
pop R1
ret
; -------------------------------------------------
+32
View File
@@ -0,0 +1,32 @@
; -------------------------------------------------
; utils.inc.jsm
; -------------------------------------------------
; -------------------------------------------------
; Parameter
; R0 : Bin value in lower nibble
; Return
; R0 : Hex character representing lower nibble
nibble2hex: and R0, 0x0F
cmp R0, 0x0A
jlt isNum1
add R0, 0x07
isNum1: add R0, 0x30
ret
; -------------------------------------------------
; Parameter
; R0 : Bin value
; Return
; R0 : Hex character high
; R1 : Hex character low
bin2hex: push R0
call nibble2hex
mov R1, R0
pop R0
swap R0
call nibble2hex
ret
; -------------------------------------------------
+64
View File
@@ -0,0 +1,64 @@
0 NOP
1 HALT
2 MOV|R|R
3 MOV|R|K
4 MOVX|R|Ri
5 MOVX|R|Ki
6 MOVX|Ri|R
7 MOVX|Ri|K
8 MOVX|Ki|R
9 MOVC|R|Ri
10 MOVC|R|Ki
11 MOVC|Ri|R
12 MOVC|Ri|K
13 MOVC|Ki|R
14 CMP|R|R
15 CMP|R|K
16 ADD|R|R
17 ADD|R|K
18 ADDC|R|R
19 ADDC|R|K
20 SUB|R|R
21 SUB|R|K
22 SUBC|R|R
23 SUBC|R|K
24 AND|R|R
25 AND|R|K
26 OR|R|R
27 OR|R|K
28 XOR|R|R
29 XOR|R|K
30 SHL|R
31 SHR|R
32 ROL|R
33 ROR|R
34 ROLC|R
35 RORC|R
36 XOUT|Ki|R
37 XOUT|Ri|K
38 COUT|Ki|R
39 COUT|Ri|K
40 XIN|R|Ki
41 CIN|R|Ki
42 SWAP|R
43 SETC
44 UNDEF
45 UNDEF
46 SUB|K|R
47 SUBC|K|R
48 JMP|K
49 JZ|K
50 JNZ|K
51 JC|K
52 JNC|K
53 JLT|K
54 JGT|K
55 JLE|K
56 JGE|K
57 JEQ|K
58 JNE|K
59 CALL|K
60 PUSH|R
61 POP|R
62 RET
63 RETI
+20
View File
@@ -0,0 +1,20 @@
#!/usr/bin/env ruby
st = "\033[7m"
en = "\033[m"
while TRUE
print "str> "
STDOUT.flush
str = gets
break if not str
str.chop!
print "pat> "
STDOUT.flush
re = gets
break if not re
re.chop!
str.gsub! re, "#{st}\\&#{en}"
print str, "\n"
end
print "\n"
+61
View File
@@ -0,0 +1,61 @@
# ----------------------------------------------------------------------
# Project: JCPU, a portable 8-bit RISC CPU written in VHDL
# This file: The ROM file for upload to target over JTAG
#
# Copyright (C) 2007 J. Ahrensfeld
#
# 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/>.
#
# For questions and ideas, please contact the author at jens@jayfield.org
#
# ---------------------------------------------------------------------
# ---------------------------------------------------------------------
# For Chipscope 9.1
# ---------------------------------------------------------------------
# Source JTAG/TCL frame work
cd $env(CHIPSCOPE)\\bin\\nt
source csejtag.tcl
namespace import ::chipscope::*
# Platform USB Cable
set PLATFORM_USB_CABLE_ARGS [list "port=USB2" "frequency=6000000"]
# frequency="24000000 | 12000000 | 6000000 | 3000000 | 1500000 | 750000"
# Create session
set handle [::chipscope::csejtag_session create 0]
# Open JTAG and lock
set open_result [::chipscope::csejtag_target open $handle $CSEJTAG_TARGET_PLATFORMUSB 0 $PLATFORM_USB_CABLE_ARGS]
set lock_result [::chipscope::csejtag_target lock $handle 1000]
set devlist [::chipscope::csejtag_tap autodetect_chain $handle $CSEJTAG_SCAN_DEFAULT]
# Get Device ID
set devtype "Virtex-4SX"
set devid 2
set irlength [::chipscope::csejtag_tap get_irlength $handle $devid]
set idcode [::chipscope::csejtag_tap get_device_idcode $handle $devid]
set CSE_OP $CSEJTAG_SHIFT_READWRITE
set CSE_ES $CSEJTAG_RUN_TEST_IDLE
# Write Program
# JASM_ROM_INSERT_HERE
::chipscope::csejtag_target unlock $handle
::chipscope::csejtag_target close $handle
::chipscope::csejtag_session destroy $handle
exit
+44
View File
@@ -0,0 +1,44 @@
#!/usr/bin/env ruby
template = <<'END'
-- (tv #1342) read output FIFO
(
cycles => 1,
cm_i => bus_read_init(addr => ADDR_KS_OFIFO_DOUT),
sep => msg(""),
cm_o => bus_no_ack,
irq => (others => '0')
),
-- (tv #1343) wait while FIFO is read
(
cycles => 2,
cm_i => bus_wait_ack,
sep => msg(""),
cm_o => bus_no_ack,
irq => (others => '0')
),
-- (tv #1343) wait for ack
(
cycles => 1,
cm_i => bus_wait_ack,
sep => msg(""),
cm_o => bus_read_ack(dat => #{exp_data}),
irq => (others => '0')
),
END
puts "KS-128 testvectors:\n"
puts "\n" * 3
0.upto(10) { |sk_no|
3.downto(0) { |sl_no|
exp_data = "slice_32(TC1_SUBKEYS(#{sk_no}), #{sl_no})"
t = template.gsub(/"/, '\\"')
puts eval("format(\"#{t}\")")
}
}
+32
View File
@@ -0,0 +1,32 @@
-------------------------------------------------------------------------
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
-- This file: The ROM file for use in your VHDL design
--
-- Copyright (C) 2007 J. Ahrensfeld
--
-- 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/>.
--
-- For questions and ideas, please contact the author at jens@jayfield.org
--
--------------------------------------------------------------------------
LIBRARY ieee;
use IEEE.STD_LOGIC_1164.ALL;
USE ieee.numeric_std.ALL;
library work;
use work.cpu_pkg.all;
-- JASM_ROM_INSERT_HERE
+151
View File
@@ -0,0 +1,151 @@
-------------------------------------------------------------------------
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
-- This file: loadable ROM
--
-- Copyright (C) 2007 J. Ahrensfeld
--
-- 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/>.
--
-- For questions and ideas, please contact the author at jens@jayfield.org
--
--------------------------------------------------------------------------
LIBRARY ieee;
use IEEE.STD_LOGIC_1164.ALL;
USE ieee.numeric_std.ALL;
library UNISIM;
use UNISIM.VComponents.all;
library work;
use work.cpu_pkg.all;
ENTITY xrom IS
Port (
clk : in STD_LOGIC;
ce : in STD_LOGIC;
addr : in dmem_addr_t;
dout : out dmem_data_t
);
END xrom;
ARCHITECTURE loadable OF xrom IS
-- JASM_ROM_INSERT_HERE
signal jtag_ld_clk : STD_LOGIC;
signal jtag_ld_we : STD_LOGIC;
signal jtag_ld_addr : dmem_addr_t;
signal jtag_ld_dout : dmem_data_t;
signal jtag_ld_din : dmem_data_t;
signal bs_rst, bs_sel, bs_shift, bs_tdi, bs_tdo : std_logic;
signal bs_capture, bs_clk0, bs_clk1, bs_update0, bs_update1 : std_logic;
signal user_regi, user_rego : unsigned (15 downto 0);
constant id : unsigned (15 downto 0) := X"BEEF";
begin
--------------------------------------------------------------------------
-- Virtex-4: JTAG Loader
--------------------------------------------------------------------------
i00_BUFG : BUFG
port map
(
O => bs_clk1,
I => bs_clk0
);
i01_BUFG : BUFG
port map
(
O => bs_update1,
I => bs_update0
);
BSCAN_VIRTEX4_inst2 : BSCAN_VIRTEX4
generic map
(
JTAG_CHAIN => 2 -- Value to set BSCAN site of device. Possible values: (1,2,3 or 4)
)
port map
(
CAPTURE => bs_capture, -- CAPTURE output from TAP controller
DRCK => bs_clk0, -- Data register output for USER functions
RESET => bs_rst, -- Reset output from TAP controller
SEL => bs_sel, -- USER active output
SHIFT => bs_shift, -- SHIFT output from TAP controller
TDI => bs_tdi, -- TDI output from TAP controller
UPDATE => bs_update0, -- UPDATE output from TAP controller
TDO => bs_tdo -- Data input for USER function
);
jtag_ld_addr <= user_regi(user_regi'left downto user_regi'left-dmem_data_t'length+1);
jtag_ld_din <= user_regi(dmem_data_t'left downto 0);
jtag_ld_clk <= bs_update1;
jtag_ld_we <= bs_sel;
sipo:
process (bs_rst, bs_clk1, bs_tdi, bs_shift)
begin
if bs_rst = '1' then
user_regi <= (others => '0');
elsif rising_edge(bs_clk1) then
if bs_shift = '1' then
user_regi <= bs_tdi & user_regi(user_regi'left downto 1);
end if;
end if;
end process;
piso:
process (bs_rst, bs_clk1, bs_shift, user_rego)
begin
bs_tdo <= user_rego(0);
if bs_rst = '1' then
user_rego <= (others => '0');
elsif rising_edge(bs_clk1) then
if bs_shift = '1' then
user_rego <= user_rego(0) & user_rego(user_rego'left downto 1);
else
user_rego <= (user_rego'left downto dmem_data_t'length => '0') & jtag_ld_dout;
-- user_rego <= id;
end if;
end if;
end process;
--------------------------------------------------------------------------
-- ROM Read/Write
--------------------------------------------------------------------------
PROM_READ:
process(clk, ce)
begin
if rising_edge(clk) and ce = '1' then
dout <= xmem_rom(to_integer(addr));
end if;
end process;
PROM_WRITE:
process(jtag_ld_clk, jtag_ld_we)
begin
if rising_edge(jtag_ld_clk) then
if jtag_ld_we = '1' then
xmem_rom(to_integer(jtag_ld_addr)) <= jtag_ld_din;
else
jtag_ld_dout <= xmem_rom(to_integer(jtag_ld_addr));
end if;
end if;
end process;
--------------------------------------------------------------------------
end loadable;
-2
View File
@@ -1,2 +0,0 @@
VHDL/lib/emac/emac_jb.vhd
-8
View File
@@ -1,8 +0,0 @@
VHDL/lib/emac/sim/tb_emac_jb.fdo
VHDL/lib/emac/sim/tb_serdes.fdo
VHDL/lib/emac/sim/tb_emac_jb.wdo
VHDL/lib/emac/sim/tb_serdes.wdo
VHDL/lib/emac/sim/tb_serdes.fdo
VHDL/lib/emac/sim/tb_serdes.wdo
-14
View File
@@ -1,14 +0,0 @@
## NOTE: Do not edit this file.
## Autogenerated by ProjNav (creatfdo.tcl) on Thu Jul 06 20:49:07 Westeuropäische Sommerzeit 2006
##
vlib work
vcom -explicit -93 "../../misc/utils_pkg.vhd"
vcom -explicit -93 "../src/crc32.vhd"
vcom -explicit -93 "../src/tb_crc32.vhd"
vsim -t 1ps -lib work tb_crc32
view wave
do {tb_crc32.wdo}
view structure
view signals
run 1 us
-25
View File
@@ -1,25 +0,0 @@
onerror {resume}
quietly WaveActivateNextPane {} 0
add wave -noupdate -format Logic /tb_crc32/clk
add wave -noupdate -format Logic /tb_crc32/rst
add wave -noupdate -format Logic /tb_crc32/din_vld
add wave -noupdate -format Literal -radix hexadecimal /tb_crc32/din
add wave -noupdate -format Literal -radix hexadecimal /tb_crc32/crc32
add wave -noupdate -format Logic /tb_crc32/crc32_vld
add wave -noupdate -format Literal -radix hexadecimal /tb_crc32/test_data
TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 1} {667016 ps} 0}
configure wave -namecolwidth 150
configure wave -valuecolwidth 100
configure wave -justifyvalue left
configure wave -signalnamewidth 1
configure wave -snapdistance 10
configure wave -datasetprefix 0
configure wave -rowmargin 4
configure wave -childrowmargin 2
configure wave -gridoffset 0
configure wave -gridperiod 100
configure wave -griddelta 40
configure wave -timeline 1
update
WaveRestoreZoom {0 ps} {1050 ns}
-15
View File
@@ -1,15 +0,0 @@
## NOTE: Do not edit this file.
## Autogenerated by ProjNav (creatfdo.tcl) on Thu Jul 06 20:49:07 Westeuropäische Sommerzeit 2006
##
vlib work
vcom -explicit -93 "../../misc/utils_pkg.vhd"
vcom -explicit -93 "../src/piso.vhd"
vcom -explicit -93 "../src/sipo.vhd"
vcom -explicit -93 "../src/tb_serdes.vhd"
vsim -t 1ps -lib work tb_serdes
view wave
do {tb_serdes.wdo}
view structure
view signals
run 20 us
-58
View File
@@ -1,58 +0,0 @@
onerror {resume}
quietly WaveActivateNextPane {} 0
add wave -noupdate -format Logic /tb_serdes/clk
add wave -noupdate -format Logic /tb_serdes/rst
add wave -noupdate -divider PiSo
add wave -noupdate -format Logic /tb_serdes/clk
add wave -noupdate -format Logic /tb_serdes/piso_din_vld
add wave -noupdate -format Logic /tb_serdes/piso_din_rdy
add wave -noupdate -format Literal /tb_serdes/piso_din_be
add wave -noupdate -format Literal -radix hexadecimal /tb_serdes/piso_din
add wave -noupdate -format Logic /tb_serdes/piso_dout_vld
add wave -noupdate -format Literal -radix hexadecimal /tb_serdes/piso_dout
add wave -noupdate -format Logic /tb_serdes/piso_dout_en
add wave -noupdate -divider SiPo
add wave -noupdate -format Logic /tb_serdes/clk
add wave -noupdate -format Logic /tb_serdes/sipo_enable
add wave -noupdate -format Logic /tb_serdes/sipo_rst
add wave -noupdate -format Logic /tb_serdes/sipo_din_vld
add wave -noupdate -format Literal -radix hexadecimal /tb_serdes/sipo_din
add wave -noupdate -format Logic /tb_serdes/sipo_dout_vld
add wave -noupdate -format Logic /tb_serdes/sipo_dout_en
add wave -noupdate -format Literal /tb_serdes/sipo_dout_be
add wave -noupdate -format Literal -radix hexadecimal /tb_serdes/sipo_dout
add wave -noupdate -divider PiSo
add wave -noupdate -format Logic /tb_serdes/clk
add wave -noupdate -format Logic /tb_serdes/piso2_din_vld
add wave -noupdate -format Logic /tb_serdes/piso2_din_rdy
add wave -noupdate -format Literal /tb_serdes/piso2_din_be
add wave -noupdate -format Literal -radix hexadecimal /tb_serdes/piso2_din
add wave -noupdate -format Logic /tb_serdes/piso2_dout_vld
add wave -noupdate -format Literal -radix hexadecimal /tb_serdes/piso2_dout
add wave -noupdate -format Logic /tb_serdes/piso2_dout_en
add wave -noupdate -divider SiPo
add wave -noupdate -format Logic /tb_serdes/clk
add wave -noupdate -format Logic /tb_serdes/sipo2_enable
add wave -noupdate -format Logic /tb_serdes/sipo2_rst
add wave -noupdate -format Logic /tb_serdes/sipo2_din_vld
add wave -noupdate -format Literal -radix hexadecimal /tb_serdes/sipo2_din
add wave -noupdate -format Logic /tb_serdes/sipo2_dout_vld
add wave -noupdate -format Logic /tb_serdes/sipo2_dout_en
add wave -noupdate -format Literal /tb_serdes/sipo2_dout_be
add wave -noupdate -format Literal -radix hexadecimal /tb_serdes/sipo2_dout
TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 1} {19757882 ps} 0} {{Cursor 2} {49999912163 ps} 0} {{Cursor 3} {49999529250 ps} 0}
configure wave -namecolwidth 150
configure wave -valuecolwidth 100
configure wave -justifyvalue left
configure wave -signalnamewidth 1
configure wave -snapdistance 10
configure wave -datasetprefix 0
configure wave -rowmargin 4
configure wave -childrowmargin 2
configure wave -gridoffset 0
configure wave -gridperiod 100
configure wave -griddelta 40
configure wave -timeline 1
update
WaveRestoreZoom {0 ps} {21 us}
-34
View File
@@ -1,34 +0,0 @@
## NOTE: Do not edit this file.
## Autogenerated by ProjNav (creatfdo.tcl) on Thu Jul 06 20:49:07 Westeuropäische Sommerzeit 2006
##
vlib work
vcom -explicit -93 "../../misc/utils_pkg.vhd"
vcom -explicit -93 "../../rams/dpram_1w1r2c_ra_sim.vhd"
vcom -explicit -93 "../../rams/dpram_2w2r2c_ra_sim.vhd"
vcom -explicit -93 "../../rams/dpram_1w1r2c_ro_sim.vhd"
vcom -explicit -93 "../../rams/dpram_2w2r2c_ro_sim.vhd"
vcom -explicit -93 "../../FIFO/src/fifo_ctrl_pkg.vhd"
vcom -explicit -93 "../../FIFO/src/fifo_sync_ctrl.vhd"
vcom -explicit -93 "../../FIFO/src/fifo_sync.vhd"
vcom -explicit -93 "../../FIFO/src/gray_counter.vhd"
vcom -explicit -93 "../../FIFO/src/fifo_async_ctrl.vhd"
vcom -explicit -93 "../../FIFO/src/fifo_async.vhd"
vcom -explicit -93 "../../JBUS/src/busmaster_types.vhd"
vcom -explicit -93 "../../JBUS/src/busmaster_sync.vhd"
vcom -explicit -93 "../../JBUS/src/dmac.vhd"
vcom -explicit -93 "../src/piso.vhd"
vcom -explicit -93 "../src/sipo.vhd"
vcom -explicit -93 "../src/crc32.vhd"
vcom -explicit -93 "../src/emac_types.vhd"
vcom -explicit -93 "../src/emac_rx.vhd"
vcom -explicit -93 "../src/emac_tx.vhd"
vcom -explicit -93 "../src/emac_top_jb.vhd"
vcom -explicit -93 "../src/pkt_gen.vhd"
vcom -explicit -93 "../src/tb_emac_top_jb.vhd"
vsim -t 1ps -lib work tb_emac_top_jb
view wave
do {tb_emac_top_jb.wdo}
view structure
view signals
run 16000 us
-236
View File
@@ -1,236 +0,0 @@
onerror {resume}
quietly WaveActivateNextPane {} 0
add wave -noupdate -divider {Ethernet MAC}
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/clk_i
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/rst_i
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/ram64
add wave -noupdate -divider Slave
add wave -noupdate -format Logic -radix hexadecimal /tb_emac_top_jb/inst_emac_top_jb/int_o
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/cyc_i
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/stb_i
add wave -noupdate -format Literal /tb_emac_top_jb/inst_emac_top_jb/sel_i
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/we_i
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/ack_o
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/srdy_o
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/mrdy_i
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/inst_emac_top_jb/addr_i
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/inst_emac_top_jb/dat_i
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/inst_emac_top_jb/dat_o
add wave -noupdate -divider Master
add wave -noupdate -format Logic /tb_emac_top_jb/cyc_o
add wave -noupdate -format Logic /tb_emac_top_jb/stb_o
add wave -noupdate -format Logic /tb_emac_top_jb/we_o
add wave -noupdate -format Literal /tb_emac_top_jb/sel_o
add wave -noupdate -format Logic /tb_emac_top_jb/ack_i
add wave -noupdate -format Logic /tb_emac_top_jb/mrdy_o
add wave -noupdate -format Logic /tb_emac_top_jb/srdy_i
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/addr_o
add wave -noupdate -format Literal /tb_emac_top_jb/mdat_i
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/mdat_o
add wave -noupdate -divider MII
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/mii_rx_clk
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/mii_rx_dv
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/mii_rx_er
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/inst_emac_top_jb/mii_rx
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/mii_tx_clk
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/mii_tx_en
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/mii_tx_er
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/inst_emac_top_jb/mii_tx
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/mii_gtx_clk
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/mii_crs
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/mii_col
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/status_reg
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/size_reg
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/dat_o_reg
add wave -noupdate -format Literal /tb_emac_top_jb/emac_action
add wave -noupdate -format Logic /tb_emac_top_jb/dat_o_cnt_rst
add wave -noupdate -format Literal /tb_emac_top_jb/dat_o_cnt
add wave -noupdate -format Literal /tb_emac_top_jb/pkt_count
add wave -noupdate -divider {Packet generator}
add wave -noupdate -format Literal /tb_emac_top_jb/inst_pkt_gen/tx_packets
add wave -noupdate -format Literal /tb_emac_top_jb/inst_pkt_gen/tx_bytes
add wave -noupdate -format Literal -radix unsigned /tb_emac_top_jb/inst_pkt_gen/pkt_nbytes
add wave -noupdate -format Literal -radix unsigned /tb_emac_top_jb/inst_pkt_gen/pkt_nwords
add wave -noupdate -format Literal /tb_emac_top_jb/inst_pkt_gen/host_s
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_emac_top_jb/inst_pkt_gen/tx_ctrl_in
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_emac_top_jb/inst_pkt_gen/tx_ctrl_out
add wave -noupdate -format Literal /tb_emac_top_jb/inst_pkt_gen/tx_bytes
add wave -noupdate -format Literal /tb_emac_top_jb/inst_pkt_gen/tx_packets
add wave -noupdate -format Literal -radix unsigned /tb_emac_top_jb/inst_pkt_gen/fill_size
add wave -noupdate -format Literal -radix unsigned /tb_emac_top_jb/inst_pkt_gen/fill_cnt
add wave -noupdate -format Logic /tb_emac_top_jb/inst_pkt_gen/fill_rdy
add wave -noupdate -format Logic /tb_emac_top_jb/inst_pkt_gen/fill_set
add wave -noupdate -format Logic /tb_emac_top_jb/inst_pkt_gen/fill_en
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/inst_pkt_gen/tx_din
add wave -noupdate -format Logic /tb_emac_top_jb/inst_pkt_gen/tx_din_vld
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/pktgen_tx
add wave -noupdate -format Logic /tb_emac_top_jb/pktgen_tx_en
add wave -noupdate -format Logic /tb_emac_top_jb/pktgen_tx_er
add wave -noupdate -format Logic /tb_emac_top_jb/pktgen_en
add wave -noupdate -divider RX-DMA
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/gen_dmac__0/inst_dmac/master_req
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/gen_dmac__0/inst_dmac/master_gnt
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/gen_dmac__0/inst_dmac/dma_start
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/gen_dmac__0/inst_dmac/dma_active
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/gen_dmac__0/inst_dmac/dma_end
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/gen_dmac__0/inst_dmac/req_rdy
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/gen_dmac__0/inst_dmac/req_en
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/gen_dmac__0/inst_dmac/req_rw
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/inst_emac_top_jb/gen_dmac__0/inst_dmac/req_addr_start
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/inst_emac_top_jb/gen_dmac__0/inst_dmac/req_num_xfers
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/gen_dmac__0/inst_dmac/req_addr_auto_inc
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/gen_dmac__0/inst_dmac/req_complete
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/gen_dmac__0/inst_dmac/req_complete_ack
add wave -noupdate -format Literal /tb_emac_top_jb/inst_emac_top_jb/gen_dmac__0/inst_dmac/s
add wave -noupdate -divider RX
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/clk
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/rst
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/dout_re
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/dout
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/ctrl_in
add wave -noupdate -format Literal -radix unsigned -expand /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/ctrl_out
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/mii_rx_clk
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/mii_rx_dv
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/mii_rx_er
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/mii_rx
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/mii_crs
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/mii_col
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/cmd_fifo_din
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/cmd_fifo_dout
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/cmd_fifo_we
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/cmd_fifo_re
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/cmd_fifo_empty
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/cmd_fifo_full
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/host_ptr
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/host_ram_limit
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/host_ram_base
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/commit_en
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/xfer_ram_limit
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/xfer_ram_full
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/xfer_base
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/xfer_ptr
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/ram_en_a
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/ram_we_a
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/ram_addr_a
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/ram_din_a
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/ram_en_b
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/ram_addr_b
add wave -noupdate -format Literal -radix unsigned /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/byte_count
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/sipo32_din
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/sipo32_din_vld
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/sipo32_dout
add wave -noupdate -format Literal /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/sipo32_dout_be
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/sipo32_dout_vld
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/sipo32_dout_en
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/sipo32_en
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/sipo32_rst
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/sipo8_dout
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/sipo8_rst
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/sipo8_dout_vld
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/sipo8_dout_en
add wave -noupdate -format Literal /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/host_s
add wave -noupdate -format Literal /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/xfer_s
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/preamble_bsy
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/preamble_ok
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/preamble_rdy
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/mac_chk_rdy
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/mac_chk_ok
add wave -noupdate -format Literal /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/mac_chk_num_ok
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/mac_chk_addr
add wave -noupdate -format Literal -radix unsigned /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/mac_chk_cnt
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/fcs_vld
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/fcs_din_vld
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/fcs
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_rx/fcs_chk_ok
add wave -noupdate -divider TX
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/clk
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/rst
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/din_vld
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/din
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/ctrl_in
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/ctrl_out
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/cmd_fifo_din
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/cmd_fifo_dout
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/cmd_fifo_we
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/cmd_fifo_re
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/cmd_fifo_empty
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/cmd_fifo_full
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/fill_pre_rdy
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/fill_bsy
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/fill_set
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/fill_en
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/fill_cnt_en
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/fill_base
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/fill_size
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/fill_cnt
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/fill_ptr
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/fill_remain
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/alloc_ok
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/alloc_req
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/alloc_ack
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/nwords_free
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/alloc_size
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/mem_alloc_en
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/mem_free_en
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/commit_en
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/uncommit_en
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/xfer_bsy
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/xfer_size
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/xfer_ptr
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/xfer_cnt
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/xfer_cnt_en
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/xfer_en
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/xfer_set
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/ram_en_a
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/ram_we_a
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/ram_addr_a
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/ram_din_a
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/ram_en_b
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/ram_addr_b
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/ram_dout_b
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/piso32_din
add wave -noupdate -format Literal /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/piso32_din_be
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/piso32_din_rdy
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/piso32_din_vld
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/piso32_dout
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/piso32_dout_vld
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/piso32_dout_en
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/mii_fifo_we
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/mii_fifo_re
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/mii_fifo_full
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/mii_fifo_empty
add wave -noupdate -format Literal /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/mii_fifo_re_dly
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/piso8_din_vld
add wave -noupdate -format Literal /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/piso8_din
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/piso8_dout_vld
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/piso8_din_rdy
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/piso8_dout
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/fcs_rst
add wave -noupdate -format Literal /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/fcs_en
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/fcs_din_vld
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/fcs_vld
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/fcs
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/mii_tx_clk
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/mii_tx_en
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/mii_tx_er
add wave -noupdate -format Literal -radix hexadecimal /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/mii_tx
add wave -noupdate -format Literal /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/host_s
add wave -noupdate -format Literal /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/xfer_s
add wave -noupdate -format Logic /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/mem_free_req
add wave -noupdate -format Literal /tb_emac_top_jb/inst_emac_top_jb/inst_emac_tx/mem_free_ack
TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 1} {15999470765 ps} 0} {{Cursor 2} {49999967706 ps} 0} {{Cursor 3} {42725669958 ps} 0} {{Cursor 4} {10461803096 ps} 0} {{Cursor 5} {10000 ps} 0}
configure wave -namecolwidth 150
configure wave -valuecolwidth 100
configure wave -justifyvalue left
configure wave -signalnamewidth 1
configure wave -snapdistance 10
configure wave -datasetprefix 0
configure wave -rowmargin 4
configure wave -childrowmargin 2
configure wave -gridoffset 0
configure wave -gridperiod 100
configure wave -griddelta 40
configure wave -timeline 1
update
WaveRestoreZoom {0 ps} {379173 ps}
-8
View File
@@ -1,8 +0,0 @@
VHDL/lib/emac/emac_jb.vhd
VHDL/lib/emac/src/emac_jb.vhd
VHDL/lib/emac/src/emac_jb.vhd
VHDL/lib/emac/src/tb_emac_jb.vhd
VHDL/lib/emac/src/tb_serdes.vhd
VHDL/lib/emac/src/tb_serdes.vhd
-64
View File
@@ -1,64 +0,0 @@
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
use std.textio.all; -- Imports the standard textio package.
use work.utils_pkg.all; -- Imports the standard textio package.
ENTITY crc32 IS
Generic
(
crc32_init : unsigned(31 downto 0) := X"00000000"
);
Port
(
rst : in STD_LOGIC;
clk : in STD_LOGIC;
din_vld : in STD_LOGIC;
din : in unsigned(7 downto 0);
crc32_vld : out STD_LOGIC;
crc32_out : out unsigned(31 downto 0)
);
END crc32;
ARCHITECTURE behavior OF crc32 IS
type crc_table_t is array (0 to 15) of unsigned(31 downto 0);
constant crc_table : crc_table_t :=
(
X"4DBDF21C", X"500AE278", X"76D3D2D4", X"6B64C2B0",
X"3B61B38C", X"26D6A3E8", X"000F9344", X"1DB88320",
X"A005713C", X"BDB26158", X"9B6B51F4", X"86DC4190",
X"D6D930AC", X"CB6E20C8", X"EDB71064", X"F0000000"
);
signal crc0 : unsigned(31 downto 0);
signal crc1 : unsigned(31 downto 0);
signal crc2 : unsigned(31 downto 0);
--------------------------------------------------------------------------
begin
crc1 <= X"0" & crc0(31 downto 4) xor crc_table(to_integer(crc0(3 downto 0) xor din(3 downto 0)));
crc2 <= X"0" & crc1(31 downto 4) xor crc_table(to_integer(crc1(3 downto 0) xor din(7 downto 4)));
crc32_out <= crc0;
--------------------------------------------------------------------------
process(clk)
begin
if rising_edge(clk) then
if rst = '1' then
crc0 <= crc32_init;
crc32_vld <= '0';
elsif din_vld = '1' then
crc0 <= crc2;
crc32_vld <= '1';
end if;
end if;
end process;
--------------------------------------------------------------------------
end behavior;
-561
View File
@@ -1,561 +0,0 @@
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
use std.textio.all; -- Imports the standard textio package.
use work.emac_types.all;
use work.utils_pkg.all;
ENTITY emac_rx IS
Generic
(
f_sysclk : real := 100.0;
RAM_SIZE : natural := 2048
);
Port
(
clk : in STD_LOGIC;
rst : in STD_LOGIC;
dout_re : in STD_LOGIC;
dout : out unsigned(31 downto 0);
ctrl_in : in rx_ctrl_in_t;
ctrl_out : out rx_ctrl_out_t;
mii_rx_clk : in STD_LOGIC;
mii_rx_dv : in STD_LOGIC;
mii_rx_er : in STD_LOGIC;
mii_rx : in unsigned(7 downto 0);
mii_crs : in STD_LOGIC;
mii_col : in STD_LOGIC
);
END emac_rx;
ARCHITECTURE behavior OF emac_rx IS
constant RAM_ADDR_WIDTH : natural := NextExpBaseTwo(RAM_SIZE);
subtype word_ptr_t is unsigned(RAM_ADDR_WIDTH-1 downto 0);
-- Signals for EMAC connections
signal cmd_fifo_din : unsigned(2*word_ptr_t'length+2 downto 0);
signal cmd_fifo_dout : unsigned(2*word_ptr_t'length+2 downto 0);
signal cmd_fifo_we : std_logic;
signal cmd_fifo_re : std_logic;
signal cmd_fifo_empty : std_logic;
signal cmd_fifo_full : std_logic;
signal reset_en : std_logic;
signal host_ptr : word_ptr_t;
signal host_ptr_next : word_ptr_t;
signal host_ram_limit : word_ptr_t;
signal host_ram_base : word_ptr_t;
signal commit_en : std_logic;
signal xfer_ram_limit : word_ptr_t;
signal xfer_ram_full : std_logic;
signal xfer_base : word_ptr_t;
signal xfer_ptr : word_ptr_t;
signal xfer_en : std_logic;
signal xfer_set : std_logic;
signal xfer_vld : std_logic;
signal xfer_promiscious : std_logic;
signal ram_en_a : std_logic;
signal ram_we_a : std_logic;
signal ram_addr_a : word_ptr_t;
signal ram_din_a : unsigned(31 downto 0);
signal ram_dout_b : unsigned(31 downto 0);
signal ram_en_b : std_logic;
signal ram_addr_b : word_ptr_t;
signal sipo32_din : unsigned(7 downto 0);
signal sipo32_din_vld : std_logic;
signal sipo32_dout : unsigned(31 downto 0);
signal sipo32_dout_be : unsigned(3 downto 0);
signal sipo32_dout_vld : std_logic;
signal sipo32_dout_en : std_logic;
signal sipo32_en : std_logic;
signal sipo32_rst : std_logic;
signal sipo8_dout : unsigned(7 downto 0);
signal sipo8_rst : std_logic;
signal sipo8_dout_vld : std_logic;
signal sipo8_dout_en : std_logic;
signal sipo8_en : std_logic;
signal byte_count_rst : std_logic;
signal byte_count : word_ptr_t;
signal reset_pipe : unsigned(31 downto 0);
signal preamble_en : std_logic;
signal preamble_rdy : std_logic;
signal preamble_bsy : std_logic;
signal preamble_OK : std_logic;
signal mac_chk_rdy : std_logic;
signal mac_chk_BC : std_logic;
signal mac_chk_OK : std_logic;
signal mac_chk_num_OK : natural range 0 to 6;
signal mac_chk_num_BC : natural range 0 to 6;
signal mac_chk_cnt : natural range 0 to 5;
signal mac_addr : mac_addr_t;
signal mac_chk_addr : mac_addr_t;
signal Gbps_en : std_logic;
signal fcs_chk_en : std_logic;
signal rx_en : std_logic;
signal fcs_vld : std_logic;
signal fcs_din_vld : std_logic;
signal fcs_din : unsigned(7 downto 0);
signal fcs : unsigned(31 downto 0);
signal fcs_chk_OK : std_logic;
type host_state_t is (host_init, host_flush, host_idle);
signal host_s, host_sn : host_state_t;
type xfer_state_t is (xfer_init, xfer_idle, xfer_preamble, xfer_setup, xfer_active, xfer_finish, xfer_commit);
signal xfer_s, xfer_sn : xfer_state_t;
alias cmd_mac_ok_in is cmd_fifo_din(cmd_fifo_din'left);
alias cmd_bcast_in is cmd_fifo_din(cmd_fifo_din'left-1);
alias cmd_pkt_valid_in is cmd_fifo_din(cmd_fifo_din'left-2);
alias cmd_nbytes_in is cmd_fifo_din(word_ptr_t'length-1 downto 0);
alias cmd_base_in is cmd_fifo_din(2*word_ptr_t'length-1 downto word_ptr_t'length);
alias cmd_mac_ok_out is cmd_fifo_dout(cmd_fifo_dout'left);
alias cmd_bcast_out is cmd_fifo_dout(cmd_fifo_dout'left-1);
alias cmd_pkt_valid_out is cmd_fifo_dout(cmd_fifo_dout'left-2);
alias cmd_nbytes_out is cmd_fifo_dout(word_ptr_t'length-1 downto 0);
alias cmd_base_out is cmd_fifo_dout(2*word_ptr_t'length-1 downto word_ptr_t'length);
begin
ctrl_out.rx_size <= resize(cmd_nbytes_out, 16);
ctrl_out.pkt_avail <= not cmd_fifo_empty;
ctrl_out.pkt_valid <= cmd_pkt_valid_out;
ctrl_out.pkt_bcast <= cmd_bcast_out;
ctrl_out.pkt_mac_match <= cmd_mac_ok_out;
ctrl_out.reset_busy <= reset_en;
dout <= ram_dout_b;
ram_en_b <= '1';
ram_addr_b <= host_ptr_next;
ram_en_a <= '1';
ram_din_a <= sipo32_dout;
ram_addr_a <= xfer_ptr;
ram_we_a <= xfer_en and sipo32_dout_vld;
xfer_vld <= (mac_chk_OK or mac_chk_BC or xfer_promiscious) and (not fcs_chk_en or fcs_chk_OK);
cmd_fifo_we <= commit_en and xfer_vld;
cmd_fifo_re <= ctrl_in.pkt_free_en;
cmd_pkt_valid_in <= fcs_chk_OK;
cmd_mac_ok_in <= mac_chk_OK;
cmd_bcast_in <= mac_chk_BC;
cmd_nbytes_in <= byte_count;
cmd_base_in <= xfer_base;
reset_en <= reset_pipe(reset_pipe'left);
------------------------------------------------------------------
reset_gen:
process(clk)
begin
if rising_edge(clk) then
if rst = '1' or ctrl_in.reset = '1' then
reset_pipe <= (others => '1');
else
reset_pipe <= reset_pipe(reset_pipe'left-1 downto 0) & '0';
end if;
end if;
end process;
------------------------------------------------------------------
-- Fill stuff
------------------------------------------------------------------
fill_pointer:
process(clk)
begin
if rising_edge(clk) then
if ctrl_in.pkt_req_en = '1' then
host_ptr <= cmd_base_out;
elsif dout_re = '1' then
host_ptr <= host_ptr_next;
end if;
end if;
end process;
host_ptr_next <= host_ptr + 1 when dout_re = '1' else host_ptr;
------------------------------------------------------------------
-- Transfer stuff
------------------------------------------------------------------
host2xfer_sync_register:
process(mii_rx_clk)
begin
if rising_edge(mii_rx_clk) then
xfer_promiscious <= ctrl_in.promiscious;
Gbps_en <= ctrl_in.Gbps_en;
fcs_chk_en <= ctrl_in.fcs_chk_en;
mac_addr <= ctrl_in.mac_addr;
xfer_ram_limit <= host_ram_limit;
end if;
end process;
host_limit_register:
process(clk)
begin
if rising_edge(clk) then
host_ram_base <= xfer_base;
if cmd_fifo_empty = '1' then
host_ram_limit <= host_ram_base - 1;
else
host_ram_limit <= cmd_base_out - 1;
end if;
end if;
end process;
xfer_ram_full_detect:
process(mii_rx_clk)
begin
if rising_edge(mii_rx_clk) then
if xfer_set = '1' or reset_en = '1' then
xfer_ram_full <= '0';
elsif xfer_en = '1' and sipo32_dout_vld = '1' then
if xfer_ptr = xfer_ram_limit then
xfer_ram_full <= '1';
end if;
end if;
end if;
end process;
xfer_base_logic:
process(mii_rx_clk)
begin
if rising_edge(mii_rx_clk) then
if reset_en = '1' then
xfer_base <= (others => '0');
elsif commit_en = '1' and xfer_vld = '1' then
xfer_base <= xfer_ptr;
end if;
end if;
end process;
xfer_pointer:
process(mii_rx_clk)
begin
if rising_edge(mii_rx_clk) then
if xfer_set = '1' then
xfer_ptr <= xfer_base;
elsif xfer_en = '1' and sipo32_dout_vld = '1' then
xfer_ptr <= xfer_ptr + 1;
end if;
end if;
end process;
------------------------------------------------------------------
byte_counter:
process(mii_rx_clk)
begin
if rising_edge(mii_rx_clk) then
if byte_count_rst = '1' then
if fcs_chk_en = '0' then
byte_count <= to_unsigned(0, RAM_ADDR_WIDTH);
else
byte_count <= unsigned(to_signed(-4, RAM_ADDR_WIDTH));
end if;
elsif sipo32_en = '1' and sipo32_din_vld = '1' then
byte_count <= byte_count + 1;
end if;
end if;
end process;
preamble_sync_logic:
process(mii_rx_clk)
begin
if rising_edge(mii_rx_clk) then
if preamble_en = '0' then
preamble_rdy <= '0';
preamble_bsy <= '0';
preamble_OK <= '0';
elsif sipo32_din_vld = '1' then
if preamble_bsy = '1' then
if sipo32_din = X"D5" then
preamble_OK <= '1';
end if;
end if;
if sipo32_din /= X"55" then
preamble_bsy <= '0';
preamble_rdy <= preamble_bsy;
else
preamble_bsy <= '1';
end if;
end if;
end if;
end process;
mac_check_logic:
process(mii_rx_clk)
begin
if rising_edge(mii_rx_clk) then
if byte_count_rst = '1' then
mac_chk_rdy <= '0';
mac_chk_OK <= '0';
mac_chk_BC <= '0';
mac_chk_cnt <= 0;
mac_chk_num_OK <= 0;
mac_chk_num_BC <= 0;
mac_chk_addr <= mac_addr;
elsif mac_chk_rdy = '1' then
if mac_chk_num_OK = 6 then
mac_chk_OK <= '1';
end if;
if mac_chk_num_BC = 6 then
mac_chk_BC <= '1';
end if;
elsif sipo32_din_vld = '1' and sipo32_en = '1' then
if sipo32_din = mac_chk_addr(mac_chk_cnt) then
mac_chk_num_OK <= mac_chk_num_OK + 1;
end if;
if sipo32_din = X"FF" then
mac_chk_num_BC <= mac_chk_num_BC + 1;
end if;
if mac_chk_cnt /= 5 then
mac_chk_cnt <= mac_chk_cnt + 1;
else
mac_chk_rdy <= '1';
end if;
end if;
end if;
end process;
------------------------------------------------------------------
xfer_state_next:
process(mii_rx_clk)
begin
if rising_edge(mii_rx_clk) then
if reset_en = '1' then
xfer_s <= xfer_init;
else
xfer_s <= xfer_sn;
end if;
end if;
end process;
xfer_state:
process(xfer_s, rx_en, sipo32_dout_en, preamble_bsy, preamble_OK, xfer_ram_full)
begin
commit_en <= '0';
xfer_set <= '0';
xfer_en <= '0';
sipo32_rst <= '0';
sipo32_en <= '0';
byte_count_rst <= '0';
preamble_en <= '0';
xfer_sn <= xfer_s;
case xfer_s is
when xfer_init =>
sipo32_rst <= '1';
if rx_en = '0' then
xfer_sn <= xfer_idle;
end if;
when xfer_idle =>
preamble_en <= rx_en;
if preamble_bsy = '1' then
xfer_sn <= xfer_preamble;
end if;
when xfer_preamble =>
preamble_en <= rx_en;
byte_count_rst <= preamble_bsy;
sipo32_en <= rx_en and not preamble_bsy;
if preamble_bsy = '0' then
xfer_sn <= xfer_init;
if preamble_OK = '1' then
xfer_sn <= xfer_setup;
end if;
end if;
when xfer_setup =>
xfer_set <= '1';
sipo32_en <= rx_en;
xfer_en <= sipo32_dout_en;
xfer_sn <= xfer_active;
when xfer_active =>
xfer_en <= sipo32_dout_en;
sipo32_en <= rx_en;
if xfer_ram_full = '1' then
xfer_sn <= xfer_init;
elsif rx_en = '0' then
xfer_sn <= xfer_finish;
end if;
when xfer_finish =>
xfer_en <= sipo32_dout_en;
if sipo32_dout_en = '0' then
xfer_sn <= xfer_commit;
end if;
when xfer_commit =>
commit_en <= '1';
xfer_sn <= xfer_init;
when others =>
xfer_sn <= xfer_init;
end case;
end process;
------------------------------------------------------------------
-- Instantiate synchronous FIFO
inst_cmd_fifo: entity work.fifo_async
GENERIC MAP
(
addr_width => NextExpBaseTwo(RAM_SIZE) - 4, -- RAMSIZE(words)/MIN_PACKET_LEN(words)
data_width => cmd_fifo_din'length,
do_last_read_update => false
)
PORT MAP
(
rst => reset_en,
clk_w => mii_rx_clk,
clk_r => clk,
we => cmd_fifo_we,
re => cmd_fifo_re,
fifo_full => cmd_fifo_full,
fifo_empty => cmd_fifo_empty,
fifo_afull => open,
fifo_aempty => open,
data_w => cmd_fifo_din,
data_r => cmd_fifo_dout
);
inst_ram : entity work.dpram_1w1r2c_ro
GENERIC MAP
(
addr_width => RAM_ADDR_WIDTH,
data_width => 32
)
PORT MAP
(
clk_a => mii_rx_clk,
clk_b => clk,
en_a => ram_en_a,
en_b => ram_en_b,
we_a => ram_we_a,
addr_a => ram_addr_a,
addr_b => ram_addr_b,
din_a => ram_din_a,
dout_b => ram_dout_b
);
inst_sipo32 : entity work.sipo
GENERIC MAP
(
data_width_in => 8,
data_width_out => 32,
msb_first => true
)
PORT MAP
(
rst => sipo32_rst,
clk => mii_rx_clk,
din_vld => sipo32_din_vld,
din_en => sipo32_en,
din => sipo32_din,
dout_be => sipo32_dout_be,
dout_vld => sipo32_dout_vld,
dout => sipo32_dout,
dout_en => sipo32_dout_en
);
inst_fcs: entity work.crc32
GENERIC MAP
(
crc32_init => X"00000000"
)
PORT MAP
(
rst => byte_count_rst,
clk => mii_rx_clk,
din_vld => fcs_din_vld,
din => fcs_din,
crc32_vld => fcs_vld,
crc32_out => fcs
);
fcs_din <= sipo32_din;
fcs_din_vld <= sipo32_en and sipo32_din_vld;
fcs_chk_register:
process(mii_rx_clk)
begin
if rising_edge(mii_rx_clk) then
if fcs_vld = '1' then
fcs_chk_OK <= '0';
if fcs = X"2144DF1C" then
fcs_chk_OK <= '1';
end if;
end if;
end if;
end process;
mii_input_register:
process(mii_rx_clk)
begin
if rising_edge(mii_rx_clk) then
if Gbps_en = '1' then
sipo32_din <= mii_rx;
sipo32_din_vld <= not mii_rx_er;
rx_en <= mii_rx_dv;
else
sipo32_din <= sipo8_dout;
sipo32_din_vld <= sipo8_dout_vld;
rx_en <= sipo8_dout_en;
end if;
end if;
end process;
inst_sipo_8bit : entity work.sipo
GENERIC MAP
(
data_width_in => 4,
data_width_out => 8,
msb_first => false
)
PORT MAP
(
rst => sipo8_rst,
clk => mii_rx_clk,
din_vld => mii_rx_dv,
din_en => mii_rx_dv,
din => mii_rx(3 downto 0),
dout_be => open,
dout_vld => sipo8_dout_vld,
dout => sipo8_dout,
dout_en => sipo8_dout_en
);
sipo8_rst <= reset_en or not (mii_rx_dv or sipo8_dout_en);
sipo8_en <= not mii_rx_er;
end behavior;
-503
View File
@@ -1,503 +0,0 @@
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
use std.textio.all; -- Imports the standard textio package.
use work.emac_types.all;
use work.utils_pkg.all;
use work.busmaster_types.all;
ENTITY emac_top_jb IS
Generic
(
f_sysclk : real := 100.0;
TX_RAM_SIZE : natural := 2048;
RX_RAM_SIZE : natural := 2048
);
Port
(
-- JBUS Slave
CLK_I : in STD_LOGIC;
RST_I : in STD_LOGIC;
INT_O : out STD_LOGIC;
CYC_I : in STD_LOGIC;
STB_I : in STD_LOGIC;
SEL_I : in unsigned(3 downto 0);
WE_I : in STD_LOGIC;
ACK_O : out STD_LOGIC;
SRDY_O : out STD_LOGIC;
MRDY_I : in STD_LOGIC;
ADDR_I : in unsigned(31 downto 0);
DAT_I : in unsigned(31 downto 0);
DAT_O : out unsigned(31 downto 0);
-- JBUS Master
ACK_I : in std_logic;
SRDY_I : in std_logic;
MDAT_I : in unsigned(31 downto 0);
MDAT_O : out unsigned(31 downto 0);
ADDR_O : out unsigned(31 downto 0);
SEL_O : out unsigned(3 downto 0);
WE_O : out std_logic;
CYC_O : out std_logic;
STB_O : out std_logic;
MRDY_O : out std_logic;
-- MII
mii_rx_clk : in STD_LOGIC;
mii_rx_dv : in STD_LOGIC;
mii_rx_er : in STD_LOGIC;
mii_rx : in unsigned(7 downto 0);
mii_tx_clk : in STD_LOGIC;
mii_tx_en : out STD_LOGIC;
mii_tx_er : out STD_LOGIC;
mii_tx : out unsigned(7 downto 0);
mii_gtx_clk : out STD_LOGIC;
mii_crs : in STD_LOGIC;
mii_col : in STD_LOGIC
);
END emac_top_jb;
ARCHITECTURE behavior OF emac_top_jb IS
-- Constants
constant DMA_NUM_CHANNEL : integer := 2;
constant DMA_CH_WRITE : integer := 0;
constant DMA_CH_READ : integer := 1;
constant DMA_RW_CONF : unsigned(DMA_NUM_CHANNEL-1 downto 0) := "01";
-- Signals for EMAC connections
signal tx_ctrl_in : tx_ctrl_in_t;
signal tx_ctrl_out : tx_ctrl_out_t;
signal tx_din : unsigned(31 downto 0);
signal tx_din_vld : std_logic;
signal rx_ctrl_in : rx_ctrl_in_t;
signal rx_ctrl_out : rx_ctrl_out_t;
signal rx_dout : unsigned(31 downto 0);
signal rx_dout_re : std_logic;
signal rx_int_en : std_logic;
signal tx_int_en : std_logic;
signal irq_rx : std_logic;
signal irq_tx : std_logic;
signal ready : std_logic;
signal read : std_logic;
signal write : std_logic;
signal rx_read_en_CPU : std_logic;
signal rx_req_en_CPU : std_logic;
signal rx_free_en_CPU : std_logic;
signal tx_write_en_CPU : std_logic;
signal reg_read : std_logic;
signal reg_write : std_logic;
signal reg_addr : unsigned(3 downto 0);
-- DMA Controller
signal dma_master_req : unsigned(DMA_NUM_CHANNEL-1 downto 0);
signal dma_master_gnt : unsigned(DMA_NUM_CHANNEL-1 downto 0) := (others => '0');
signal dma_req_rdy : unsigned(DMA_NUM_CHANNEL-1 downto 0);
signal dma_req_en : unsigned(DMA_NUM_CHANNEL-1 downto 0) := (others => '0');
signal dma_req_addr_auto_inc : unsigned(DMA_NUM_CHANNEL-1 downto 0);
type array32_t is array (0 to DMA_NUM_CHANNEL-1) of unsigned(31 downto 0);
signal dma_req_addr : array32_t;
signal dma_req_num_xfers : array32_t;
signal dma_req_complete : unsigned(DMA_NUM_CHANNEL-1 downto 0);
signal dma_req_complete_ack : unsigned(DMA_NUM_CHANNEL-1 downto 0) := (others => '0');
signal dma_start : unsigned(DMA_NUM_CHANNEL-1 downto 0);
signal dma_active : unsigned(DMA_NUM_CHANNEL-1 downto 0);
signal dma_end : unsigned(DMA_NUM_CHANNEL-1 downto 0);
signal dma_bus_cmd_cycle_finished : unsigned(DMA_NUM_CHANNEL-1 downto 0);
signal dma_bus_cmd_cycle_en : unsigned(DMA_NUM_CHANNEL-1 downto 0) := (others => '0');
signal dma_bus_cmd_rdy : unsigned(DMA_NUM_CHANNEL-1 downto 0);
signal dma_bus_cmd_we : unsigned(DMA_NUM_CHANNEL-1 downto 0) := (others => '0');
type array_bus_cmd_t is array (0 to DMA_NUM_CHANNEL-1) of bm_cmd_t;
signal dma_bus_cmd : array_bus_cmd_t;
-- Busmaster arbiter
signal arb_idx : natural range 0 to DMA_NUM_CHANNEL-1;
-- BUS Master controller
signal bus_din_re : std_logic;
signal bus_cmd_cycle_finished : std_logic;
signal bus_cmd_cycle_en : std_logic := '0';
signal bus_cmd_rdy : std_logic;
signal bus_cmd_we : std_logic := '0';
signal bus_cmd : bm_cmd_t;
signal bus_din_rdy : std_logic;
signal bus_din_vld : std_logic := '0';
signal bus_din : unsigned(31 downto 0) := (others => '-');
signal bus_dout : unsigned(31 downto 0);
signal bus_dout_vld : std_logic;
signal bus_dout_re : std_logic := '0';
begin
mii_gtx_clk <= '0';
SRDY_O <= CYC_I and ready;
read <= STB_I and CYC_I and not WE_I;
write <= STB_I and CYC_I and WE_I;
rx_read_en_CPU <= read and ADDR_I(15);
tx_write_en_CPU <= write and ADDR_I(15);
reg_read <= read and not ADDR_I(15);
reg_write <= write and not ADDR_I(15);
reg_addr <= ADDR_I(5 downto 2);
ready <= not tx_ctrl_in.pkt_alloc_en;
tx_din_vld <= tx_write_en_CPU;
tx_din <= DAT_I;
rx_ctrl_in.pkt_free_en <= rx_free_en_CPU or dma_end(0);
rx_ctrl_in.pkt_req_en <= rx_req_en_CPU or dma_start(0);
rx_dout_re <= rx_read_en_CPU or (dma_active(DMA_CH_WRITE) and bus_din_rdy);
bus_din <= rx_dout;
bus_din_vld <= dma_active(DMA_CH_WRITE);
dma_master_gnt(0) <= SRDY_I;
dma_req_en(0) <= rx_ctrl_out.pkt_avail;
dma_req_num_xfers(0) <= X"0000" & "00" & rx_ctrl_out.rx_size(15 downto 2) when rx_ctrl_out.rx_size(1 downto 0) = "00" else X"0000" & "00" & rx_ctrl_out.rx_size(15 downto 2) + 1;
dma_req_addr(0) <= X"00000800";
dma_req_addr_auto_inc <= "11";
------------------------------------------------------------------
registers_write:
process(CLK_I)
begin
if rising_edge(CLK_I) then
tx_ctrl_in.pkt_alloc_en <= '0';
tx_ctrl_in.pkt_commit_en <= '0';
tx_ctrl_in.reset <= '0';
rx_free_en_CPU <= '0';
rx_req_en_CPU <= '0';
rx_ctrl_in.reset <= '0';
if RST_I = '1' then
rx_int_en <= '0';
tx_int_en <= '0';
tx_ctrl_in.tx_size <= (others => '0');
rx_ctrl_in.mac_addr <= (X"03", X"02", X"01", X"00", X"07", X"06");
rx_ctrl_in.promiscious <= '0';
tx_ctrl_in.Gbps_en <= '0';
rx_ctrl_in.Gbps_en <= '0';
tx_ctrl_in.fcs_gen_en <= '0';
rx_ctrl_in.fcs_chk_en <= '0';
elsif reg_write = '1' then
-- 0x0000 .. 0x003C
case reg_addr is
-- 0x0000
when "0000" =>
rx_ctrl_in.reset <= DAT_I(31);
rx_ctrl_in.Gbps_en <= DAT_I(30);
rx_ctrl_in.fcs_chk_en <= DAT_I(29);
rx_ctrl_in.promiscious <= DAT_I(23);
rx_req_en_CPU <= DAT_I(17);
rx_free_en_CPU <= DAT_I(16);
rx_int_en <= DAT_I(4);
-- 0x0004
-- rx_size R/O
-- 0x0008
when "0010" =>
tx_ctrl_in.reset <= DAT_I(31);
tx_ctrl_in.Gbps_en <= DAT_I(30);
tx_ctrl_in.fcs_gen_en <= DAT_I(29);
tx_ctrl_in.pkt_alloc_en <= DAT_I(17);
tx_ctrl_in.pkt_commit_en <= DAT_I(16);
tx_int_en <= DAT_I(4);
-- 0x000C
when "0011" =>
tx_ctrl_in.tx_size <= DAT_I(15 downto 0);
-- 0x0010
-- Gap
-- 0x0014
-- Gap
-- 0x0018
when "0110" =>
rx_ctrl_in.mac_addr(0) <= DAT_I(31 downto 24);
rx_ctrl_in.mac_addr(1) <= DAT_I(23 downto 16);
rx_ctrl_in.mac_addr(2) <= DAT_I(15 downto 8);
rx_ctrl_in.mac_addr(3) <= DAT_I(7 downto 0);
-- 0x001C
when "0111" =>
rx_ctrl_in.mac_addr(4) <= DAT_I(31 downto 24);
rx_ctrl_in.mac_addr(5) <= DAT_I(23 downto 16);
-- 0x0020 .. 0x003C
-- Gap
when others => null;
end case;
end if;
end if;
end process;
registers_read:
process(CLK_I)
begin
if rising_edge(CLK_I) then
ACK_O <= rx_read_en_CPU;
DAT_O <= rx_dout;
if reg_read = '1' then
-- 0x0000 .. 0x003C
case reg_addr is
-- 0x0000
when "0000" =>
ACK_O <= ready;
DAT_O <= (others => '0');
DAT_O(31) <= rx_ctrl_out.reset_busy;
DAT_O(30) <= rx_ctrl_in.Gbps_en;
DAT_O(29) <= rx_ctrl_in.fcs_chk_en;
DAT_O(23) <= rx_ctrl_in.promiscious;
DAT_O(19) <= rx_ctrl_out.pkt_bcast;
DAT_O(18) <= rx_ctrl_out.pkt_mac_match;
DAT_O(17) <= rx_ctrl_out.pkt_valid;
DAT_O(16) <= rx_ctrl_out.pkt_avail;
DAT_O(4) <= rx_int_en;
-- 0x0004
when "0001" =>
ACK_O <= '1';
DAT_O <= X"0000" & rx_ctrl_out.rx_size;
-- 0x0008
when "0010" =>
ACK_O <= ready;
DAT_O <= (others => '0');
DAT_O(31) <= tx_ctrl_out.reset_busy;
DAT_O(30) <= tx_ctrl_in.Gbps_en;
DAT_O(29) <= tx_ctrl_in.fcs_gen_en;
DAT_O(24) <= tx_ctrl_out.pkt_done;
DAT_O(17) <= tx_ctrl_out.pkt_alloc_req;
DAT_O(16) <= tx_ctrl_out.pkt_armed;
DAT_O(4) <= tx_int_en;
-- 0x000C
when "0011" =>
ACK_O <= '1';
DAT_O <= X"0000" & tx_ctrl_out.tx_size;
-- 0x0010
-- Gap
-- 0x0014
-- Gap
-- 0x0018
when "0110" =>
ACK_O <= '1';
DAT_O <= rx_ctrl_in.mac_addr(0) & rx_ctrl_in.mac_addr(1) & rx_ctrl_in.mac_addr(2) & rx_ctrl_in.mac_addr(3);
-- 0x001C
when "0111" =>
ACK_O <= '1';
DAT_O <= rx_ctrl_in.mac_addr(4) & rx_ctrl_in.mac_addr(5) & X"0000";
-- 0x0020 .. 0x003C
-- Gap
when others => null;
end case;
end if;
end if;
end process;
irq_register:
process(CLK_I)
begin
if rising_edge(CLK_I) then
INT_O <= irq_rx or irq_tx;
irq_tx <= tx_int_en and tx_ctrl_out.pkt_done;
irq_rx <= rx_int_en and rx_ctrl_out.pkt_avail;
end if;
end process;
inst_emac_rx : entity work.emac_rx
GENERIC MAP
(
f_sysclk => f_sysclk,
RAM_SIZE => RX_RAM_SIZE
)
PORT MAP
(
clk => CLK_I,
rst => RST_I,
dout_re => rx_dout_re,
dout => rx_dout,
ctrl_in => rx_ctrl_in,
ctrl_out => rx_ctrl_out,
mii_rx_clk => mii_rx_clk,
mii_rx_dv => mii_rx_dv,
mii_rx_er => mii_rx_er,
mii_rx => mii_rx,
mii_crs => mii_crs,
mii_col => mii_col
);
inst_emac_tx : entity work.emac_tx
GENERIC MAP
(
f_sysclk => f_sysclk,
RAM_SIZE => TX_RAM_SIZE
)
PORT MAP
(
clk => CLK_I,
rst => RST_I,
din_vld => tx_din_vld,
din => tx_din,
ctrl_in => tx_ctrl_in,
ctrl_out => tx_ctrl_out,
mii_tx_clk => mii_tx_clk,
mii_tx_en => mii_tx_en,
mii_tx_er => mii_tx_er,
mii_tx => mii_tx
);
gen_dmac:
for i in 0 to DMA_NUM_CHANNEL-1 generate
dma_bus_cmd_cycle_finished(i) <= bus_cmd_cycle_finished;
dma_bus_cmd_rdy(i) <= bus_cmd_rdy;
inst_dmac : entity work.dmac
Generic map
(
DATA_WIDTH => 32,
XFER_CHUNK_SIZE => 32
)
Port map
(
clk => CLK_I,
rst => RST_I,
master_req => dma_master_req(i),
master_gnt => dma_master_gnt(i),
req_rdy => dma_req_rdy(i),
req_en => dma_req_en(i),
req_rw => DMA_RW_CONF(i),
req_addr_auto_inc => dma_req_addr_auto_inc(i),
req_addr_start => dma_req_addr(i),
req_num_xfers => dma_req_num_xfers(i),
req_complete => dma_req_complete(i),
req_complete_ack => dma_req_complete_ack(i),
dma_start => dma_start(i),
dma_active => dma_active(i),
dma_end => dma_end(i),
-- busmaster control
bus_cyc_complete => dma_bus_cmd_cycle_finished(i),
bus_cmd_rdy => dma_bus_cmd_rdy(i),
bus_cmd_we => dma_bus_cmd_we(i),
bus_cmd_cycle_en => dma_bus_cmd_cycle_en(i),
-- busmaster command
bus_cmd_out => dma_bus_cmd(i)
);
end generate;
inst_busmaster_sync : entity work.busmaster_sync
GENERIC MAP
(
DATA_WIDTH => 32,
FIFO_DEPTH => 4
)
PORT MAP
(
-- System signals
rst => RST_I,
clk => CLK_I,
cmd_cycle_finished => bus_cmd_cycle_finished,
cmd_cycle_en => bus_cmd_cycle_en,
cmd_rdy => bus_cmd_rdy,
cmd_we => bus_cmd_we,
cmd_in => bus_cmd,
din_rdy => bus_din_rdy,
din_we => bus_din_vld,
din => bus_din,
dout => bus_dout,
dout_vld => bus_dout_vld,
dout_re => bus_dout_re,
-- JBUS Master signals
CYC_O => CYC_O,
STB_O => STB_O,
WE_O => WE_O,
SEL_O => SEL_O,
ACK_I => ACK_I,
SRDY_I => SRDY_I,
MRDY_O => MRDY_O,
ADDR_O => ADDR_O,
MDAT_I => MDAT_I,
MDAT_O => MDAT_O
);
arbiter_proc:
process(CLK_I)
begin
if rising_edge(CLK_I) then
if RST_I = '1' then
dma_master_gnt <= (others => '0');
arb_idx <= 0;
elsif dma_master_req(arb_idx) = '0' then
if arb_idx /= DMA_NUM_CHANNEL-1 then
arb_idx <= arb_idx + 1;
else
arb_idx <= 0;
end if;
else
dma_master_gnt <= (others => '0');
dma_master_gnt(arb_idx) <= '1';
end if;
end if;
end process;
arbiter_mux:
process(dma_master_gnt, dma_bus_cmd, dma_bus_cmd_we, dma_bus_cmd_cycle_en)
variable v_bus_cmd_we : std_logic;
variable v_bus_cmd_cycle_en : std_logic;
begin
v_bus_cmd_we := '0';
v_bus_cmd_cycle_en := '0';
for i in 0 to DMA_NUM_CHANNEL-1 loop
v_bus_cmd_we := v_bus_cmd_we or dma_bus_cmd_we(i);
v_bus_cmd_cycle_en := v_bus_cmd_cycle_en or dma_bus_cmd_cycle_en(i);
if dma_master_gnt(i) = '1' then
bus_cmd <= dma_bus_cmd(i);
end if;
end loop;
bus_cmd_we <= v_bus_cmd_we;
bus_cmd_cycle_en <= v_bus_cmd_cycle_en;
end process;
end behavior;
-751
View File
@@ -1,751 +0,0 @@
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
use std.textio.all; -- Imports the standard textio package.
use work.emac_types.all;
use work.utils_pkg.all;
ENTITY emac_tx IS
Generic
(
f_sysclk : real := 100.0;
RAM_SIZE : natural := 2048
);
Port
(
clk : in STD_LOGIC;
rst : in STD_LOGIC;
din_vld : in STD_LOGIC;
din : in unsigned(31 downto 0);
ctrl_in : in tx_ctrl_in_t;
ctrl_out : out tx_ctrl_out_t;
mii_tx_clk : in STD_LOGIC;
mii_tx_en : out STD_LOGIC;
mii_tx_er : out STD_LOGIC;
mii_tx : out unsigned(7 downto 0)
);
END emac_tx;
ARCHITECTURE behavior OF emac_tx IS
constant RAM_ADDR_WIDTH : natural := NextExpBaseTwo(RAM_SIZE);
subtype word_ptr_t is unsigned(RAM_ADDR_WIDTH-1 downto 0);
signal cmd_fifo_din : unsigned(2*word_ptr_t'length-1 downto 0);
signal cmd_fifo_dout : unsigned(2*word_ptr_t'length-1 downto 0);
signal cmd_fifo_we : std_logic;
signal cmd_fifo_re : std_logic;
signal cmd_fifo_empty : std_logic;
signal cmd_fifo_full : std_logic;
signal reset_en : std_logic;
signal fill_base : word_ptr_t;
signal fill_size : word_ptr_t;
signal fill_cnt : word_ptr_t;
signal fill_ptr : word_ptr_t;
signal fill_pre_rdy : std_logic;
signal fill_bsy : std_logic;
signal fill_remain : unsigned(1 downto 0);
signal fill_set : std_logic;
signal fill_en : std_logic;
signal fill_cnt_en : std_logic;
signal alloc_OK : std_logic;
signal alloc_req : std_logic;
signal alloc_ack : std_logic;
signal alloc_size : word_ptr_t;
signal alloc_remain : unsigned(1 downto 0);
signal commit_en : std_logic;
signal uncommit_en : std_logic;
signal mem_alloc_en : std_logic;
signal mem_free_en : std_logic;
signal nwords_free : word_ptr_t;
signal mem_free_req : std_logic;
signal mem_free_ack : unsigned(1 downto 0);
signal xfer_size : word_ptr_t;
signal xfer_ptr : word_ptr_t;
signal xfer_cnt : word_ptr_t;
signal xfer_set : std_logic;
signal xfer_en : std_logic;
signal xfer_cnt_en : std_logic;
signal xfer_bsy : std_logic;
signal xfer_free_en : std_logic;
signal ram_en_a : std_logic;
signal ram_we_a : std_logic;
signal ram_addr_a : word_ptr_t;
signal ram_din_a : unsigned(35 downto 0);
signal ram_en_b : std_logic;
signal ram_addr_b : word_ptr_t;
signal ram_dout_b : unsigned(35 downto 0);
signal piso32_din : unsigned(31 downto 0);
signal piso32_din_be : unsigned(3 downto 0);
signal piso32_din_rdy : std_logic;
signal piso32_din_vld : std_logic;
signal piso32_dout : unsigned(7 downto 0);
signal piso32_dout_vld : std_logic;
signal piso32_dout_en : std_logic;
signal piso8_dout_vld : std_logic;
signal piso8_din_rdy : std_logic;
signal piso8_din_vld : std_logic;
signal piso8_dout : unsigned(3 downto 0);
signal piso8_din : unsigned(7 downto 0);
signal reset_pipe : unsigned(31 downto 0);
signal Gbps_en : std_logic;
signal fcs_gen_en : std_logic;
signal fcs_inject_en : std_logic;
signal fcs_rst : std_logic;
signal fcs_en : unsigned(7 downto 0);
signal fcs_vld : std_logic;
signal fcs_din_vld : std_logic;
signal fcs : unsigned(31 downto 0);
signal fcs_rev_endian : unsigned(31 downto 0);
signal mii_fifo_we : std_logic;
signal mii_fifo_re : std_logic;
signal mii_fifo_full : std_logic;
signal mii_fifo_empty : std_logic;
signal mii_fifo_re_dly : unsigned(23 downto 0);
signal mii_bsy : std_logic;
type host_state_t is (host_init, host_idle, host_alloc, host_setup, host_arm, host_fill, host_commit);
signal host_s, host_sn : host_state_t;
type xfer_state_t is (xfer_init, xfer_idle, xfer_start, xfer_preamble0, xfer_preamble1, xfer_active, xfer_crc, xfer_stop, xfer_finish);
signal xfer_s, xfer_sn : xfer_state_t;
type piso_byte_mask_array_t is array (0 to 3) of unsigned (3 downto 0);
constant piso_byte_mask_rom : piso_byte_mask_array_t :=
(
"1111",
"1000",
"1100",
"1110"
);
signal preamble_en : std_logic;
signal preamble_addr : natural range 0 to 1;
type preamble_t is array (0 to 1) of unsigned(31 downto 0);
constant preamble : preamble_t :=
(
X"55555555",
X"555555D5"
);
begin
ctrl_out.pkt_alloc_req <= alloc_req;
ctrl_out.pkt_done <= cmd_fifo_empty;
ctrl_out.reset_busy <= reset_en;
ram_en_a <= din_vld;
ram_we_a <= fill_bsy;
ram_din_a(31 downto 0) <= din;
ram_din_a(35 downto 32) <= piso_byte_mask_rom(to_integer(fill_remain)) when fill_pre_rdy = '1' else "1111";
ram_addr_a <= fill_ptr;
piso32_din <= preamble(preamble_addr) when preamble_en = '1' else fcs_rev_endian when fcs_inject_en = '1' else ram_dout_b(31 downto 0);
piso32_din_be <= "1111" when (preamble_en = '1' or fcs_inject_en = '1') else ram_dout_b(35 downto 32);
cmd_fifo_we <= commit_en;
cmd_fifo_re <= uncommit_en;
cmd_fifo_din <= fill_size & fill_base;
ram_en_b <= piso32_din_rdy;
ram_addr_b <= xfer_ptr;
reset_en <= reset_pipe(reset_pipe'left);
xfer_cnt_en <= xfer_bsy and piso32_din_rdy;
fill_cnt_en <= fill_bsy and din_vld;
mem_free_en <= not mem_free_ack(0) and mem_free_ack(1);
fcs_rev_endian <= fcs(7 downto 0) & fcs(15 downto 8) & fcs(23 downto 16) & fcs(31 downto 24);
------------------------------------------------------------------
reset_gen:
process(clk)
begin
if rising_edge(clk) then
if rst = '1' or ctrl_in.reset = '1' then
reset_pipe <= (others => '1');
else
reset_pipe <= reset_pipe(reset_pipe'left-1 downto 0) & '0';
end if;
end if;
end process;
------------------------------------------------------------------
host_state_next:
process(clk)
begin
if rising_edge(clk) then
if reset_en = '1' then
host_s <= host_init;
else
host_s <= host_sn;
end if;
end if;
end process;
host_state:
process(host_s, alloc_OK, fill_bsy, ctrl_in.pkt_commit_en, alloc_req, mem_free_ack)
begin
fill_set <= '0';
fill_en <= '0';
commit_en <= '0';
alloc_ack <= '0';
mem_alloc_en <= '0';
host_sn <= host_s;
case host_s is
when host_init =>
host_sn <= host_idle;
when host_idle =>
if alloc_req = '1' then
host_sn <= host_alloc;
end if;
when host_alloc =>
if alloc_OK = '1' then
host_sn <= host_setup;
else
host_sn <= host_idle;
alloc_ack <= '1';
end if;
when host_setup =>
fill_set <= '1';
host_sn <= host_arm;
when host_arm =>
fill_en <= '1';
alloc_ack <= '1';
host_sn <= host_fill;
when host_fill =>
fill_en <= '1';
if alloc_req = '1' then
host_sn <= host_alloc;
elsif ctrl_in.pkt_commit_en = '1' then
host_sn <= host_commit;
end if;
when host_commit =>
if mem_free_ack = "00" then
commit_en <= '1';
mem_alloc_en <= '1';
host_sn <= host_idle;
end if;
when others =>
host_sn <= host_idle;
end case;
end process;
------------------------------------------------------------------
-- Allocation stuff
------------------------------------------------------------------
alloc_request_logic:
process(clk)
begin
if rising_edge(clk) then
if reset_en = '1' then
alloc_req <= '0';
elsif ctrl_in.pkt_alloc_en = '1' and alloc_req = '0' then
alloc_req <= '1';
alloc_remain <= ctrl_in.tx_size(1 downto 0);
alloc_size <= ctrl_in.tx_size(word_ptr_t'left+2 downto 2);
if ctrl_in.tx_size(1 downto 0) /= "00" then
alloc_size <= ctrl_in.tx_size(word_ptr_t'left+2 downto 2) + 1;
end if;
ctrl_out.tx_size <= resize(ctrl_in.tx_size(word_ptr_t'left downto 0), 16);
elsif alloc_ack = '1' then
alloc_req <= '0';
end if;
end if;
end process;
------------------------------------------------------------------
host_alloc_armed_register:
process(clk)
begin
if rising_edge(clk) then
if reset_en = '1' or commit_en = '1' then
ctrl_out.pkt_armed <= '0';
elsif alloc_ack = '1' then
ctrl_out.pkt_armed <= alloc_OK;
end if;
end if;
end process;
------------------------------------------------------------------
alloc_eval_logic:
process(clk)
begin
if rising_edge(clk) then
alloc_OK <= '0';
if alloc_size < nwords_free then
alloc_OK <= '1';
end if;
end if;
end process;
------------------------------------------------------------------
fill_base_logic:
process(clk)
begin
if rising_edge(clk) then
if reset_en = '1' then
fill_base <= (others => '0');
elsif commit_en = '1' then
fill_base <= fill_ptr;
end if;
end if;
end process;
------------------------------------------------------------------
mem_free_counter:
process(clk)
begin
if rising_edge(clk) then
if reset_en = '1' then
nwords_free <= (others => '1');
elsif mem_alloc_en = '1' then
nwords_free <= nwords_free - fill_size;
elsif mem_free_en = '1' then
nwords_free <= nwords_free + xfer_size;
end if;
end if;
end process;
------------------------------------------------------------------
mem_free_mii:
process(mii_tx_clk)
begin
if rising_edge(mii_tx_clk) then
if reset_en = '1' then
mem_free_req <= '0';
elsif mem_free_ack(0) = '0' then
if xfer_free_en = '1' then
mem_free_req <= '1';
end if;
else
mem_free_req <= '0';
end if;
end if;
end process;
------------------------------------------------------------------
mem_free_host:
process(clk)
begin
if rising_edge(clk) then
mem_free_ack(1) <= mem_free_ack(0);
if reset_en = '1' then
mem_free_ack <= "00";
elsif mem_free_req = '1' then
if mem_alloc_en = '0' then
mem_free_ack(0) <= '1';
end if;
else
mem_free_ack(0) <= '0';
end if;
end if;
end process;
------------------------------------------------------------------
-- Fill stuff
------------------------------------------------------------------
fill_counter:
process(clk)
begin
if rising_edge(clk) then
if fill_set = '1' then
fill_bsy <= '0';
fill_pre_rdy <= '0';
fill_cnt <= alloc_size;
fill_size <= alloc_size;
fill_remain <= alloc_remain;
elsif fill_en = '1' then
fill_bsy <= '1';
if fill_cnt_en = '1' or fill_bsy = '0' then
if fill_cnt /= 1 then
fill_cnt <= fill_cnt - 1;
else
fill_pre_rdy <= '1';
end if;
if fill_pre_rdy = '1' then
fill_bsy <= '0';
end if;
end if;
end if;
end if;
end process;
------------------------------------------------------------------
fill_pointer:
process(clk)
begin
if rising_edge(clk) then
if fill_set = '1' then
fill_ptr <= fill_base;
elsif fill_cnt_en = '1' then
fill_ptr <= fill_ptr + 1;
end if;
end if;
end process;
------------------------------------------------------------------
-- Transfer stuff
------------------------------------------------------------------
host2xfer_sync_register:
process(mii_tx_clk)
begin
if rising_edge(mii_tx_clk) then
Gbps_en <= ctrl_in.Gbps_en;
fcs_gen_en <= ctrl_in.fcs_gen_en;
end if;
end process;
------------------------------------------------------------------
xfer_counter:
process(mii_tx_clk)
begin
if rising_edge(mii_tx_clk) then
xfer_bsy <= '0';
if xfer_set = '1' then
xfer_cnt <= cmd_fifo_dout(cmd_fifo_dout'left downto word_ptr_t'length);
xfer_size <= (others => '0');
elsif xfer_en = '1' then
xfer_bsy <= '1';
if xfer_cnt_en = '1' or xfer_bsy = '0' then
if xfer_cnt /= 0 then
xfer_cnt <= xfer_cnt - 1;
xfer_size <= xfer_size + 1;
else
xfer_bsy <= '0';
end if;
end if;
end if;
end if;
end process;
------------------------------------------------------------------
xfer_pointer:
process(mii_tx_clk)
begin
if rising_edge(mii_tx_clk) then
if xfer_set = '1' then
xfer_ptr <= cmd_fifo_dout(xfer_ptr'left downto 0);
elsif xfer_en = '1' then
if xfer_bsy = '0' or xfer_cnt_en = '1' then
xfer_ptr <= xfer_ptr + 1;
end if;
end if;
end if;
end process;
------------------------------------------------------------------
xfer_state_next:
process(mii_tx_clk)
begin
if rising_edge(mii_tx_clk) then
if reset_en = '1' then
xfer_s <= xfer_init;
else
xfer_s <= xfer_sn;
end if;
end if;
end process;
xfer_state:
process(xfer_s, mii_bsy, cmd_fifo_empty, piso32_din_rdy, piso32_dout_vld, xfer_bsy, fcs_gen_en)
begin
piso32_din_vld <= '0';
preamble_en <= '0';
preamble_addr <= 0;
xfer_set <= '0';
xfer_en <= '0';
xfer_free_en <= '0';
fcs_rst <= '0';
fcs_inject_en <= '0';
uncommit_en <= '0';
xfer_sn <= xfer_s;
case xfer_s is
when xfer_init =>
xfer_sn <= xfer_idle;
when xfer_idle =>
if cmd_fifo_empty = '0' and mii_bsy = '0' then
xfer_sn <= xfer_start;
end if;
when xfer_start =>
if cmd_fifo_empty = '0' then
xfer_sn <= xfer_preamble0;
end if;
when xfer_preamble0 =>
xfer_set <= '1';
fcs_rst <= '1';
preamble_addr <= 0;
preamble_en <= '1';
piso32_din_vld <= '1';
if piso32_din_rdy = '1' then
xfer_sn <= xfer_preamble1;
end if;
when xfer_preamble1 =>
preamble_addr <= 1;
preamble_en <= '1';
piso32_din_vld <= '1';
if piso32_din_rdy = '1' then
xfer_sn <= xfer_active;
xfer_en <= '1';
end if;
when xfer_active =>
piso32_din_vld <= xfer_bsy;
xfer_en <= '1';
if xfer_bsy = '0' then
xfer_sn <= xfer_stop;
end if;
when xfer_stop =>
if piso32_dout_vld = '0' then
xfer_sn <= xfer_finish;
if fcs_gen_en = '1' then
xfer_sn <= xfer_crc;
end if;
end if;
when xfer_crc =>
fcs_inject_en <= piso32_din_rdy;
piso32_din_vld <= '1';
if piso32_din_rdy = '1' then
xfer_sn <= xfer_finish;
end if;
when xfer_finish =>
uncommit_en <= '1';
xfer_free_en <= '1';
xfer_sn <= xfer_idle;
when others =>
xfer_sn <= xfer_idle;
end case;
end process;
------------------------------------------------------------------
inst_ram : entity work.dpram_1w1r2c_ro
GENERIC MAP
(
addr_width => RAM_ADDR_WIDTH,
data_width => ram_din_a'length
)
PORT MAP
(
clk_a => clk,
clk_b => mii_tx_clk,
en_a => ram_en_a,
en_b => ram_en_b,
we_a => ram_we_a,
addr_a => ram_addr_a,
addr_b => ram_addr_b,
din_a => ram_din_a,
dout_b => ram_dout_b
);
------------------------------------------------------------------
-- Instantiate synchronous FIFO
inst_cmd_fifo: entity work.fifo_async
GENERIC MAP
(
addr_width => NextExpBaseTwo(RAM_SIZE) - 4, -- RAMSIZE(words)/MIN_PACKET_LEN(words)
data_width => cmd_fifo_din'length,
do_last_read_update => true
)
PORT MAP
(
rst => reset_en,
clk_w => clk,
clk_r => mii_tx_clk,
we => cmd_fifo_we,
re => cmd_fifo_re,
fifo_full => cmd_fifo_full,
fifo_empty => cmd_fifo_empty,
fifo_afull => open,
fifo_aempty => open,
data_w => cmd_fifo_din,
data_r => cmd_fifo_dout
);
------------------------------------------------------------------
inst_piso32 : entity work.piso
GENERIC MAP
(
data_width_in => 32,
data_width_out => 8,
msb_first => true
)
PORT MAP
(
rst => reset_en,
clk => mii_tx_clk,
din_vld => piso32_din_vld,
din_rdy => piso32_din_rdy,
din_be => piso32_din_be,
din => piso32_din,
dout_vld => piso32_dout_vld,
dout_en => piso32_dout_en,
dout => piso32_dout
);
piso32_dout_en <= not mii_fifo_full; --'1' when Gbps_en = '1' else piso8_din_rdy;
------------------------------------------------------------------
fcs_enable_gen:
process(mii_tx_clk)
begin
if rising_edge(mii_tx_clk) then
if fcs_rst = '1' then
fcs_en <= (others => '0');
elsif piso32_dout_vld = '1' then
fcs_en <= fcs_en(fcs_en'left-1 downto 0) & '1';
end if;
end if;
end process;
------------------------------------------------------------------
inst_fcs: entity work.crc32
GENERIC MAP
(
crc32_init => X"00000000"
)
PORT MAP
(
rst => fcs_rst,
clk => mii_tx_clk,
din_vld => fcs_din_vld,
din => piso32_dout,
crc32_vld => fcs_vld,
crc32_out => fcs
);
fcs_din_vld <= fcs_en(fcs_en'left) and piso32_dout_vld and piso32_dout_en;
------------------------------------------------------------------
-- ensures continous MII-data stream and also acts as Inter Frame Gap delay
mii_fifo_re_dly_gen:
process(mii_tx_clk)
begin
if rising_edge(mii_tx_clk) then
if mii_fifo_empty = '1' then
if Gbps_en = '0' then
mii_fifo_re_dly <= X"000000"; -- 100 mbps
else
mii_fifo_re_dly <= X"000FFF"; -- Gigabit
end if;
else
mii_fifo_re_dly <= mii_fifo_re_dly(mii_fifo_re_dly'left-1 downto 0) & not mii_fifo_empty;
end if;
end if;
end process;
mii_bsy <= mii_fifo_re_dly(mii_fifo_re_dly'left);
------------------------------------------------------------------
-- Instantiate synchronous FIFO
inst_mii_fifo: entity work.fifo_sync
GENERIC MAP
(
addr_width => 4,
data_width => piso32_dout'length,
do_last_read_update => true
)
PORT MAP
(
rst => reset_en,
clk => mii_tx_clk,
we => mii_fifo_we,
re => mii_fifo_re,
fifo_full => mii_fifo_full,
fifo_empty => mii_fifo_empty,
fifo_afull => open,
fifo_aempty => open,
data_w => piso32_dout,
data_r => piso8_din
);
mii_fifo_re <= mii_bsy when Gbps_en = '1' else (piso8_din_rdy and mii_bsy);
mii_fifo_we <= piso32_dout_vld;
------------------------------------------------------------------
inst_piso8 : entity work.piso
GENERIC MAP
(
data_width_in => 8,
data_width_out => 4,
msb_first => false
)
PORT MAP
(
rst => reset_en,
clk => mii_tx_clk,
din_vld => piso8_din_vld,
din_rdy => piso8_din_rdy,
din_be => "11",
din => piso8_din,
dout_vld => piso8_dout_vld,
dout_en => '1',
dout => piso8_dout
);
piso8_din_vld <= not mii_fifo_empty and mii_bsy;
------------------------------------------------------------------
mii_output_register:
process(mii_tx_clk)
begin
if rising_edge(mii_tx_clk) then
mii_tx_er <= '0';
if Gbps_en = '1' then
mii_tx_en <= piso8_din_vld;
mii_tx <= piso8_din;
else
mii_tx_en <= piso8_dout_vld;
mii_tx <= "0000" & piso8_dout;
end if;
end if;
end process;
------------------------------------------------------------------
end behavior;
-63
View File
@@ -1,63 +0,0 @@
-- Package File Template
--
-- Purpose: This package defines supplemental types, subtypes,
-- constants, and functions
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use IEEE.MATH_REAL.ALL;
package emac_types is
-- Constants
type mac_addr_t is array (0 to 5) of unsigned (7 downto 0);
-- Types
type tx_ctrl_in_t is record
Gbps_en : std_logic;
reset : std_logic;
fcs_gen_en : std_logic;
tx_size : unsigned(15 downto 0);
pkt_commit_en : std_logic;
pkt_alloc_en : std_logic;
end record;
type tx_ctrl_out_t is record
tx_size : unsigned(15 downto 0);
pkt_done : std_logic;
pkt_alloc_req : std_logic;
pkt_armed : std_logic;
reset_busy : std_logic;
end record;
type rx_ctrl_in_t is record
Gbps_en : std_logic;
reset : std_logic;
fcs_chk_en : std_logic;
pkt_req_en : std_logic;
pkt_free_en : std_logic;
mac_addr : mac_addr_t;
promiscious : std_logic;
end record;
type rx_ctrl_out_t is record
pkt_avail : std_logic;
pkt_valid : std_logic;
pkt_bcast : std_logic;
pkt_mac_match : std_logic;
rx_size : unsigned(15 downto 0);
reset_busy : std_logic;
end record;
-- Functions
end emac_types;
package body emac_types is
end emac_types;
-124
View File
@@ -1,124 +0,0 @@
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
use std.textio.all; -- Imports the standard textio package.
use work.utils_pkg.all; -- Imports the standard textio package.
ENTITY piso IS
Generic
(
data_width_in : natural := 32;
data_width_out : natural := 8;
msb_first : boolean := false
);
Port
(
rst : in STD_LOGIC;
clk : in STD_LOGIC;
din_vld : in STD_LOGIC;
din_rdy : out STD_LOGIC;
din_be : in unsigned(data_width_in/data_width_out-1 downto 0);
din : in unsigned(data_width_in-1 downto 0);
dout_vld : out STD_LOGIC;
dout_en : in STD_LOGIC;
dout : out unsigned(data_width_out-1 downto 0)
);
END piso;
ARCHITECTURE behavior OF piso IS
constant num_shifts : natural := data_width_in/data_width_out;
signal pre_fin : STD_LOGIC;
signal shift_cnt_pipe : unsigned(num_shifts-1 downto 0);
signal shift_pipe : unsigned(data_width_in-1 downto 0);
signal vld_pipe : unsigned(num_shifts-1 downto 0);
signal din_reg : unsigned(data_width_in-1 downto 0);
signal din_be_reg : unsigned(num_shifts-1 downto 0);
signal din_reg_empty : STD_LOGIC;
--------------------------------------------------------------------------
begin
pre_fin <= shift_cnt_pipe(shift_cnt_pipe'left-1);
din_rdy <= din_reg_empty;
dout_vld <= vld_pipe(vld_pipe'left) when msb_first else vld_pipe(0);
dout <= shift_pipe(shift_pipe'left downto shift_pipe'left-data_width_out+1) when msb_first
else shift_pipe(data_width_out-1 downto 0);
--------------------------------------------------------------------------
process(clk)
begin
if rising_edge(clk) then
if rst = '1' then
din_reg_empty <= '1';
elsif din_reg_empty = '1' then
if din_vld = '1' then
din_reg_empty <= '0';
end if;
elsif pre_fin = '1' and dout_en = '1' then
din_reg_empty <= '1';
end if;
end if;
end process;
process(clk)
begin
if rising_edge(clk) then
if din_vld = '1' and din_reg_empty = '1' then
din_reg <= din;
din_be_reg <= din_be;
end if;
end if;
end process;
process(clk)
begin
if rising_edge(clk) then
if rst = '1' then
shift_cnt_pipe <= (others => '1');
elsif (pre_fin = '1' and dout_en = '1' and din_reg_empty = '0') then
shift_cnt_pipe <= (others => '0');
elsif dout_en = '1' then
shift_cnt_pipe <= shift_cnt_pipe(shift_cnt_pipe'left-1 downto 0) & '1';
end if;
end if;
end process;
--------------------------------------------------------------------------
process(clk)
begin
if rising_edge(clk) then
if (pre_fin = '1' and dout_en = '1' and din_reg_empty = '0') then
shift_pipe <= din_reg;
elsif dout_en = '1' then
if (msb_first) then
shift_pipe <= shift_pipe(shift_pipe'left-data_width_out downto 0) & (data_width_out-1 downto 0 => '0');
else
shift_pipe <= (data_width_out-1 downto 0 => '0') & shift_pipe(shift_pipe'left downto data_width_out);
end if;
end if;
end if;
end process;
--------------------------------------------------------------------------
process(clk)
begin
if rising_edge(clk) then
if rst = '1' then
vld_pipe <= (others => '0');
elsif (pre_fin = '1' and dout_en = '1' and din_reg_empty = '0') then
vld_pipe <= din_be_reg;
elsif dout_en = '1' then
if (msb_first) then
vld_pipe <= vld_pipe(vld_pipe'left-1 downto 0) & '0';
else
vld_pipe <= '0' & vld_pipe(vld_pipe'left downto 1);
end if;
end if;
end if;
end process;
--------------------------------------------------------------------------
end behavior;
-230
View File
@@ -1,230 +0,0 @@
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
USE IEEE.MATH_REAL.ALL;
use std.textio.all; -- Imports the standard textio package.
use work.emac_types.all;
use work.utils_pkg.all;
ENTITY pkt_gen IS
Generic
(
f_sysclk : real := 100.0;
TX_RAM_SIZE : natural := 2048;
PKT_SIZE_MIN : natural := 64;
PKT_SIZE_MAX : natural := 1518
);
Port
(
clk : in STD_LOGIC;
rst : in STD_LOGIC;
en : in STD_LOGIC;
gigabit_en : in STD_LOGIC;
fcs_gen_en : in STD_LOGIC;
mii_tx_clk : in STD_LOGIC;
mii_tx_en : out STD_LOGIC;
mii_tx_er : out STD_LOGIC;
mii_tx : out unsigned(7 downto 0)
);
END pkt_gen;
ARCHITECTURE behavior OF pkt_gen IS
subtype word_ptr_t is unsigned(15 downto 0);
signal pkt_data : unsigned(31 downto 0);
signal pkt_nbytes : word_ptr_t := X"0040";
signal pkt_nwords : word_ptr_t := X"0010";
signal fill_size : word_ptr_t;
signal fill_cnt : word_ptr_t;
signal fill_rdy : std_logic;
signal fill_set : std_logic;
signal fill_en : std_logic;
signal tx_packets : natural;
signal tx_bytes : natural;
signal tx_ctrl_in : tx_ctrl_in_t;
signal tx_ctrl_out : tx_ctrl_out_t;
signal tx_din : unsigned(31 downto 0);
signal tx_din_vld : std_logic;
type host_state_t is (host_init, host_idle, host_alloc, host_setup, host_arm, host_fill, host_commit);
signal host_s, host_sn : host_state_t;
begin
------------------------------------------------------------------
host_state_next:
process(clk)
begin
if rising_edge(clk) then
if rst = '1' then
host_s <= host_init;
else
host_s <= host_sn;
end if;
end if;
end process;
host_state:
process(host_s, tx_ctrl_out, pkt_nbytes, fill_rdy, en, gigabit_en, fcs_gen_en)
begin
tx_ctrl_in.pkt_alloc_en <= '0';
tx_ctrl_in.pkt_commit_en <= '0';
tx_ctrl_in.reset <= '0';
tx_ctrl_in.Gbps_en <= gigabit_en;
tx_ctrl_in.fcs_gen_en <= fcs_gen_en;
tx_ctrl_in.tx_size <= pkt_nbytes;
fill_set <= '0';
fill_en <= '0';
host_sn <= host_s;
case host_s is
when host_init =>
if tx_ctrl_out.reset_busy = '0' then
host_sn <= host_idle;
end if;
when host_idle =>
if tx_ctrl_out.pkt_alloc_req = '0' and en = '1' then
tx_ctrl_in.pkt_alloc_en <= '1';
host_sn <= host_alloc;
end if;
when host_alloc =>
if tx_ctrl_out.pkt_alloc_req = '0' then
if tx_ctrl_out.pkt_armed = '1' then
host_sn <= host_setup;
else
host_sn <= host_idle;
end if;
end if;
when host_setup =>
fill_set <= '1';
host_sn <= host_fill;
when host_fill =>
fill_en <= '1';
if fill_rdy = '1' then
host_sn <= host_commit;
end if;
when host_commit =>
tx_ctrl_in.pkt_commit_en <= '1';
host_sn <= host_idle;
when others =>
host_sn <= host_idle;
end case;
end process;
------------------------------------------------------------------
pkt_generator:
process(clk)
variable size : word_ptr_t;
variable krand : real;
variable seed1 : integer;
variable seed2 : integer;
begin
if rising_edge(clk) then
if rst = '1' then
size := to_unsigned(PKT_SIZE_MIN, word_ptr_t'length);
seed1 := 31101970;
seed2 := 12586901;
tx_packets <= 0;
tx_bytes <= 0;
elsif tx_ctrl_in.pkt_commit_en = '1' then
uniform(seed1, seed2, krand);
size := to_unsigned(PKT_SIZE_MIN + natural(real(PKT_SIZE_MAX-PKT_SIZE_MIN)*krand), word_ptr_t'length);
tx_packets <= tx_packets + 1;
tx_bytes <= tx_bytes + to_integer(pkt_nbytes);
end if;
pkt_nbytes <= size;
if size(1 downto 0) = 0 then
pkt_nwords <= "00" & size(word_ptr_t'left downto 2);
else
pkt_nwords <= "00" & size(word_ptr_t'left downto 2) + 1;
end if;
end if;
end process;
------------------------------------------------------------------
pkt_data_gen:
process(clk)
variable data : unsigned(7 downto 0);
begin
if rising_edge(clk) then
tx_din_vld <= fill_en;
if fill_set = '1' then
data := X"00";
tx_din <= X"03020100";
elsif fill_en = '1' then
tx_din(7 downto 0) <= data;
data := data + 1;
tx_din(15 downto 8) <= data;
data := data + 1;
tx_din(23 downto 16) <= data;
data := data + 1;
tx_din(31 downto 24) <= data;
data := data + 1;
end if;
end if;
end process;
------------------------------------------------------------------
pkt_data_counter:
process(clk)
begin
if rising_edge(clk) then
if fill_set = '1' then
fill_size <= (others => '0');
fill_rdy <= '0';
fill_cnt <= pkt_nwords;
elsif fill_en = '1' then
if fill_cnt /= 0 then
fill_cnt <= fill_cnt - 1;
fill_size <= fill_size + 1;
else
fill_rdy <= '1';
end if;
end if;
end if;
end process;
------------------------------------------------------------------
inst_emac_tx : entity work.emac_tx
GENERIC MAP
(
f_sysclk => f_sysclk,
RAM_SIZE => TX_RAM_SIZE
)
PORT MAP
(
clk => clk,
rst => rst,
din_vld => tx_din_vld,
din => tx_din,
ctrl_in => tx_ctrl_in,
ctrl_out => tx_ctrl_out,
mii_tx_clk => mii_tx_clk,
mii_tx_en => mii_tx_en,
mii_tx_er => mii_tx_er,
mii_tx => mii_tx
);
end behavior;
-111
View File
@@ -1,111 +0,0 @@
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
use std.textio.all; -- Imports the standard textio package.
use work.utils_pkg.all; -- Imports the standard textio package.
ENTITY shifter IS
Generic
(
data_width : natural := 32;
aggregate_size : natural := 8;
do_pipelined : boolean := true
);
Port
(
rst : in STD_LOGIC;
clk : in STD_LOGIC;
sa : in integer;
din_vld : in STD_LOGIC;
din : in unsigned(data_width-1 downto 0);
dout_vld : out STD_LOGIC;
dout : out unsigned(data_width-1 downto 0)
);
END shifter;
ARCHITECTURE behavior OF shifter IS
constant num_rounds : natural := NextExpBaseTwo(data_width/aggregate_size);
subtype sa_rnd_t is signed(num_rounds-1 downto 0);
subtype word_t is unsigned(data_width-1 downto 0);
type word_array_t is array (0 to num_rounds) of word_t;
signal rot_data : word_array_t;
signal sa_rnd : sa_rnd_t;
type sa_rnd_array_t is array (0 to num_rounds) of sa_rnd_t;
signal sa_rnd_pipe : sa_rnd_array_t;
signal dout_vld_pipe : unsigned(0 to num_rounds);
--------------------------------------------------------------------------
function rol_stage(x : unsigned; en : std_logic; stage_num : natural; size : natural) return unsigned is
variable result : unsigned(x'range);
constant sa : natural := (2**stage_num) * size;
begin
if en = '1' then
result := x(x'left-sa downto 0) & x(x'left downto x'length-sa);
else
result := x;
end if;
return result;
end rol_stage;
--------------------------------------------------------------------------
begin
--------------------------------------------------------------------------
gen_non_pipelined:
if do_pipelined = false generate
begin
rot_data(0) <= din;
gen_rotate_right:
for stage in 0 to num_rounds-1 generate
begin
rot_data(stage+1) <= rol_stage(rot_data(stage), sa_rnd(stage), stage, aggregate_size);
end generate;
sa_rnd <= to_signed(sa, num_rounds);
dout <= rot_data(num_rounds);
dout_vld <= din_vld;
end generate;
--------------------------------------------------------------------------
gen_pipelined:
if do_pipelined = true generate
begin
rot_data(0) <= din;
sa_rnd_pipe(0) <= to_signed(sa, num_rounds);
dout_vld_pipe(0) <= din_vld;
gen_rotate_right:
for stage in 0 to num_rounds-1 generate
begin
process(clk)
begin
if rising_edge(clk) then
if rst = '1' then
dout_vld_pipe(stage+1) <= '0';
else
dout_vld_pipe(stage+1) <= dout_vld_pipe(stage);
if dout_vld_pipe(stage) = '1' then
sa_rnd_pipe(stage+1) <= sa_rnd_pipe(stage);
rot_data(stage+1) <= rol_stage(rot_data(stage), sa_rnd_pipe(stage)(stage), stage, aggregate_size);
end if;
end if;
end if;
end process;
end generate;
dout <= rot_data(num_rounds);
dout_vld <= dout_vld_pipe(num_rounds);
end generate;
--------------------------------------------------------------------------
end behavior;
-118
View File
@@ -1,118 +0,0 @@
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
use std.textio.all; -- Imports the standard textio package.
use work.utils_pkg.all; -- Imports the standard textio package.
ENTITY sipo IS
Generic
(
data_width_in : natural := 8;
data_width_out : natural := 32;
msb_first : boolean := false
);
Port
(
rst : in STD_LOGIC;
clk : in STD_LOGIC;
din_en : in STD_LOGIC;
din_vld : in STD_LOGIC;
din : in unsigned(data_width_in-1 downto 0);
dout_en : out STD_LOGIC;
dout_vld : out STD_LOGIC;
dout : out unsigned(data_width_out-1 downto 0);
dout_be : out unsigned(data_width_out/data_width_in-1 downto 0)
);
END sipo;
ARCHITECTURE behavior OF sipo IS
constant num_shifts : natural := data_width_out/data_width_in;
signal pre_fin : STD_LOGIC;
signal shift_cnt_pipe : unsigned(num_shifts-1 downto 0);
signal shift_pipe : unsigned(data_width_out-1 downto 0);
signal out_en : STD_LOGIC;
signal out_vld : STD_LOGIC;
signal din_vld_r : STD_LOGIC;
signal abort : STD_LOGIC;
--------------------------------------------------------------------------
begin
pre_fin <= shift_cnt_pipe(shift_cnt_pipe'left) when msb_first else shift_cnt_pipe(0);
dout_en <= out_en;
dout_vld <= out_vld;
--------------------------------------------------------------------------
process(clk)
begin
if rising_edge(clk) then
if rst = '1' or pre_fin = '1' then
abort <= '0';
elsif din_vld_r = '1' and din_en = '0' then
abort <= '1';
end if;
end if;
end process;
process(clk)
begin
if rising_edge(clk) then
din_vld_r <= din_vld and din_en;
if rst = '1' then
out_en <= '0';
elsif out_en = '0' then
out_en <= pre_fin and din_en;
elsif out_vld = '1' then
out_en <= din_en;
end if;
end if;
end process;
process(clk)
begin
if rising_edge(clk) then
out_vld <= pre_fin;
if pre_fin = '1' then
dout <= shift_pipe;
dout_be <= shift_cnt_pipe;
end if;
end if;
end process;
process(clk)
begin
if rising_edge(clk) then
if rst = '1' or pre_fin = '1' then
if (msb_first) then
shift_cnt_pipe <= (shift_cnt_pipe'left downto 1 => '0') & (din_en and din_vld);
else
shift_cnt_pipe <= (din_en and din_vld) & (shift_cnt_pipe'left downto 1 => '0');
end if;
elsif din_vld = '1' or abort = '1' then
if (msb_first) then
shift_cnt_pipe <= shift_cnt_pipe(shift_cnt_pipe'left-1 downto 0) & din_en;
else
shift_cnt_pipe <= din_en & shift_cnt_pipe(shift_cnt_pipe'left downto 1);
end if;
end if;
end if;
end process;
process(clk)
begin
if rising_edge(clk) then
if din_vld = '1' or abort = '1' then
if (msb_first) then
shift_pipe <= shift_pipe(shift_pipe'left-data_width_in downto 0) & din;
else
shift_pipe <= din & shift_pipe(shift_pipe'left downto data_width_in);
end if;
end if;
end if;
end process;
--------------------------------------------------------------------------
end behavior;
-106
View File
@@ -1,106 +0,0 @@
-------------------------------------------------------------------------
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
-- This file: testbench for system test using Xilinx ML-402
-- Copyright (C) 2007 J. Ahrensfeld
-- This library is free software; you can redistribute it and/or
-- modify it under the terms of the GNU Lesser General Public
-- License as published by the Free Software Foundation; either
-- version 2.1 of the License, or (at your option) any later version.
-- This library 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
-- Lesser General Public License for more details.
-- You should have received a copy of the GNU Lesser General Public
-- License along with this library; if not, write to the Free Software
-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-- For questions and ideas, please contact the author at jens@jayfield.org
-----------------------------------------------------------------------
LIBRARY ieee;
use IEEE.STD_LOGIC_1164.ALL;
USE ieee.numeric_std.ALL;
ENTITY tb_crc32 IS
END tb_crc32;
ARCHITECTURE behavior OF tb_crc32 IS
constant CLK_PERIOD : time := 10 ns;
signal CLK : std_logic := '1';
signal RST : std_logic := '1';
signal din_vld : std_logic := '0';
signal din : unsigned(7 downto 0) := (others => '-');
signal crc32 : unsigned(31 downto 0);
signal crc32_vld : std_logic;
type byte_array_t is array (0 to 61) of unsigned(7 downto 0);
signal test_data : byte_array_t :=
(
X"00", X"0A", X"E6", X"F0", X"05", X"A3", X"00", X"12",
X"34", X"56", X"78", X"90", X"08", X"00", X"45", X"00",
X"00", X"30", X"B3", X"FE", X"00", X"00", X"80", X"11",
X"72", X"BA", X"0A", X"00", X"00", X"03", X"0A", X"00",
X"00", X"02", X"04", X"00", X"04", X"00", X"00", X"1C",
X"89", X"4D", X"00", X"01", X"02", X"03", X"04", X"05",
X"06", X"07", X"08", X"09", X"0A", X"0B", X"0C", X"0D",
X"0E", X"0F", X"10", X"11", X"12", X"13"
);
BEGIN
inst_crc32: entity work.crc32
PORT MAP
(
rst => RST,
clk => CLK,
din_vld => din_vld,
din => din,
crc32_vld => crc32_vld,
crc32_out => crc32
);
CLK_GEN: process
begin
wait for CLK_PERIOD/2;
CLK <= not CLK;
end process;
-- Master
STIMULUS: process
begin
wait for 6*CLK_PERIOD;
RST <= '0';
wait for 6*CLK_PERIOD;
wait until rising_edge(CLK);
for i in 0 to 61 loop
din_vld <= '1';
din <= test_data(i);
wait until rising_edge(CLK);
end loop;
din <= (others => '-');
din_vld <= '0';
wait;
end process;
END;
-224
View File
@@ -1,224 +0,0 @@
-------------------------------------------------------------------------
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
-- This file: testbench for system test using Xilinx ML-402
-- Copyright (C) 2007 J. Ahrensfeld
-- This library is free software; you can redistribute it and/or
-- modify it under the terms of the GNU Lesser General Public
-- License as published by the Free Software Foundation; either
-- version 2.1 of the License, or (at your option) any later version.
-- This library 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
-- Lesser General Public License for more details.
-- You should have received a copy of the GNU Lesser General Public
-- License along with this library; if not, write to the Free Software
-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-- For questions and ideas, please contact the author at jens@jayfield.org
-----------------------------------------------------------------------
LIBRARY ieee;
use IEEE.STD_LOGIC_1164.ALL;
USE ieee.numeric_std.ALL;
ENTITY tb_serdes IS
END tb_serdes;
ARCHITECTURE behavior OF tb_serdes IS
constant CLK_PERIOD : time := 10 ns;
signal CLK : std_logic := '1';
signal RST : std_logic := '1';
signal piso_din_vld : std_logic := '0';
signal piso_din_rdy : std_logic;
signal piso_din_be : unsigned(3 downto 0) := (others => '0');
signal piso_din : unsigned(31 downto 0) := (others => '-');
signal piso_dout_vld : std_logic;
signal piso_dout : unsigned(7 downto 0);
signal piso_dout_en : std_logic;
signal piso2_din_vld : std_logic := '0';
signal piso2_din_rdy : std_logic;
signal piso2_din_be : unsigned(1 downto 0) := (others => '1');
signal piso2_din : unsigned(7 downto 0) := (others => '-');
signal piso2_dout_vld : std_logic;
signal piso2_dout : unsigned(3 downto 0);
signal piso2_dout_en : std_logic;
signal sipo_enable : std_logic := '0';
signal sipo_rst : std_logic := '0';
signal sipo_din_vld : std_logic := '0';
signal sipo_din : unsigned(7 downto 0) := (others => '-');
signal sipo_dout_vld : std_logic;
signal sipo_dout_en : std_logic;
signal sipo_dout_be : unsigned(3 downto 0);
signal sipo_dout : unsigned(31 downto 0);
signal sipo2_enable : std_logic := '0';
signal sipo2_rst : std_logic := '0';
signal sipo2_din_vld : std_logic := '0';
signal sipo2_din : unsigned(3 downto 0) := (others => '-');
signal sipo2_dout_vld : std_logic;
signal sipo2_dout_en : std_logic;
signal sipo2_dout_be : unsigned(1 downto 0);
signal sipo2_dout : unsigned(7 downto 0);
BEGIN
inst_piso : entity work.piso
GENERIC MAP
(
data_width_in => 32,
data_width_out => 8,
msb_first => true
)
PORT MAP
(
rst => RST,
clk => CLK,
din_vld => piso_din_vld,
din_rdy => piso_din_rdy,
din_be => piso_din_be,
din => piso_din,
dout_vld => piso_dout_vld,
dout_en => piso_dout_en,
dout => piso_dout
);
piso_dout_en <= piso2_din_rdy;
inst_piso2 : entity work.piso
GENERIC MAP
(
data_width_in => 8,
data_width_out => 4,
msb_first => true
)
PORT MAP
(
rst => RST,
clk => CLK,
din_vld => piso2_din_vld,
din_rdy => piso2_din_rdy,
din_be => piso2_din_be,
din => piso2_din,
dout_vld => piso2_dout_vld,
dout_en => piso2_dout_en,
dout => piso2_dout
);
piso2_din_vld <= piso_dout_vld;
piso2_dout_en <= '1';
piso2_din <= piso_dout;
inst_sipo : entity work.sipo
GENERIC MAP
(
data_width_in => 8,
data_width_out => 32,
msb_first => true
)
PORT MAP
(
rst => RST,
clk => CLK,
din_en => sipo_enable,
din_vld => sipo_din_vld,
din => sipo_din,
dout_be => sipo_dout_be,
dout_vld => sipo_dout_vld,
dout => sipo_dout,
dout_en => sipo_dout_en
);
sipo_din <= sipo2_dout;
sipo_din_vld <= sipo2_dout_vld;
sipo_enable <= sipo2_dout_en;
sipo_rst <= RST or not piso2_dout_vld;
inst_sipo2 : entity work.sipo
GENERIC MAP
(
data_width_in => 4,
data_width_out => 8,
msb_first => true
)
PORT MAP
(
rst => RST,
clk => CLK,
din_en => sipo2_enable,
din_vld => sipo2_din_vld,
din => sipo2_din,
dout_be => sipo2_dout_be,
dout_vld => sipo2_dout_vld,
dout => sipo2_dout,
dout_en => sipo2_dout_en
);
sipo2_din <= piso2_dout;
sipo2_din_vld <= piso2_dout_vld;
sipo2_enable <= sipo2_din_vld;
sipo_rst <= RST or not piso2_dout_vld;
CLK_GEN: process
begin
wait for CLK_PERIOD/2;
CLK <= not CLK;
end process;
-- Master
STIMULUS: process
begin
wait for 600*CLK_PERIOD;
RST <= '0';
wait for 60*CLK_PERIOD;
for i in 1 to 10 loop
wait until rising_edge(CLK);
piso_din_vld <= '1';
piso_din <= X"12345678";
piso_din_be <= "1111";
wait until rising_edge(CLK) and piso_din_rdy = '1';
piso_din <= piso_din + X"12345678";
piso_din_be <= "1111";
wait until rising_edge(CLK) and piso_din_rdy = '1';
piso_din <= piso_din + X"12345678";
piso_din_be <= "1111";
wait until rising_edge(CLK) and piso_din_rdy = '1';
piso_din <= piso_din + X"12345678";
piso_din_be <= "1100";
wait until rising_edge(CLK) and piso_din_rdy = '1';
piso_din <= (others => '-');
piso_din_vld <= '0';
wait until rising_edge(CLK) and piso_dout_vld = '0';
-- wait until rising_edge(CLK);
-- wait until rising_edge(CLK) and sipo_dout_vld = '1';
--
wait for 33*CLK_PERIOD;
end loop;
wait;
end process;
END;
-761
View File
@@ -1,761 +0,0 @@
-------------------------------------------------------------------------
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
-- This file: testbench for system test using Xilinx ML-402
-- Copyright (C) 2007 J. Ahrensfeld
-- This library is free software; you can redistribute it and/or
-- modify it under the terms of the GNU Lesser General Public
-- License as published by the Free Software Foundation; either
-- version 2.1 of the License, or (at your option) any later version.
-- This library 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
-- Lesser General Public License for more details.
-- You should have received a copy of the GNU Lesser General Public
-- License along with this library; if not, write to the Free Software
-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-- For questions and ideas, please contact the author at jens@jayfield.org
-----------------------------------------------------------------------
LIBRARY ieee;
use IEEE.STD_LOGIC_1164.ALL;
USE ieee.numeric_std.ALL;
ENTITY tb_emac_top_jb IS
END tb_emac_top_jb;
ARCHITECTURE behavior OF tb_emac_top_jb IS
constant CLK_PERIOD : time := 10 ns;
constant MII_CLK_PERIOD : time := 37.7 ns;
signal CLK : std_logic := '1';
signal RST : std_logic := '1';
-- Slave
signal CYC_I : std_logic := '0';
signal STB_I : std_logic := '0';
signal WE_I : std_logic := '0';
signal SEL_I : unsigned(3 downto 0) := (others => '1');
signal ACK_O : std_logic;
signal INT_O : std_logic;
signal MRDY_I : std_logic := '0';
signal SRDY_O : std_logic;
signal ADDR_I : unsigned(31 downto 0) := (others => '-');
signal DAT_I : unsigned(31 downto 0) := (others => '-');
signal DAT_O : unsigned(31 downto 0) := (others => '-');
signal DAT_O_reg : unsigned(31 downto 0) := (others => '-');
signal status_reg : unsigned(31 downto 0) := (others => '0');
signal size_reg : unsigned(31 downto 0) := (others => '0');
-- Master
signal CYC_O : std_logic;
signal STB_O : std_logic;
signal WE_O : std_logic;
signal SEL_O : unsigned(3 downto 0) := (others => '1');
signal ACK_I : std_logic := '0';
signal MRDY_O : std_logic := '1';
signal SRDY_I : std_logic := '1';
signal ADDR_O : unsigned(31 downto 0) := (others => '-');
signal MDAT_I : unsigned(31 downto 0) := (others => '-');
signal MDAT_O : unsigned(31 downto 0) := (others => '-');
-- MII signals
signal mii_rx_clk_board : std_logic := '1';
signal mii_tx_clk_board : std_logic := '1';
signal mii_rx_clk : std_logic := '1';
signal mii_tx_clk : std_logic := '1';
signal mii_rx : unsigned(7 downto 0) := (others => '-');
signal mii_tx : unsigned(7 downto 0);
signal mii_rx_dv : std_logic := '0';
signal mii_rx_er : std_logic := '0';
signal mii_tx_en : std_logic;
signal mii_tx_er : std_logic;
signal mii_crs : std_logic := '0';
signal mii_col : std_logic := '0';
signal mii_gtx_clk : std_logic;
signal loop_back_en : std_logic := '0';
signal pktgen_tx : unsigned(7 downto 0);
signal pktgen_tx_en : std_logic;
signal pktgen_tx_er : std_logic;
signal pktgen_en : std_logic := '0';
signal pktgen_gigabit : std_logic := '0';
signal pktgen_fcs_en : std_logic := '0';
signal dat_o_cnt_en : std_logic := '0';
signal dat_o_cnt_rst : std_logic := '1';
signal dat_o_cnt : natural;
signal pkt_count : natural;
type emac_action_t is (emac_idle, emac_alloc, emac_write, emac_commit, emac_wait_data, emac_read, emac_free);
signal emac_action : emac_action_t;
constant RX_STATUS_REG_ADDR : unsigned(31 downto 0) := X"0000_0000";
constant RX_SIZE_REG_ADDR : unsigned(31 downto 0) := X"0000_0004";
constant TX_STATUS_REG_ADDR : unsigned(31 downto 0) := X"0000_0008";
constant TX_SIZE_REG_ADDR : unsigned(31 downto 0) := X"0000_000C";
constant DATA_REG_ADDR : unsigned(31 downto 0) := X"0000_8000";
-- 64Bit RAM
signal MDAT_I_64 : unsigned(63 downto 0) := (others => '-');
signal MDAT_O_64 : unsigned(63 downto 0) := (others => '-');
type ram_t is array (0 to 511) of unsigned(63 downto 0);
signal ram64 : ram_t;
BEGIN
MDAT_I <= MDAT_I_64(31 downto 0);
MDAT_O_64 <= MDAT_O & MDAT_O;
process(CLK)
variable res: unsigned(63 downto 0);
variable ram_data : unsigned(63 downto 0);
variable data8: unsigned(7 downto 0);
begin
if rising_edge(CLK) then
if RST = '1' then
data8 := X"00";
for i in 0 to 255 loop
ram_data(7 downto 0) := data8;
data8 := data8 + 1;
ram_data(15 downto 8) := data8;
data8 := data8 + 1;
ram_data(23 downto 16) := data8;
data8 := data8 + 1;
ram_data(31 downto 24) := data8;
data8 := data8 + 1;
ram_data(39 downto 32) := data8;
data8 := data8 + 1;
ram_data(47 downto 40) := data8;
data8 := data8 + 1;
ram_data(55 downto 48) := data8;
data8 := data8 + 1;
ram_data(63 downto 56) := data8;
data8 := data8 + 1;
ram64(i) <= ram_data;
end loop;
else
ACK_I <= '0';
if (CYC_O and STB_O) = '1' then
if WE_O = '0' then
ACK_I <= '1';
ram_data := ram64(to_integer(ADDR_O(31 downto 3)));
if ADDR_O(2) = '0' then
res := ram_data;
else
res := ram_data(31 downto 0) & ram_data(63 downto 32);
end if;
else -- WE=1
ram_data := ram64(to_integer(ADDR_O(31 downto 3)));
-- ram_data := (others => '-');
if ADDR_O(2) = '0' then
if SEL_O = "11111111" then
ram64(to_integer(ADDR_O(31 downto 3))) <= MDAT_O_64;
elsif SEL_O = "00001111" then
ram64(to_integer(ADDR_O(31 downto 3))) <= ram_data(63 downto 32) & MDAT_O_64(31 downto 0);
elsif SEL_O = "11110000" then
ram64(to_integer(ADDR_O(31 downto 3))) <= MDAT_O_64(63 downto 32) & ram_data(31 downto 0);
end if;
else
if SEL_O = "11111111" then
ram64(to_integer(ADDR_O(31 downto 3))) <= MDAT_O_64(31 downto 0) & MDAT_O_64(63 downto 32);
elsif SEL_O = "00001111" then
ram64(to_integer(ADDR_O(31 downto 3))) <= MDAT_O_64(31 downto 0) & ram_data(31 downto 0);
elsif SEL_O = "11110000" then
ram64(to_integer(ADDR_O(31 downto 3))) <= ram_data(63 downto 32) & MDAT_O_64(63 downto 32);
end if;
end if;
end if;
end if;
MDAT_I_64 <= res;
end if;
end if;
end process;
inst_emac_top_jb : entity work.emac_top_jb
GENERIC MAP
(
f_sysclk => 100.0,
RX_RAM_SIZE => 2048,
TX_RAM_SIZE => 2048
)
PORT MAP
(
-- JBUS Slave signals
CLK_I => CLK,
RST_I => RST,
INT_O => INT_O,
CYC_I => CYC_I,
STB_I => STB_I,
SEL_I => SEL_I,
WE_I => WE_I,
ACK_O => ACK_O,
SRDY_O => SRDY_O,
MRDY_I => MRDY_I,
ADDR_I => ADDR_I,
DAT_I => DAT_I,
DAT_O => DAT_O,
-- JBUS Master signals
CYC_O => CYC_O,
STB_O => STB_O,
WE_O => WE_O,
SEL_O => SEL_O,
ACK_I => ACK_I,
SRDY_I => SRDY_I,
MRDY_O => MRDY_O,
ADDR_O => ADDR_O,
MDAT_I => MDAT_I,
MDAT_O => MDAT_O,
mii_rx_clk => mii_rx_clk_board,
mii_rx_dv => mii_rx_dv,
mii_rx_er => mii_rx_er,
mii_rx => mii_rx,
mii_tx_clk => mii_tx_clk_board,
mii_tx_en => mii_tx_en,
mii_tx_er => mii_tx_er,
mii_tx => mii_tx,
mii_gtx_clk => mii_gtx_clk,
mii_crs => mii_crs,
mii_col => mii_col
);
inst_pkt_gen : entity work.pkt_gen
GENERIC MAP
(
f_sysclk => 100.0,
PKT_SIZE_MIN => 64,
PKT_SIZE_MAX => 1512
)
PORT MAP
(
clk => CLK,
rst => RST,
en => pktgen_en,
gigabit_en => pktgen_gigabit,
fcs_gen_en => pktgen_fcs_en,
mii_tx_clk => mii_tx_clk_board,
mii_tx_en => pktgen_tx_en,
mii_tx_er => pktgen_tx_er,
mii_tx => pktgen_tx
);
CLK_GEN: process
begin
wait for CLK_PERIOD/2;
CLK <= not CLK;
end process;
MII_CLK_GEN: process
begin
wait for MII_CLK_PERIOD/2;
mii_rx_clk <= not mii_rx_clk;
mii_tx_clk <= not mii_tx_clk;
end process;
mii_rx_clk_board <= mii_rx_clk;
mii_tx_clk_board <= mii_tx_clk;
DAT_O_register:
process(CLK)
begin
if rising_edge(CLK) then
if ACK_O = '1' then
DAT_O_reg <= DAT_O;
end if;
end if;
end process;
DAT_O_count_register:
process(CLK)
begin
if rising_edge(CLK) then
if dat_o_cnt_rst = '1' then
dat_o_cnt <= 0;
elsif ACK_O = '1' and dat_o_cnt_en = '1' then
dat_o_cnt <= dat_o_cnt + 1;
end if;
end if;
end process;
mii_rx <= mii_tx when loop_back_en = '1' else pktgen_tx;
mii_rx_dv <= mii_tx_en when loop_back_en = '1' else pktgen_tx_en;
mii_rx_er <= mii_tx_er when loop_back_en = '1' else pktgen_tx_er;
mii_crs <= '0';
mii_col <= '0';
-- Master
STIMULUS: process
procedure emac_tx_reset_100mbps is
begin
CYC_I <= '1';
wait until rising_edge(CLK) and SRDY_O = '1';
DAT_I <= X"A000_0000";
STB_I <= '1';
WE_I <= '1';
ADDR_I <= TX_STATUS_REG_ADDR;
wait until rising_edge(CLK) and SRDY_O = '1';
STB_I <= '0';
WE_I <= '0';
end procedure emac_tx_reset_100mbps;
procedure emac_rx_reset_100mbps is
begin
CYC_I <= '1';
wait until rising_edge(CLK) and SRDY_O = '1';
DAT_I <= X"A000_0000";
STB_I <= '1';
WE_I <= '1';
ADDR_I <= RX_STATUS_REG_ADDR;
wait until rising_edge(CLK) and SRDY_O = '1';
STB_I <= '0';
WE_I <= '0';
end procedure emac_rx_reset_100mbps;
procedure emac_tx_reset_1000mbps is
begin
CYC_I <= '1';
wait until rising_edge(CLK) and SRDY_O = '1';
DAT_I <= X"E000_0000";
STB_I <= '1';
WE_I <= '1';
ADDR_I <= TX_STATUS_REG_ADDR;
wait until rising_edge(CLK) and SRDY_O = '1';
STB_I <= '0';
WE_I <= '0';
end procedure emac_tx_reset_1000mbps;
procedure emac_rx_reset_1000mbps is
begin
CYC_I <= '1';
wait until rising_edge(CLK) and SRDY_O = '1';
DAT_I <= X"E000_0000";
STB_I <= '1';
WE_I <= '1';
ADDR_I <= RX_STATUS_REG_ADDR;
wait until rising_edge(CLK) and SRDY_O = '1';
STB_I <= '0';
WE_I <= '0';
end procedure emac_rx_reset_1000mbps;
procedure emac_alloc (size : natural) is
begin
-- TX-ALLOCATION
-- set TX-size
emac_action <= emac_alloc;
CYC_I <= '1';
wait until rising_edge(CLK) and SRDY_O = '1';
DAT_I <= to_unsigned(size, 32);
STB_I <= '1';
WE_I <= '1';
ADDR_I <= TX_SIZE_REG_ADDR;
check_alloc_ok:
while(true) loop
-- set alloc request
wait until rising_edge(CLK) and SRDY_O = '1';
WE_I <= '0';
STB_I <= '1';
ADDR_I <= TX_STATUS_REG_ADDR;
wait until rising_edge(CLK) and SRDY_O = '1';
STB_I <= '0';
wait until rising_edge(CLK) and ACK_O = '1';
status_reg <= DAT_O;
wait until rising_edge(CLK) and SRDY_O = '1';
DAT_I <= X"0002_0000" or (not X"0001_0000" and status_reg);
STB_I <= '1';
WE_I <= '1';
ADDR_I <= TX_STATUS_REG_ADDR;
check_bsy:
while (true) loop
wait until rising_edge(CLK) and SRDY_O = '1';
WE_I <= '0';
STB_I <= '1';
ADDR_I <= TX_STATUS_REG_ADDR;
wait until rising_edge(CLK) and SRDY_O = '1';
STB_I <= '0';
wait until rising_edge(CLK) and ACK_O = '1';
status_reg <= DAT_O;
wait until rising_edge(CLK);
if status_reg(17) = '0' then
exit check_bsy;
end if;
end loop;
if status_reg(16) = '1' then
exit check_alloc_ok;
end if;
end loop;
CYC_I <= '0';
emac_action <= emac_idle;
end procedure emac_alloc;
procedure emac_commit is
begin
-- RX- DEALLOCATION
emac_action <= emac_commit;
-- set free request
CYC_I <= '1';
wait until rising_edge(CLK) and SRDY_O = '1';
WE_I <= '0';
STB_I <= '1';
ADDR_I <= TX_STATUS_REG_ADDR;
wait until rising_edge(CLK) and SRDY_O = '1';
STB_I <= '0';
wait until rising_edge(CLK) and ACK_O = '1';
status_reg <= DAT_O;
wait until rising_edge(CLK) and SRDY_O = '1';
DAT_I <= X"0001_0000" or (not X"0002_0000" and status_reg);
STB_I <= '1';
WE_I <= '1';
ADDR_I <= TX_STATUS_REG_ADDR;
wait until rising_edge(CLK) and SRDY_O = '1';
STB_I <= '0';
WE_I <= '0';
emac_action <= emac_idle;
end procedure emac_commit;
procedure emac_write (size : natural) is
variable data : unsigned (7 downto 0);
variable num_words : natural;
begin
-- FILL TX data
emac_action <= emac_write;
if (size mod 4) = 0 then
num_words := size/4;
else
num_words := size/4 + 1;
end if;
CYC_I <= '1';
wait until rising_edge(CLK) and SRDY_O = '1';
data := X"00";
ADDR_I <= DATA_REG_ADDR;
WE_I <= '1';
for i in 1 to num_words loop
STB_I <= '1';
DAT_I(7 downto 0) <= data;
data := data + 1;
DAT_I(15 downto 8) <= data;
data := data + 1;
DAT_I(23 downto 16) <= data;
data := data + 1;
DAT_I(31 downto 24) <= data;
data := data + 1;
wait until rising_edge(CLK) and SRDY_O = '1';
end loop;
STB_I <= '0';
wait until rising_edge(CLK) and SRDY_O = '1';
emac_commit;
emac_action <= emac_idle;
end procedure emac_write;
procedure emac_read (size_in : natural) is
variable data : unsigned (7 downto 0);
variable size, num_words : natural;
begin
return;
emac_action <= emac_wait_data;
-- check if data available
check_data_avail:
while (true) loop
CYC_I <= '1';
wait until rising_edge(CLK) and SRDY_O = '1';
WE_I <= '0';
STB_I <= '1';
ADDR_I <= RX_STATUS_REG_ADDR;
wait until rising_edge(CLK) and SRDY_O = '1';
STB_I <= '0';
wait until rising_edge(CLK) and ACK_O = '1';
status_reg <= DAT_O;
wait until rising_edge(CLK);
if status_reg(17) = '1' and status_reg(16) = '1' then
exit check_data_avail;
end if;
end loop;
read_size:
dat_o_cnt_rst <= '1';
CYC_I <= '1';
wait until rising_edge(CLK) and SRDY_O = '1';
WE_I <= '0';
STB_I <= '1';
ADDR_I <= RX_SIZE_REG_ADDR;
wait until rising_edge(CLK) and SRDY_O = '1';
STB_I <= '0';
wait until rising_edge(CLK) and ACK_O = '1';
size_reg <= DAT_O;
wait until rising_edge(CLK);
-- set packet request
CYC_I <= '1';
wait until rising_edge(CLK) and SRDY_O = '1';
WE_I <= '0';
STB_I <= '1';
ADDR_I <= RX_STATUS_REG_ADDR;
wait until rising_edge(CLK) and SRDY_O = '1';
STB_I <= '0';
wait until rising_edge(CLK) and ACK_O = '1';
status_reg <= DAT_O;
wait until rising_edge(CLK) and SRDY_O = '1';
DAT_I <= X"0002_0000" or (not X"0001_0000" and status_reg);
STB_I <= '1';
WE_I <= '1';
ADDR_I <= RX_STATUS_REG_ADDR;
wait until rising_edge(CLK) and SRDY_O = '1';
STB_I <= '0';
WE_I <= '0';
emac_action <= emac_read;
-- Read RX data
size := size_in;
if (size_in = 0) then
size := to_integer(size_reg(15 downto 0));
end if;
if (size mod 4) = 0 then
num_words := size/4;
else
num_words := size/4 + 1;
end if;
dat_o_cnt_rst <= '0';
dat_o_cnt_en <= '1';
CYC_I <= '1';
wait until rising_edge(CLK) and SRDY_O = '1';
ADDR_I <= DATA_REG_ADDR;
WE_I <= '0';
STB_I <= '1';
for i in 1 to num_words loop
wait until rising_edge(CLK) and SRDY_O = '1';
end loop;
STB_I <= '0';
wait until rising_edge(CLK) and dat_o_cnt = num_words;
dat_o_cnt_en <= '0';
emac_action <= emac_idle;
end procedure emac_read;
procedure emac_free is
begin
return;
-- RX- DEALLOCATION
emac_action <= emac_free;
-- set free request
CYC_I <= '1';
wait until rising_edge(CLK) and SRDY_O = '1';
WE_I <= '0';
STB_I <= '1';
ADDR_I <= RX_STATUS_REG_ADDR;
wait until rising_edge(CLK) and SRDY_O = '1';
STB_I <= '0';
wait until rising_edge(CLK) and ACK_O = '1';
status_reg <= DAT_O;
wait until rising_edge(CLK) and SRDY_O = '1';
DAT_I <= X"0001_0000" or (not X"0002_0000" and status_reg);
STB_I <= '1';
WE_I <= '1';
ADDR_I <= RX_STATUS_REG_ADDR;
wait until rising_edge(CLK) and SRDY_O = '1';
STB_I <= '0';
WE_I <= '0';
emac_action <= emac_idle;
end procedure emac_free;
begin
wait for 6*MII_CLK_PERIOD;
RST <= '0';
wait for 60*CLK_PERIOD;
emac_rx_reset_100mbps;
emac_tx_reset_100mbps;
pktgen_gigabit <= '0';
pktgen_fcs_en <= '1';
wait for 60*CLK_PERIOD;
emac_alloc (1004);
emac_alloc (1004);
emac_alloc (1004);
emac_alloc (1004);
emac_alloc (1004);
emac_alloc (1004);
emac_alloc (1004);
emac_alloc (1004);
emac_alloc (1004);
emac_alloc (1004);
emac_alloc (1004);
emac_alloc (1004);
for i in 1 to 10 loop
for j in 1 to 100 loop
emac_alloc (72);
emac_write (72);
end loop;
wait for 1 ms;
end loop;
wait until rising_edge(mii_tx_clk) and mii_tx_en = '0';
wait for 6000*CLK_PERIOD;
loop_back_en <= '1';
emac_alloc (74);
emac_write (74);
emac_alloc (105);
emac_write (105);
emac_read (0);
emac_free;
emac_read (0);
emac_free;
emac_alloc (103);
emac_write (103);
emac_read (0);
emac_free;
emac_alloc (71);
emac_write (71);
emac_read (0);
emac_free;
emac_alloc (82);
emac_write (82);
emac_alloc (86);
emac_write (86);
emac_read (0);
emac_free;
emac_read (0);
emac_free;
emac_alloc (77);
emac_write (77);
emac_alloc (99);
emac_write (99);
emac_alloc (65);
emac_write (65);
emac_alloc (321);
emac_write (321);
emac_read (0);
emac_free;
emac_alloc (1111);
emac_write (1111);
emac_read (0);
emac_free;
emac_alloc (73);
emac_write (73);
emac_alloc (107);
emac_write (107);
emac_alloc (83);
emac_write (83);
emac_read (0);
emac_free;
emac_alloc (72);
emac_write (72);
emac_alloc (1003);
emac_write (1003);
emac_read (0);
emac_free;
emac_read (0);
emac_free;
emac_read (0);
emac_free;
emac_read (0);
emac_free;
emac_read (0);
emac_free;
emac_read (0);
emac_free;
emac_read (0);
emac_free;
wait for 6000*CLK_PERIOD;
loop_back_en <= '0';
pktgen_en <= '1';
pkt_count <= 0;
for i in 1 to 500 loop
wait for 1 us;
emac_read (0);
emac_free;
pkt_count <= pkt_count + 1;
end loop;
pktgen_en <= '0';
emac_read (0);
emac_free;
wait;
end process;
END;