mirror of
https://github.com/pConst/basic_verilog.git
synced 2025-01-28 07:02:55 +08:00
739 lines
30 KiB
Plaintext
739 lines
30 KiB
Plaintext
/* Symbol Table */
|
|
// ISR = LABEL: 254
|
|
// ISR_preserve_s0 = CONSTANT: 13
|
|
// ISR_preserve_s1 = CONSTANT: 14
|
|
// ISR_preserve_s2 = CONSTANT: 15
|
|
// LED0 = CONSTANT: 1
|
|
// LED0_sequence = CONSTANT: 16
|
|
// LED1 = CONSTANT: 2
|
|
// LED1_sequence = CONSTANT: 17
|
|
// LED2 = CONSTANT: 4
|
|
// LED2_sequence = CONSTANT: 18
|
|
// LED3 = CONSTANT: 8
|
|
// LED3_sequence = CONSTANT: 19
|
|
// LED4 = CONSTANT: 16
|
|
// LED4_sequence = CONSTANT: 20
|
|
// LED5 = CONSTANT: 32
|
|
// LED5_sequence = CONSTANT: 21
|
|
// LED6 = CONSTANT: 64
|
|
// LED6_sequence = CONSTANT: 22
|
|
// LED7 = CONSTANT: 128
|
|
// LED7_sequence = CONSTANT: 23
|
|
// LED_port = CONSTANT: 128
|
|
// LED_read_port = CONSTANT: 0
|
|
// LED_to_duty = LABEL: 168
|
|
// PWM_channel0 = CONSTANT: 1
|
|
// PWM_channel1 = CONSTANT: 2
|
|
// PWM_channel2 = CONSTANT: 3
|
|
// PWM_channel3 = CONSTANT: 4
|
|
// PWM_channel4 = CONSTANT: 5
|
|
// PWM_channel5 = CONSTANT: 6
|
|
// PWM_channel6 = CONSTANT: 7
|
|
// PWM_channel7 = CONSTANT: 8
|
|
// PWM_duty_counter = CONSTANT: 0
|
|
// all_LED_fade = LABEL: 228
|
|
// all_LED_fade_loop = LABEL: 229
|
|
// authentication_check = LABEL: 182
|
|
// character_A = CONSTANT: 65
|
|
// character_F = CONSTANT: 70
|
|
// character_I = CONSTANT: 73
|
|
// character_L = CONSTANT: 76
|
|
// character_P = CONSTANT: 80
|
|
// character_S = CONSTANT: 83
|
|
// clear_loop = LABEL: 2
|
|
// cold_start = LABEL: 0
|
|
// decay_LEDs = LABEL: 234
|
|
// delay_s0_loop = LABEL: 24
|
|
// delay_s1_loop = LABEL: 23
|
|
// delay_s2_loop = LABEL: 22
|
|
// enable_int = LABEL: 7
|
|
// fail_confirm = LABEL: 203
|
|
// failed_LED_sequence = LABEL: 226
|
|
// go_down = LABEL: 177
|
|
// go_down_loop = LABEL: 178
|
|
// go_up_loop = LABEL: 172
|
|
// inc_LED0 = LABEL: 36
|
|
// inc_LED1 = LABEL: 55
|
|
// inc_LED2 = LABEL: 72
|
|
// inc_LED3 = LABEL: 89
|
|
// inc_LED4 = LABEL: 106
|
|
// inc_LED5 = LABEL: 123
|
|
// inc_LED6 = LABEL: 145
|
|
// inc_LED7 = LABEL: 159
|
|
// link_FIFO_data_present = CONSTANT: 1
|
|
// link_FIFO_full = CONSTANT: 4
|
|
// link_FIFO_half_full = CONSTANT: 2
|
|
// link_FIFO_read_port = CONSTANT: 2
|
|
// link_FIFO_status_port = CONSTANT: 1
|
|
// link_fifo_control_port = CONSTANT: 32
|
|
// link_fifo_reset = CONSTANT: 1
|
|
// normal_LED1 = LABEL: 49
|
|
// normal_LED6 = LABEL: 139
|
|
// normal_LED_sequence = LABEL: 21
|
|
// read_link_FIFO = LABEL: 249
|
|
// request_delay = LABEL: 204
|
|
// s0 = REGISTER: 0
|
|
// s1 = REGISTER: 1
|
|
// s2 = REGISTER: 2
|
|
// s3 = REGISTER: 3
|
|
// s4 = REGISTER: 4
|
|
// s5 = REGISTER: 5
|
|
// s6 = REGISTER: 6
|
|
// s7 = REGISTER: 7
|
|
// s8 = REGISTER: 8
|
|
// s9 = REGISTER: 9
|
|
// sA = REGISTER: 10
|
|
// sB = REGISTER: 11
|
|
// sC = REGISTER: 12
|
|
// sD = REGISTER: 13
|
|
// sE = REGISTER: 14
|
|
// sF = REGISTER: 15
|
|
// security_interrupt = CONSTANT: 1
|
|
// security_request_port = CONSTANT: 64
|
|
// stop_completely = LABEL: 248
|
|
// test_LED0_start = LABEL: 38
|
|
// test_LED1_start = LABEL: 57
|
|
// test_LED2_start = LABEL: 74
|
|
// test_LED3_start = LABEL: 91
|
|
// test_LED4_start = LABEL: 108
|
|
// test_LED5_start = LABEL: 125
|
|
// test_LED6_start = LABEL: 147
|
|
// test_LED7_start = LABEL: 161
|
|
// update_LED0 = LABEL: 41
|
|
// update_LED1 = LABEL: 63
|
|
// update_LED2 = LABEL: 80
|
|
// update_LED3 = LABEL: 97
|
|
// update_LED4 = LABEL: 114
|
|
// update_LED5 = LABEL: 131
|
|
// update_LED6 = LABEL: 150
|
|
// update_LED7 = LABEL: 164
|
|
// wait_s1 = LABEL: 235
|
|
// wait_s2 = LABEL: 236
|
|
// wait_s3 = LABEL: 237
|
|
// warm_start = LABEL: 19
|
|
|
|
/* Program Code */
|
|
// #1: ; KCPSM3 Program - LED control with Pulse Width Modulation (PWM).
|
|
// #2: ;
|
|
// #3: ; Design provided for use with the design 'low_cost_design_authentication_for_spartan_3e.vhd'
|
|
// #4: ; and the Spartan-3E Starter Kit. This design provides the token 'real' application to be
|
|
// #5: ; protected by design authentication.
|
|
// #6: ;
|
|
// #7: ; Ken Chapman - Xilinx Ltd
|
|
// #8: ;
|
|
// #9: ; Version v1.00 - 9th November 2006
|
|
// #10: ;
|
|
// #11: ; This code automatically sequences the LEDs on the board using PWM to change intensity.
|
|
// #12: ; It also checks for correct design authentication and will perform a different sequence if
|
|
// #13: ; the design is not authorised.
|
|
// #14: ;
|
|
// #15: ;
|
|
// #16: ;**************************************************************************************
|
|
// #17: ; NOTICE:
|
|
// #18: ;
|
|
// #19: ; Copyright Xilinx, Inc. 2006. This code may be contain portions patented by other
|
|
// #20: ; third parties. By providing this core as one possible implementation of a standard,
|
|
// #21: ; Xilinx is making no representation that the provided implementation of this standard
|
|
// #22: ; is free from any claims of infringement by any third party. Xilinx expressly
|
|
// #23: ; disclaims any warranty with respect to the adequacy of the implementation, including
|
|
// #24: ; but not limited to any warranty or representation that the implementation is free
|
|
// #25: ; from claims of any third party. Furthermore, Xilinx is providing this core as a
|
|
// #26: ; courtesy to you and suggests that you contact all third parties to obtain the
|
|
// #27: ; necessary rights to use this implementation.
|
|
// #28: ;
|
|
// #29: ;
|
|
// #30: ;**************************************************************************************
|
|
// #31: ; Port definitions
|
|
// #32: ;**************************************************************************************
|
|
// #33: ;
|
|
// #34: ;
|
|
// #35: ;
|
|
// #36: CONSTANT(LED_port,128) ;8 simple LEDs
|
|
// #37: CONSTANT(LED0,1) ; LD0 - bit0
|
|
// #38: CONSTANT(LED1,2) ; LD1 - bit1
|
|
// #39: CONSTANT(LED2,4) ; LD2 - bit2
|
|
// #40: CONSTANT(LED3,8) ; LD3 - bit3
|
|
// #41: CONSTANT(LED4,16) ; LD4 - bit4
|
|
// #42: CONSTANT(LED5,32) ; LD5 - bit5
|
|
// #43: CONSTANT(LED6,64) ; LD6 - bit6
|
|
// #44: CONSTANT(LED7,128) ; LD7 - bit7
|
|
// #45: ;
|
|
// #46: CONSTANT(LED_read_port,0) ;read back of current LED drive values
|
|
// #47: ;
|
|
// #48: ;
|
|
// #49: CONSTANT(security_request_port,64) ;Port to stimulate security KCPSM3 processor
|
|
// #50: CONSTANT(security_interrupt,1) ; interrupt - bit0
|
|
// #51: ;
|
|
// #52: ;
|
|
// #53: ;A FIFO buffer links the security KCPSM3 processor to the application KCPSM3 processor.
|
|
// #54: ; This application processor controls and reads the FIFO.
|
|
// #55: ; The security processor writes to the FIFO.
|
|
// #56: ;
|
|
// #57: CONSTANT(link_fifo_control_port,32) ;FIFO control
|
|
// #58: CONSTANT(link_fifo_reset,1) ; reset - bit0
|
|
// #59: ;
|
|
// #60: CONSTANT(link_FIFO_status_port,1) ;FIFO status input
|
|
// #61: CONSTANT(link_FIFO_data_present,1) ; half full - bit0
|
|
// #62: CONSTANT(link_FIFO_half_full,2) ; full - bit1
|
|
// #63: CONSTANT(link_FIFO_full,4) ; data present - bit2
|
|
// #64: ;
|
|
// #65: CONSTANT(link_FIFO_read_port,2) ;read FIFO data
|
|
// #66: ;
|
|
// #67: ;
|
|
// #68: ;
|
|
// #69: ;**************************************************************************************
|
|
// #70: ; Special Register usage
|
|
// #71: ;**************************************************************************************
|
|
// #72: ;
|
|
// #73: ;
|
|
// #74: ;
|
|
// #75: ;
|
|
// #76: ;**************************************************************************************
|
|
// #77: ;Scratch Pad Memory Locations
|
|
// #78: ;**************************************************************************************
|
|
// #79: ;
|
|
// #80: CONSTANT(PWM_duty_counter,0) ;Duty Counter 0 to 255 within 1KHz period (1ms)
|
|
// #81: CONSTANT(PWM_channel0,1) ;PWM settings for each channel
|
|
// #82: CONSTANT(PWM_channel1,2) ; Channels 0 to 7 = LEDs 0 to 7
|
|
// #83: CONSTANT(PWM_channel2,3)
|
|
// #84: CONSTANT(PWM_channel3,4)
|
|
// #85: CONSTANT(PWM_channel4,5)
|
|
// #86: CONSTANT(PWM_channel5,6)
|
|
// #87: CONSTANT(PWM_channel6,7)
|
|
// #88: CONSTANT(PWM_channel7,8)
|
|
// #89: CONSTANT(ISR_preserve_s0,13) ;preserve register contents during Interrupt Service Routine
|
|
// #90: CONSTANT(ISR_preserve_s1,14)
|
|
// #91: CONSTANT(ISR_preserve_s2,15)
|
|
// #92: ;
|
|
// #93: ;
|
|
// #94: CONSTANT(LED0_sequence,16) ;LED sequence values
|
|
// #95: CONSTANT(LED1_sequence,17)
|
|
// #96: CONSTANT(LED2_sequence,18)
|
|
// #97: CONSTANT(LED3_sequence,19)
|
|
// #98: CONSTANT(LED4_sequence,20)
|
|
// #99: CONSTANT(LED5_sequence,21)
|
|
// #100: CONSTANT(LED6_sequence,22)
|
|
// #101: CONSTANT(LED7_sequence,23)
|
|
// #102: ;
|
|
// #103: ;
|
|
// #104: ;
|
|
// #105: ;**************************************************************************************
|
|
// #106: ;Useful data constants
|
|
// #107: ;**************************************************************************************
|
|
// #108: ;
|
|
// #109: ;
|
|
// #110: ;
|
|
// #111: ;
|
|
// #112: ;
|
|
// #113: ;
|
|
// #114: ;
|
|
// #115: ;**************************************************************************************
|
|
// #116: ;Initialise the system
|
|
// #117: ;**************************************************************************************
|
|
// #118: ;
|
|
// #119: ; All PWM channels initialise to off (zero).
|
|
// #120: ; Simple I/O outputs will remain off at all times.
|
|
// #121: ;
|
|
// @000 #122: [cold_start]
|
|
00000 // @000 #122: LOAD(s0,0)
|
|
00101 // @001 #123: LOAD(s1,PWM_channel0)
|
|
// @002 #124: [clear_loop]
|
|
2f010 // @002 #124: STORE(s0,s1)
|
|
14108 // @003 #125: COMPARE(s1,PWM_channel7)
|
|
35007 // @004 #126: JUMP(Z,enable_int)
|
|
18101 // @005 #127: ADD(s1,1)
|
|
34002 // @006 #128: JUMP(clear_loop)
|
|
// #129: ;
|
|
// @007 #130: [enable_int]
|
|
3c001 // @007 #130: ENABLE(INTERRUPT) ;interrupts used to set PWM frequency
|
|
// #131: ;
|
|
// #132: ;
|
|
// #133: ; Initialise LED pattern sequence
|
|
// #134: ;
|
|
00001 // @008 #135: LOAD(s0,1) ;trigger to start wave pattern
|
|
2e010 // @009 #136: STORE(s0,LED0_sequence)
|
|
00000 // @00a #137: LOAD(s0,0)
|
|
2e011 // @00b #138: STORE(s0,LED1_sequence)
|
|
2e012 // @00c #139: STORE(s0,LED2_sequence)
|
|
2e013 // @00d #140: STORE(s0,LED3_sequence)
|
|
2e014 // @00e #141: STORE(s0,LED4_sequence)
|
|
2e015 // @00f #142: STORE(s0,LED5_sequence)
|
|
2e016 // @010 #143: STORE(s0,LED6_sequence)
|
|
2e017 // @011 #144: STORE(s0,LED7_sequence)
|
|
// #145: ;
|
|
// #146: ;
|
|
// #147: ; Reset authentication check counter
|
|
// #148: ;
|
|
00f00 // @012 #149: LOAD(sF,0)
|
|
// #150: ;
|
|
// #151: ;
|
|
// #152: ;**************************************************************************************
|
|
// #153: ; Main program
|
|
// #154: ;**************************************************************************************
|
|
// #155: ;
|
|
// #156: ; Provides a pattern of interest on the LEDs :-)
|
|
// #157: ;
|
|
// #158: ; Each LED increases intensity in 8 steps and then decreases intensity in 8 steps until it is off.
|
|
// #159: ; The middle LEDs (LD2 to LD5) each start to turn on when either neighbour is turned half on and increasing
|
|
// #160: ; to provide the effect of a passing a 'wave' of light passing from side to side. The pair of LEDs at each
|
|
// #161: ; (LD0, Ld1 and LD6, LD7) are required to reflect the 'wave' so that the pattern continues.
|
|
// #162: ;
|
|
// #163: ; I'm sure this code cold be written in more elegant way, but I leave that as an exercise to you :-)
|
|
// #164: ;
|
|
// #165: ;
|
|
// #166: ; Using a simple software counter (implemented by register sF) the design occasionally requests an
|
|
// #167: ; authorisation message from the authentication processor. If it receives a PASS message it continues
|
|
// #168: ; normally but if it receives a FAIL message the LED pattern is changed.
|
|
// #169: ;
|
|
// #170: ;
|
|
// #171: ;
|
|
// @013 #172: [warm_start]
|
|
18f01 // @013 #172: ADD(sF,1) ;authentication check timer
|
|
358b6 // @014 #173: JUMP(C,authentication_check) ;Check made approximately every 8 seconds.
|
|
// #174: ;
|
|
// @015 #175: [normal_LED_sequence]
|
|
00203 // @015 #175: LOAD(s2,3) ;simple delay loop (delay will be increased by ISR processing)
|
|
// @016 #176: [delay_s2_loop]
|
|
001ff // @016 #176: LOAD(s1,FF)
|
|
// @017 #177: [delay_s1_loop]
|
|
000ff // @017 #177: LOAD(s0,FF)
|
|
// @018 #178: [delay_s0_loop]
|
|
1c001 // @018 #178: SUB(s0,1)
|
|
35c18 // @019 #179: JUMP(NC,delay_s0_loop)
|
|
1c101 // @01a #180: SUB(s1,1)
|
|
35c17 // @01b #181: JUMP(NC,delay_s1_loop)
|
|
1c201 // @01c #182: SUB(s2,1)
|
|
35c16 // @01d #183: JUMP(NC,delay_s2_loop)
|
|
// #184: ;
|
|
// #185: ;Pattern generation
|
|
// #186: ;
|
|
06010 // @01e #187: FETCH(s0,LED0_sequence) ;read sequence for LED0
|
|
14000 // @01f #188: COMPARE(s0,0)
|
|
35026 // @020 #189: JUMP(Z,test_LED0_start)
|
|
1c020 // @021 #190: SUB(s0,32) ;Count longer to ensure end stops then reset count if maximum
|
|
35029 // @022 #191: JUMP(Z,update_LED0)
|
|
18020 // @023 #192: ADD(s0,32)
|
|
// @024 #193: [inc_LED0]
|
|
18001 // @024 #193: ADD(s0,1) ;increment counter
|
|
34029 // @025 #194: JUMP(update_LED0)
|
|
// @026 #195: [test_LED0_start]
|
|
06111 // @026 #195: FETCH(s1,LED1_sequence) ;start LED0 if LED1 = 4
|
|
14104 // @027 #196: COMPARE(s1,4)
|
|
35024 // @028 #197: JUMP(Z,inc_LED0)
|
|
// @029 #198: [update_LED0]
|
|
2e010 // @029 #198: STORE(s0,LED0_sequence)
|
|
300a8 // @02a #199: CALL(LED_to_duty)
|
|
2e101 // @02b #200: STORE(s1,PWM_channel0)
|
|
// #201: ;
|
|
06110 // @02c #202: FETCH(s1,LED0_sequence) ; refresh LED1 if LED0 = 11 (0B hex) to reflect wave
|
|
1410b // @02d #203: COMPARE(s1,11)
|
|
35431 // @02e #204: JUMP(NZ,normal_LED1)
|
|
00004 // @02f #205: LOAD(s0,4)
|
|
3403f // @030 #206: JUMP(update_LED1)
|
|
// @031 #207: [normal_LED1]
|
|
06011 // @031 #207: FETCH(s0,LED1_sequence) ;read sequence for LED1
|
|
14000 // @032 #208: COMPARE(s0,0)
|
|
35039 // @033 #209: JUMP(Z,test_LED1_start)
|
|
1c010 // @034 #210: SUB(s0,16) ;reset count if maximum
|
|
3503f // @035 #211: JUMP(Z,update_LED1)
|
|
18010 // @036 #212: ADD(s0,16)
|
|
// @037 #213: [inc_LED1]
|
|
18001 // @037 #213: ADD(s0,1) ;increment counter
|
|
3403f // @038 #214: JUMP(update_LED1)
|
|
// @039 #215: [test_LED1_start]
|
|
06110 // @039 #215: FETCH(s1,LED0_sequence) ;start LED1 if LED0 = 11 (0B hex) to reflect wave
|
|
1410b // @03a #216: COMPARE(s1,11)
|
|
35037 // @03b #217: JUMP(Z,inc_LED1)
|
|
06112 // @03c #218: FETCH(s1,LED2_sequence) ;start LED1 if LED2 = 4
|
|
14104 // @03d #219: COMPARE(s1,4)
|
|
35037 // @03e #220: JUMP(Z,inc_LED1)
|
|
// @03f #221: [update_LED1]
|
|
2e011 // @03f #221: STORE(s0,LED1_sequence)
|
|
300a8 // @040 #222: CALL(LED_to_duty)
|
|
2e102 // @041 #223: STORE(s1,PWM_channel1)
|
|
// #224: ;
|
|
06012 // @042 #225: FETCH(s0,LED2_sequence) ;read sequence for LED2
|
|
14000 // @043 #226: COMPARE(s0,0)
|
|
3504a // @044 #227: JUMP(Z,test_LED2_start)
|
|
1c010 // @045 #228: SUB(s0,16) ;reset count if maximum
|
|
35050 // @046 #229: JUMP(Z,update_LED2)
|
|
18010 // @047 #230: ADD(s0,16)
|
|
// @048 #231: [inc_LED2]
|
|
18001 // @048 #231: ADD(s0,1) ;increment counter
|
|
34050 // @049 #232: JUMP(update_LED2)
|
|
// @04a #233: [test_LED2_start]
|
|
06111 // @04a #233: FETCH(s1,LED1_sequence) ;start LED2 if LED1 = 4
|
|
14104 // @04b #234: COMPARE(s1,4)
|
|
35048 // @04c #235: JUMP(Z,inc_LED2)
|
|
06113 // @04d #236: FETCH(s1,LED3_sequence) ;start LED2 if LED3 = 4
|
|
14104 // @04e #237: COMPARE(s1,4)
|
|
35048 // @04f #238: JUMP(Z,inc_LED2)
|
|
// @050 #239: [update_LED2]
|
|
2e012 // @050 #239: STORE(s0,LED2_sequence)
|
|
300a8 // @051 #240: CALL(LED_to_duty)
|
|
2e103 // @052 #241: STORE(s1,PWM_channel2)
|
|
// #242: ;
|
|
// #243: ;
|
|
06013 // @053 #244: FETCH(s0,LED3_sequence) ;read sequence for LED3
|
|
14000 // @054 #245: COMPARE(s0,0)
|
|
3505b // @055 #246: JUMP(Z,test_LED3_start)
|
|
1c010 // @056 #247: SUB(s0,16) ;reset count if maximum
|
|
35061 // @057 #248: JUMP(Z,update_LED3)
|
|
18010 // @058 #249: ADD(s0,16)
|
|
// @059 #250: [inc_LED3]
|
|
18001 // @059 #250: ADD(s0,1) ;increment counter
|
|
34061 // @05a #251: JUMP(update_LED3)
|
|
// @05b #252: [test_LED3_start]
|
|
06112 // @05b #252: FETCH(s1,LED2_sequence) ;start LED3 if LED2 = 4
|
|
14104 // @05c #253: COMPARE(s1,4)
|
|
35059 // @05d #254: JUMP(Z,inc_LED3)
|
|
06114 // @05e #255: FETCH(s1,LED4_sequence) ;start LED3 if LED4 = 4
|
|
14104 // @05f #256: COMPARE(s1,4)
|
|
35059 // @060 #257: JUMP(Z,inc_LED3)
|
|
// @061 #258: [update_LED3]
|
|
2e013 // @061 #258: STORE(s0,LED3_sequence)
|
|
300a8 // @062 #259: CALL(LED_to_duty)
|
|
2e104 // @063 #260: STORE(s1,PWM_channel3)
|
|
// #261: ;
|
|
06014 // @064 #262: FETCH(s0,LED4_sequence) ;read sequence for LED4
|
|
14000 // @065 #263: COMPARE(s0,0)
|
|
3506c // @066 #264: JUMP(Z,test_LED4_start)
|
|
1c010 // @067 #265: SUB(s0,16) ;reset count if maximum
|
|
35072 // @068 #266: JUMP(Z,update_LED4)
|
|
18010 // @069 #267: ADD(s0,16)
|
|
// @06a #268: [inc_LED4]
|
|
18001 // @06a #268: ADD(s0,1) ;increment counter
|
|
34072 // @06b #269: JUMP(update_LED4)
|
|
// @06c #270: [test_LED4_start]
|
|
06113 // @06c #270: FETCH(s1,LED3_sequence) ;start LED4 if LED3 = 4
|
|
14104 // @06d #271: COMPARE(s1,4)
|
|
3506a // @06e #272: JUMP(Z,inc_LED4)
|
|
06115 // @06f #273: FETCH(s1,LED5_sequence) ;start LED4 if LED5 = 4
|
|
14104 // @070 #274: COMPARE(s1,4)
|
|
3506a // @071 #275: JUMP(Z,inc_LED4)
|
|
// @072 #276: [update_LED4]
|
|
2e014 // @072 #276: STORE(s0,LED4_sequence)
|
|
300a8 // @073 #277: CALL(LED_to_duty)
|
|
2e105 // @074 #278: STORE(s1,PWM_channel4)
|
|
// #279: ;
|
|
06015 // @075 #280: FETCH(s0,LED5_sequence) ;read sequence for LED5
|
|
14000 // @076 #281: COMPARE(s0,0)
|
|
3507d // @077 #282: JUMP(Z,test_LED5_start)
|
|
1c010 // @078 #283: SUB(s0,16) ;reset count if maximum
|
|
35083 // @079 #284: JUMP(Z,update_LED5)
|
|
18010 // @07a #285: ADD(s0,16)
|
|
// @07b #286: [inc_LED5]
|
|
18001 // @07b #286: ADD(s0,1) ;increment counter
|
|
34083 // @07c #287: JUMP(update_LED5)
|
|
// @07d #288: [test_LED5_start]
|
|
06114 // @07d #288: FETCH(s1,LED4_sequence) ;start LED5 if LED4 = 4
|
|
14104 // @07e #289: COMPARE(s1,4)
|
|
3507b // @07f #290: JUMP(Z,inc_LED5)
|
|
06116 // @080 #291: FETCH(s1,LED6_sequence) ;start LED5 if LED6 = 4
|
|
14104 // @081 #292: COMPARE(s1,4)
|
|
3507b // @082 #293: JUMP(Z,inc_LED5)
|
|
// @083 #294: [update_LED5]
|
|
2e015 // @083 #294: STORE(s0,LED5_sequence)
|
|
300a8 // @084 #295: CALL(LED_to_duty)
|
|
2e106 // @085 #296: STORE(s1,PWM_channel5)
|
|
// #297: ;
|
|
06117 // @086 #298: FETCH(s1,LED7_sequence) ; refresh LED6 if LED7 = 11 (0B hex) to reflect wave
|
|
1410b // @087 #299: COMPARE(s1,11)
|
|
3548b // @088 #300: JUMP(NZ,normal_LED6)
|
|
00004 // @089 #301: LOAD(s0,4)
|
|
34096 // @08a #302: JUMP(update_LED6)
|
|
// @08b #303: [normal_LED6]
|
|
06016 // @08b #303: FETCH(s0,LED6_sequence) ;read sequence for LED6
|
|
14000 // @08c #304: COMPARE(s0,0)
|
|
35093 // @08d #305: JUMP(Z,test_LED6_start)
|
|
1c010 // @08e #306: SUB(s0,16) ;reset count if maximum
|
|
35096 // @08f #307: JUMP(Z,update_LED6)
|
|
18010 // @090 #308: ADD(s0,16)
|
|
// @091 #309: [inc_LED6]
|
|
18001 // @091 #309: ADD(s0,1) ;increment counter
|
|
34096 // @092 #310: JUMP(update_LED6)
|
|
// @093 #311: [test_LED6_start]
|
|
06115 // @093 #311: FETCH(s1,LED5_sequence) ;start LED6 if LED5 = 4
|
|
14104 // @094 #312: COMPARE(s1,4)
|
|
35091 // @095 #313: JUMP(Z,inc_LED6)
|
|
// @096 #314: [update_LED6]
|
|
2e016 // @096 #314: STORE(s0,LED6_sequence)
|
|
300a8 // @097 #315: CALL(LED_to_duty)
|
|
2e107 // @098 #316: STORE(s1,PWM_channel6)
|
|
// #317: ;
|
|
06017 // @099 #318: FETCH(s0,LED7_sequence) ;read sequence for LED7
|
|
14000 // @09a #319: COMPARE(s0,0)
|
|
350a1 // @09b #320: JUMP(Z,test_LED7_start)
|
|
1c020 // @09c #321: SUB(s0,32) ;Count longer to ensure end stops then reset count if maximum
|
|
350a4 // @09d #322: JUMP(Z,update_LED7)
|
|
18020 // @09e #323: ADD(s0,32)
|
|
// @09f #324: [inc_LED7]
|
|
18001 // @09f #324: ADD(s0,1) ;increment counter
|
|
340a4 // @0a0 #325: JUMP(update_LED7)
|
|
// @0a1 #326: [test_LED7_start]
|
|
06116 // @0a1 #326: FETCH(s1,LED6_sequence) ;start LED7 if LED6 = 4
|
|
14104 // @0a2 #327: COMPARE(s1,4)
|
|
3509f // @0a3 #328: JUMP(Z,inc_LED7)
|
|
// @0a4 #329: [update_LED7]
|
|
2e017 // @0a4 #329: STORE(s0,LED7_sequence)
|
|
300a8 // @0a5 #330: CALL(LED_to_duty)
|
|
2e108 // @0a6 #331: STORE(s1,PWM_channel7)
|
|
34013 // @0a7 #332: JUMP(warm_start)
|
|
// #333: ;
|
|
// #334: ;
|
|
// #335: ; Convert LED sequence number into PWM intensity figure
|
|
// #336: ;
|
|
// #337: ; LEDs duty cycle values are 0,1,2,4,8,16,32 and 64 because they appear to give what
|
|
// #338: ; appears to be a fairly liner change in intensity and provides a simple way to set
|
|
// #339: ; the duty value.
|
|
// #340: ;
|
|
// #341: ; Provide sequence value in register s0 and intensity will be
|
|
// #342: ; returned in register s1.
|
|
// #343: ;
|
|
// #344: ; s0 s1
|
|
// #345: ; 00 00
|
|
// #346: ; 01 01
|
|
// #347: ; 02 02
|
|
// #348: ; 03 04
|
|
// #349: ; 04 08
|
|
// #350: ; 05 10
|
|
// #351: ; 06 20
|
|
// #352: ; 07 40
|
|
// #353: ; 08 80
|
|
// #354: ; 09 40
|
|
// #355: ; 0A 20
|
|
// #356: ; 0B 10
|
|
// #357: ; 0C 08
|
|
// #358: ; 0D 04
|
|
// #359: ; 0E 02
|
|
// #360: ; 0F 01
|
|
// #361: ; 10 00 and zero for all larger values of s0
|
|
// #362: ;
|
|
// @0a8 #363: [LED_to_duty]
|
|
00100 // @0a8 #363: LOAD(s1,0)
|
|
14000 // @0a9 #364: COMPARE(s0,0) ;test for zero
|
|
2b000 // @0aa #365: RETURN(Z)
|
|
00101 // @0ab #366: LOAD(s1,1) ;inject '1'
|
|
// @0ac #367: [go_up_loop]
|
|
1c001 // @0ac #367: SUB(s0,1)
|
|
2b000 // @0ad #368: RETURN(Z)
|
|
20106 // @0ae #369: SL0(s1) ;multiply by 2
|
|
358b1 // @0af #370: JUMP(C,go_down)
|
|
340ac // @0b0 #371: JUMP(go_up_loop)
|
|
// @0b1 #372: [go_down]
|
|
00140 // @0b1 #372: LOAD(s1,64)
|
|
// @0b2 #373: [go_down_loop]
|
|
1c001 // @0b2 #373: SUB(s0,1)
|
|
2b000 // @0b3 #374: RETURN(Z)
|
|
2010e // @0b4 #375: SR0(s1) ;divide by 2
|
|
340b2 // @0b5 #376: JUMP(go_down_loop)
|
|
// #377: ;
|
|
// #378: ;
|
|
// #379: ;
|
|
// #380: ;**************************************************************************************
|
|
// #381: ; Authentication Check and fail procedure
|
|
// #382: ;**************************************************************************************
|
|
// #383: ;
|
|
// #384: ; The authentication check is performed by issuing and interrupt to the authentication
|
|
// #385: ; processor and then observing the simple text string that it returns via the link FIFO
|
|
// #386: ; buffer.
|
|
// #387: ;
|
|
// #388: ; PASS - Design is authorised to work.
|
|
// #389: ; FAIL - Design is not authorised and should stop working normally.
|
|
// #390: ;
|
|
// #391: ;
|
|
// #392: ;ASCII character values that are used in messages
|
|
// #393: ;
|
|
// #394: CONSTANT(character_A,65)
|
|
// #395: CONSTANT(character_F,70)
|
|
// #396: CONSTANT(character_I,73)
|
|
// #397: CONSTANT(character_L,76)
|
|
// #398: CONSTANT(character_P,80)
|
|
// #399: CONSTANT(character_S,83)
|
|
// #400: ;
|
|
// #401: ;
|
|
// @0b6 #402: [authentication_check]
|
|
00001 // @0b6 #402: LOAD(s0,link_fifo_reset) ;clear link FIFO to ensure no unexpected characters
|
|
2c020 // @0b7 #403: OUTPUT(s0,link_fifo_control_port)
|
|
00000 // @0b8 #404: LOAD(s0,0)
|
|
2c020 // @0b9 #405: OUTPUT(s0,link_fifo_control_port)
|
|
// #406: ;
|
|
00001 // @0ba #407: LOAD(s0,security_interrupt) ;generate interrupt to authentication processor
|
|
2c040 // @0bb #408: OUTPUT(s0,security_request_port)
|
|
00000 // @0bc #409: LOAD(s0,0)
|
|
2c040 // @0bd #410: OUTPUT(s0,security_request_port)
|
|
// #411: ;
|
|
300f9 // @0be #412: CALL(read_link_FIFO) ;read each character and compare
|
|
14050 // @0bf #413: COMPARE(s0,character_P)
|
|
354cb // @0c0 #414: JUMP(NZ,fail_confirm)
|
|
300f9 // @0c1 #415: CALL(read_link_FIFO)
|
|
14041 // @0c2 #416: COMPARE(s0,character_A)
|
|
354cb // @0c3 #417: JUMP(NZ,fail_confirm)
|
|
300f9 // @0c4 #418: CALL(read_link_FIFO)
|
|
14053 // @0c5 #419: COMPARE(s0,character_S)
|
|
354cb // @0c6 #420: JUMP(NZ,fail_confirm)
|
|
300f9 // @0c7 #421: CALL(read_link_FIFO)
|
|
14053 // @0c8 #422: COMPARE(s0,character_S)
|
|
354cb // @0c9 #423: JUMP(NZ,fail_confirm)
|
|
34015 // @0ca #424: JUMP(normal_LED_sequence) ;Continue normal operation for PASS message
|
|
// #425: ;
|
|
// #426: ;
|
|
// #427: ; To confirm that the authentication is really a FAIL message
|
|
// #428: ; another request is made to the authentication processor and tested.
|
|
// #429: ;
|
|
// @0cb #430: [fail_confirm]
|
|
000ff // @0cb #430: LOAD(s0,FF) ;short delay to ensure authentication processor is ready
|
|
// @0cc #431: [request_delay]
|
|
1c001 // @0cc #431: SUB(s0,1) ; to respond to new interrupt request
|
|
354cc // @0cd #432: JUMP(NZ,request_delay)
|
|
// #433: ;
|
|
00001 // @0ce #434: LOAD(s0,link_fifo_reset) ;clear link FIFO to ensure no unexpected characters
|
|
2c020 // @0cf #435: OUTPUT(s0,link_fifo_control_port)
|
|
00000 // @0d0 #436: LOAD(s0,0)
|
|
2c020 // @0d1 #437: OUTPUT(s0,link_fifo_control_port)
|
|
// #438: ;
|
|
00001 // @0d2 #439: LOAD(s0,security_interrupt) ;generate interrupt to authentication processor
|
|
2c040 // @0d3 #440: OUTPUT(s0,security_request_port)
|
|
00000 // @0d4 #441: LOAD(s0,0)
|
|
2c040 // @0d5 #442: OUTPUT(s0,security_request_port)
|
|
// #443: ;
|
|
300f9 // @0d6 #444: CALL(read_link_FIFO) ;read each character and compare
|
|
14046 // @0d7 #445: COMPARE(s0,character_F)
|
|
35415 // @0d8 #446: JUMP(NZ,normal_LED_sequence)
|
|
300f9 // @0d9 #447: CALL(read_link_FIFO)
|
|
14041 // @0da #448: COMPARE(s0,character_A)
|
|
35415 // @0db #449: JUMP(NZ,normal_LED_sequence)
|
|
300f9 // @0dc #450: CALL(read_link_FIFO)
|
|
14049 // @0dd #451: COMPARE(s0,character_I)
|
|
35415 // @0de #452: JUMP(NZ,normal_LED_sequence)
|
|
300f9 // @0df #453: CALL(read_link_FIFO)
|
|
1404c // @0e0 #454: COMPARE(s0,character_L)
|
|
35415 // @0e1 #455: JUMP(NZ,normal_LED_sequence)
|
|
// #456: ;
|
|
// #457: ;
|
|
// #458: ; When the design fails to authenticate the LEDs will appear to
|
|
// #459: ; turn on and then slowly fade to off using PWM.
|
|
// #460: ;
|
|
// @0e2 #461: [failed_LED_sequence]
|
|
000ff // @0e2 #461: LOAD(s0,FF) ;maximum intensity on all LEDs
|
|
00400 // @0e3 #462: LOAD(s4,0) ;reset fade rate control
|
|
// @0e4 #463: [all_LED_fade]
|
|
00101 // @0e4 #463: LOAD(s1,PWM_channel0)
|
|
// @0e5 #464: [all_LED_fade_loop]
|
|
2f010 // @0e5 #464: STORE(s0,s1)
|
|
14108 // @0e6 #465: COMPARE(s1,PWM_channel7)
|
|
350ea // @0e7 #466: JUMP(Z,decay_LEDs)
|
|
18101 // @0e8 #467: ADD(s1,1)
|
|
340e5 // @0e9 #468: JUMP(all_LED_fade_loop)
|
|
// @0ea #469: [decay_LEDs]
|
|
01140 // @0ea #469: LOAD(s1,s4) ;software delay starts quickly and slows down because LEDs are non-linear.
|
|
// @0eb #470: [wait_s1]
|
|
00218 // @0eb #470: LOAD(s2,24)
|
|
// @0ec #471: [wait_s2]
|
|
003ff // @0ec #471: LOAD(s3,FF)
|
|
// @0ed #472: [wait_s3]
|
|
1c301 // @0ed #472: SUB(s3,1)
|
|
354ed // @0ee #473: JUMP(NZ,wait_s3)
|
|
1c201 // @0ef #474: SUB(s2,1)
|
|
354ec // @0f0 #475: JUMP(NZ,wait_s2)
|
|
1c101 // @0f1 #476: SUB(s1,1)
|
|
354eb // @0f2 #477: JUMP(NZ,wait_s1)
|
|
14000 // @0f3 #478: COMPARE(s0,0) ;test for fully off
|
|
350f8 // @0f4 #479: JUMP(Z,stop_completely)
|
|
1c001 // @0f5 #480: SUB(s0,1) ;fade LEDs
|
|
18401 // @0f6 #481: ADD(s4,1) ;slow fade rate as intensity decreases
|
|
340e4 // @0f7 #482: JUMP(all_LED_fade)
|
|
// #483: ;
|
|
// @0f8 #484: [stop_completely]
|
|
340f8 // @0f8 #484: JUMP(stop_completely)
|
|
// #485: ;
|
|
// #486: ;**************************************************************************************
|
|
// #487: ; Read Byte from Link FIFO
|
|
// #488: ;**************************************************************************************
|
|
// #489: ;
|
|
// #490: ; The routine first tests the FIFO buffer to see if data is present.
|
|
// #491: ; If the FIFO is empty, the routine waits until there is a character to read.
|
|
// #492: ; the read value is returned in register s0.
|
|
// #493: ;
|
|
// #494: ;
|
|
// @0f9 #495: [read_link_FIFO]
|
|
04001 // @0f9 #495: INPUT(s0,link_FIFO_status_port) ;test FIFO buffer
|
|
12001 // @0fa #496: TEST(s0,link_FIFO_data_present) ;wait if empty
|
|
350f9 // @0fb #497: JUMP(Z,read_link_FIFO)
|
|
04002 // @0fc #498: INPUT(s0,link_FIFO_read_port) ;read data from FIFO
|
|
2a000 // @0fd #499: RETURN
|
|
// #500: ;
|
|
// #501: ;
|
|
// #502: ;**************************************************************************************
|
|
// #503: ; Interrupt Service Routine (ISR)
|
|
// #504: ;**************************************************************************************
|
|
// #505: ;
|
|
// #506: ; Interrupts occur at 3.92us intervals and are used to generate the PWM pulses generated
|
|
// #507: ; at a PRF of 1KHz. The 3.92us interrupt rate corresponds with a resolution of 256 steps
|
|
// #508: ; over the 1ms associated with the 1KHz PRF.
|
|
// #509: ;
|
|
// #510: ; The ISR is self contained and all registers used are preserved. Scratch pad memory
|
|
// #511: ; locations are used to determine the desired duty factor for each of 8 channels.
|
|
// #512: ;
|
|
// #513: ; Note that an interrupt is generated every 196 clock cycles. This means that there is
|
|
// #514: ; only time to execute 98 instructions between each interrupt. This ISR is 35 instructions
|
|
// #515: ; long. A further 3 instructions are also consumed by the interrupt process
|
|
// #516: ; (abandoned instruction, virtual CALL to 3FF and the interrupt vector JUMP) and hence
|
|
// #517: ; PicoBlaze has approximately 63% of its time available for other tasks in the main program.
|
|
// #518: ;
|
|
// #519: ; Although a loop would normal be employed in software to process each of 8 channels,
|
|
// #520: ; the implementation of a loop would increase the number of instructions which needed to
|
|
// #521: ; be executed significantly reduce the time available for the main program to operate.
|
|
// #522: ; Consequently the code is written out in a linear fashion which consumes more program
|
|
// #523: ; space but which executes faster.
|
|
// #524: ;
|
|
// @0fe #525: [ISR]
|
|
2e00d // @0fe #525: STORE(s0,ISR_preserve_s0) ;preserve registers to be used
|
|
2e10e // @0ff #526: STORE(s1,ISR_preserve_s1)
|
|
2e20f // @100 #527: STORE(s2,ISR_preserve_s2)
|
|
// #528: ;Determine the number of steps currently through the 1ms PWM cycle
|
|
06100 // @101 #529: FETCH(s1,PWM_duty_counter) ;read 8-bit counter of steps
|
|
18101 // @102 #530: ADD(s1,1) ;increment counter (will roll over to zero)
|
|
2e100 // @103 #531: STORE(s1,PWM_duty_counter) ;update count value in memory for next interrupt.
|
|
// #532: ;Read duty factor for each channel and compare it with the duty counter and set or
|
|
// #533: ;reset a bit in register s2 accordingly.
|
|
06008 // @104 #534: FETCH(s0,PWM_channel7) ;read desired setting of pulse width
|
|
15100 // @105 #535: COMPARE(s1,s0) ;set carry flag if duty factor > duty counter
|
|
20200 // @106 #536: SLA(s2) ;shift carry into register s2
|
|
06007 // @107 #537: FETCH(s0,PWM_channel6) ;read desired setting of pulse width
|
|
15100 // @108 #538: COMPARE(s1,s0) ;set carry flag if duty factor > duty counter
|
|
20200 // @109 #539: SLA(s2) ;shift carry into register s2
|
|
06006 // @10a #540: FETCH(s0,PWM_channel5) ;read desired setting of pulse width
|
|
15100 // @10b #541: COMPARE(s1,s0) ;set carry flag if duty factor > duty counter
|
|
20200 // @10c #542: SLA(s2) ;shift carry into register s2
|
|
06005 // @10d #543: FETCH(s0,PWM_channel4) ;read desired setting of pulse width
|
|
15100 // @10e #544: COMPARE(s1,s0) ;set carry flag if duty factor > duty counter
|
|
20200 // @10f #545: SLA(s2) ;shift carry into register s2
|
|
06004 // @110 #546: FETCH(s0,PWM_channel3) ;read desired setting of pulse width
|
|
15100 // @111 #547: COMPARE(s1,s0) ;set carry flag if duty factor > duty counter
|
|
20200 // @112 #548: SLA(s2) ;shift carry into register s2
|
|
06003 // @113 #549: FETCH(s0,PWM_channel2) ;read desired setting of pulse width
|
|
15100 // @114 #550: COMPARE(s1,s0) ;set carry flag if duty factor > duty counter
|
|
20200 // @115 #551: SLA(s2) ;shift carry into register s2
|
|
06002 // @116 #552: FETCH(s0,PWM_channel1) ;read desired setting of pulse width
|
|
15100 // @117 #553: COMPARE(s1,s0) ;set carry flag if duty factor > duty counter
|
|
20200 // @118 #554: SLA(s2) ;shift carry into register s2
|
|
06001 // @119 #555: FETCH(s0,PWM_channel0) ;read desired setting of pulse width
|
|
15100 // @11a #556: COMPARE(s1,s0) ;set carry flag if duty factor > duty counter
|
|
20200 // @11b #557: SLA(s2) ;shift carry into register s2
|
|
2c280 // @11c #558: OUTPUT(s2,LED_port) ;drive LEDs
|
|
0600d // @11d #559: FETCH(s0,ISR_preserve_s0) ;restore register values
|
|
0610e // @11e #560: FETCH(s1,ISR_preserve_s1)
|
|
0620f // @11f #561: FETCH(s2,ISR_preserve_s2)
|
|
38001 // @120 #562: RETURNI(ENABLE)
|
|
// #563: ;
|
|
// #564: ;
|
|
// #565: ;**************************************************************************************
|
|
// #566: ; Interrupt Vector
|
|
// #567: ;**************************************************************************************
|
|
// #568: ;
|
|
@3ff // #569: ADDRESS(1023)
|
|
340fe // @3ff #570: JUMP(ISR)
|
|
// #571: ;
|
|
// #572: ;
|