目次
前
次
乱数生成
実験のための乱数が必要になったので、擬似乱数と
してシフトレジスタを利用する、LFSRを採用して
みました。
LFSRは、Linear Feedback Shift Registerの略で
2のべき乗のレジスタの指定ビット間で、排他的
論理和を求め、レジスタのLSBとしていきます。
今回は、次の処理でQ30とQ27の排他的論理和を求めて
擬似乱数を生成しました。
32ビット必要なので、汎用レジスタのr0からr3で
ひとつのレジスタを構成して対応。
32ビットのレジスタを用意して、初期化しておきます。
汎用レジスタに初期値を格納して対応。
INIT_REG:
;+++ low byte +++
mov r0,#0AFH
;+++ middle byte +++
mov r1,#50H
;+++ high byte +++
mov r2,#05H
;+++ extra byte +++
mov r3,#34H
ret
排他的論理和を求めるには、回転とスワップ命令を
利用して実現します。
; calculate feedback value = Q27 XOR Q30 and put in carry flag:
mov a,r3 ; Q27 --> x.7 (Q31 Q30 Q29 Q28 / Q27 Q26 Q25 Q24)
; get Q30
rl a
anl a,#80H ; get MSB
mov r4,a ; store MSB(Q30)
mov a,r3 ; Q27 --> x.7 (Q31 Q30 Q29 Q28 / Q27 Q26 Q25 Q24)
swap a ; Q27 Q26 Q25 Q24 / Q31 Q30 Q29 Q28
anl a,#80H ; get MSB
xrl a,r4
この動作を図解すると、以下。
8048には、シフト命令がないので回転命令で代用。
排他的論理和の結果を、キャリーフラグに入れるため
JB7命令を使って判定を簡単にます。
; clear carry flag
clr c
; judge
xrl a,r4 ; Q30 XOR Q27
jb7 MAIN1
jmp MAIN2
; set carry flag
MAIN1:
cpl c
MAIN2:
キャリーの中に排他的論理和を格納したなら
キャリーを含めて回転命令でシフトしていけば
LFSRが完成します。
ソースコードは、以下。
; LFSR(Linear Feedback Shift Register)
;
INCLUDE 8048.LIB
;****************
; define symbols
;****************
ENTRY equ 0h
E_INT equ 3h
E_TIM equ 7h
;*******************
; interrupt vectors
;*******************
org ENTRY
jmp START
; external interrupt
org E_INT
retr
; timer interrupt
org E_TIM
retr
org 10h
;**************
; sub routines
;**************
INIT:
; disable external interrupt
dis i
; disable timer interrupt
dis tcnti
; initialize I/O
clr a
outl P1,a
outl P2,a
ret
INIT_REG:
;+++ low byte +++
mov r0,#0AFH
;+++ middle byte +++
mov r1,#50H
;+++ high byte +++
mov r2,#05H
;+++ extra byte +++
mov r3,#34H
ret
;**************
; main routine
;**************
org 100h
START:
call INIT
call INIT_REG
MAIN:
; calculate feedback value = Q27 XOR Q30 and put in carry flag:
mov a,r3 ; Q27 --> x.7 (Q31 Q30 Q29 Q28 / Q27 Q26 Q25 Q24)
; get Q30
rl a
anl a,#80H ; get MSB
mov r4,a ; store MSB(Q30)
mov a,r3 ; Q27 --> x.7 (Q31 Q30 Q29 Q28 / Q27 Q26 Q25 Q24)
swap a ; Q27 Q26 Q25 Q24 / Q31 Q30 Q29 Q28
anl a,#80H ; get MSB
; clear carry flag
clr c
; judge
xrl a,r4 ; Q30 XOR Q27
jb7 MAIN1
jmp MAIN2
; set carry flag
MAIN1:
cpl c
MAIN2:
; rotate left (XRND0)
mov a,r0
rlc a
mov r0,a
; rotate left (XRND1)
mov a,r1
rlc a
mov r1,a
; rotate left (XRND2)
mov a,r2
rlc a
mov r2,a
; rotate left (XRND3)
mov a,r3
rlc a
mov r3,a
; copy r0 (XRND0)
mov a,r0
; impress
outl P1,a
;
jmp MAIN
end
機械語との対応は、以下。
0000 ;
0000 ; LFSR(Linear Feedback Shift Register)
0000 ;
0000 INCLUDE 8048.LIB
0000 list
0000
0000 ;*******************
0000 ; value and address
0000 ;*******************
0000
0000 ;****************
0000 ; define symbols
0000 ;****************
0000 ENTRY equ 0h
0003 E_INT equ 3h
0007 E_TIM equ 7h
0000
0000 ;*******************
0000 ; interrupt vectors
0000 ;*******************
0000 org ENTRY
0000 2400 + jmp START
0002
0002 ; external interrupt
0002 org E_INT
0003 93 + retr
0004
0004 ; timer interrupt
0004 org E_TIM
0007 93 + retr
0008
0008 org 10h
0010 ;**************
0010 ; sub routines
0010 ;**************
0010 INIT:
0010 ; disable external interrupt
0010 15 + dis i
0011
0011 ; disable timer interrupt
0011 35 + dis tcnti
0012
0012 ; initialize I/O
0012 27 + clr a
0013 39 + outl P1,a
0014 3A + outl P2,a
0015
0015 83 + ret
0016
0016 INIT_REG:
0016 ;+++ low byte +++
0016 B8AF + mov r0,#0AFH
0018
0018 ;+++ middle byte +++
0018 B950 + mov r1,#50H
001A
001A ;+++ high byte +++
001A BA05 + mov r2,#05H
001C
001C ;+++ extra byte +++
001C BB34 + mov r3,#34H
001E
001E 83 + ret
001F
001F ;**************
001F ; main routine
001F ;**************
001F org 100h
0100 START:
0100 1410 + call INIT
0102 1416 + call INIT_REG
0104 MAIN:
0104 ; calculate feedback value = Q27 XOR Q30 and put in carry flag:
0104 FB + mov a,r3 ; Q27 --> x.7 (Q31 Q30 Q29 Q28 / Q27 Q26 Q25 Q24)
0105
0105 ; get Q30
0105 E7 + rl a
0106 5380 + anl a,#80H ; get MSB
0108 AC + mov r4,a ; store MSB(Q30)
0109
0109 FB + mov a,r3 ; Q27 --> x.7 (Q31 Q30 Q29 Q28 / Q27 Q26 Q25 Q24)
010A 47 + swap a ; Q27 Q26 Q25 Q24 / Q31 Q30 Q29 Q28
010B 5380 + anl a,#80H ; get MSB
010D
010D ; clear carry flag
010D 97 + clr c
010E
010E ; judge
010E DC + xrl a,r4 ; Q30 XOR Q27
010F F213 + jb7 MAIN1
0111 2414 + jmp MAIN2
0113
0113 ; set carry flag
0113 MAIN1:
0113 A7 + cpl c
0114
0114 MAIN2:
0114 ; rotate left (XRND0)
0114 F8 + mov a,r0
0115 F7 + rlc a
0116 A8 + mov r0,a
0117
0117 ; rotate left (XRND1)
0117 F9 + mov a,r1
0118 F7 + rlc a
0119 A9 + mov r1,a
011A
011A ; rotate left (XRND2)
011A FA + mov a,r2
011B F7 + rlc a
011C AA + mov r2,a
011D
011D ; rotate left (XRND3)
011D FB + mov a,r3
011E F7 + rlc a
011F AB + mov r3,a
0120
0120 ; copy r0 (XRND0)
0120 F8 + mov a,r0
0121
0121 ; impress
0121 39 + outl P1,a
0122
0122 ;
0122 2404 + jmp MAIN
0124
0124 end
ポート1から出力されてくる擬似乱数は、次の回路で
D/A変換すれば、実験に利用できます。
目次
前
次