firstcommit

This commit is contained in:
rco
2026-06-09 21:42:12 +09:00
commit efaf6574f4
198 changed files with 35006 additions and 0 deletions
+51
View File
@@ -0,0 +1,51 @@
사용법
1. ASM을 HEX로 변환
python asmtohex.py led.asm
결과:
led.hex
2. HEX를 COM3로 전송
python hexsend.py led.hex
pyserial 설치:
pip install pyserial
명령어 포맷:
16bit = opcode[15:12] + operand[11:0]
명령어:
NOP 0x0
LOAD n 0x1
INC 0x2
DEC 0x3
JMP addr 0x4
JZ addr 0x5
JNZ addr 0x6
LED_ON 0x7
LED_OFF 0x8
DELAY n 0x9
led.asm 변환 결과:
1005
7000
9064
8000
9064
3000
6001
5008
7000
4008
시리얼 전송 바이트:
10 05 70 00 90 64 80 00 90 64 30 00 60 01 50 08 70 00 40 08
+132
View File
@@ -0,0 +1,132 @@
#!/usr/bin/env python3
import sys
from pathlib import Path
OPCODE = {
"NOP": 0x0,
"LOAD": 0x1,
"INC": 0x2,
"DEC": 0x3,
"JMP": 0x4,
"JZ": 0x5,
"JNZ": 0x6,
"LED_ON": 0x7,
"LED_OFF": 0x8,
"DELAY": 0x9,
}
def remove_comment(line):
return line.split(";")[0].strip()
def parse_number(text):
text = text.strip()
if text.lower().startswith("0x"):
return int(text, 16)
if text.lower().startswith("0b"):
return int(text, 2)
return int(text, 10)
def assemble(asm_text):
labels = {}
instructions = []
pc = 0
# 1차 패스: 라벨 주소 수집
for raw_line in asm_text.splitlines():
line = remove_comment(raw_line)
if not line:
continue
if line.endswith(":"):
label = line[:-1].strip()
if label in labels:
raise ValueError(f"중복 라벨: {label}")
labels[label] = pc
continue
if ":" in line:
label_part, inst_part = line.split(":", 1)
label = label_part.strip()
inst_line = inst_part.strip()
if label in labels:
raise ValueError(f"중복 라벨: {label}")
labels[label] = pc
if inst_line:
instructions.append(inst_line)
pc += 1
continue
instructions.append(line)
pc += 1
machine = []
# 2차 패스: 명령어 변환
for addr, line in enumerate(instructions):
parts = line.replace(",", " ").split()
if not parts:
continue
mnemonic = parts[0].upper()
if mnemonic not in OPCODE:
raise ValueError(f"{addr}: 알 수 없는 명령어: {mnemonic}")
opcode = OPCODE[mnemonic]
operand = 0
if len(parts) >= 2:
arg = parts[1]
if arg in labels:
operand = labels[arg]
else:
operand = parse_number(arg)
if operand < 0 or operand > 0x0FFF:
raise ValueError(f"{addr}: operand 범위 초과 0~4095: {operand}")
word = (opcode << 12) | (operand & 0x0FFF)
machine.append(word)
return machine, labels, instructions
def main():
if len(sys.argv) != 2:
print("사용법: python asmtohex.py led.asm")
sys.exit(1)
asm_path = Path(sys.argv[1])
if not asm_path.exists():
print(f"파일 없음: {asm_path}")
sys.exit(1)
hex_path = asm_path.with_suffix(".hex")
asm_text = asm_path.read_text(encoding="utf-8")
machine, labels, instructions = assemble(asm_text)
with hex_path.open("w", encoding="utf-8") as f:
for word in machine:
f.write(f"{word:04X}\n")
print("라벨:")
for name, addr in labels.items():
print(f" {name} = {addr}")
print()
print("기계어:")
for addr, word in enumerate(machine):
print(f" {addr:02d}: {word:04X} ; {instructions[addr]}")
print()
print(f"HEX 생성 완료: {hex_path}")
if __name__ == "__main__":
main()
+85
View File
@@ -0,0 +1,85 @@
#!/usr/bin/env python3
import sys
import time
from pathlib import Path
try:
import serial
except ImportError:
print("pyserial이 필요합니다.")
print("설치: pip install pyserial")
sys.exit(1)
PORT = "COM3"
BAUD = 115200
def read_hex_file(hex_path):
data = bytearray()
for line_no, raw_line in enumerate(hex_path.read_text(encoding="utf-8").splitlines(), start=1):
line = raw_line.split(";")[0].strip()
if not line:
continue
line = line.replace("0x", "").replace("0X", "")
if len(line) != 4:
raise ValueError(f"{line_no}번째 줄 오류: 16비트 HEX 4자리여야 함: {raw_line}")
word = int(line, 16)
high = (word >> 8) & 0xFF
low = word & 0xFF
data.append(high)
data.append(low)
return data
def main():
if len(sys.argv) != 2:
print("사용법: python hexsend.py led.hex")
sys.exit(1)
hex_path = Path(sys.argv[1])
if not hex_path.exists():
print(f"파일 없음: {hex_path}")
sys.exit(1)
send_data = read_hex_file(hex_path)
send_data.append(0xFF)
send_data.append(0xFF)
print(f"파일: {hex_path}")
print(f"전송 바이트 수: {len(send_data)}")
print("전송 데이터:")
print(send_data.hex(" ").upper())
ser = serial.Serial(
port=PORT,
baudrate=BAUD,
bytesize=serial.EIGHTBITS,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
timeout=1
)
time.sleep(2)
ser.reset_input_buffer()
ser.reset_output_buffer()
ser.write(send_data)
ser.flush()
ser.close()
print()
print(f"{PORT}, {BAUD}bps 전송 완료")
if __name__ == "__main__":
main()
+18
View File
@@ -0,0 +1,18 @@
LOAD 1 ; R0 = 5
LOOP:
LED_ON ; LED 켜기
DELAY 300 ; 대기
LED_OFF ; LED 끄기
DELAY 300 ; 대기
DEC ; R0 = R0 - 1
JNZ LOOP ; R0 != 0이면 LOOP로 이동
JZ END_ON ; R0 == 0이면 END_ON으로 이동
END_ON:
LED_ON ; LED 켠 상태 유지
JMP END_ON ; 무한 반복
+10
View File
@@ -0,0 +1,10 @@
1001
7000
912C
8000
912C
3000
6001
5008
7000
4008
+315
View File
@@ -0,0 +1,315 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity micom is
port (
clk : in std_logic; -- 50MHz
reset : in std_logic; -- High reset
uart_rx : in std_logic;
led : out std_logic
);
end entity;
architecture rtl of micom is
constant CLK_FREQ : integer := 50000000;
constant BAUD_RATE : integer := 115200;
constant BAUD_CNT : integer := CLK_FREQ / BAUD_RATE;
type ram_type is array (0 to 255) of std_logic_vector(15 downto 0);
signal prog_ram : ram_type := (others => x"0000");
type uart_state_type is (
UART_IDLE,
UART_START,
UART_DATA,
UART_STOP
);
signal uart_state : uart_state_type := UART_IDLE;
signal baud_counter : integer range 0 to BAUD_CNT := 0;
signal bit_index : integer range 0 to 7 := 0;
signal rx_shift : std_logic_vector(7 downto 0) := (others => '0');
signal rx_byte : std_logic_vector(7 downto 0) := (others => '0');
signal rx_valid : std_logic := '0';
signal byte_high : std_logic_vector(7 downto 0) := (others => '0');
signal rx_phase : std_logic := '0';
signal wr_addr : integer range 0 to 255 := 0;
signal cpu_run : std_logic := '0';
type cpu_state_type is (
CPU_LOAD_PROGRAM,
CPU_FETCH,
CPU_DECODE,
CPU_DELAY
);
signal cpu_state : cpu_state_type := CPU_LOAD_PROGRAM;
signal pc : integer range 0 to 255 := 0;
signal inst : std_logic_vector(15 downto 0) := x"0000";
signal opcode : std_logic_vector(3 downto 0);
signal operand : unsigned(11 downto 0);
signal r0 : unsigned(15 downto 0) := (others => '0');
signal zflag : std_logic := '0';
signal delay_counter : unsigned(31 downto 0) := (others => '0');
begin
opcode <= inst(15 downto 12);
operand <= unsigned(inst(11 downto 0));
--------------------------------------------------------------------
-- UART RX
--------------------------------------------------------------------
process(clk, reset)
begin
if reset = '1' then
uart_state <= UART_IDLE;
baud_counter <= 0;
bit_index <= 0;
rx_shift <= (others => '0');
rx_byte <= (others => '0');
rx_valid <= '0';
elsif rising_edge(clk) then
rx_valid <= '0';
case uart_state is
when UART_IDLE =>
if uart_rx = '0' then
baud_counter <= BAUD_CNT / 2;
uart_state <= UART_START;
end if;
when UART_START =>
if baud_counter = 0 then
if uart_rx = '0' then
baud_counter <= BAUD_CNT - 1;
bit_index <= 0;
uart_state <= UART_DATA;
else
uart_state <= UART_IDLE;
end if;
else
baud_counter <= baud_counter - 1;
end if;
when UART_DATA =>
if baud_counter = 0 then
rx_shift(bit_index) <= uart_rx;
baud_counter <= BAUD_CNT - 1;
if bit_index = 7 then
uart_state <= UART_STOP;
else
bit_index <= bit_index + 1;
end if;
else
baud_counter <= baud_counter - 1;
end if;
when UART_STOP =>
if baud_counter = 0 then
rx_byte <= rx_shift;
rx_valid <= '1';
uart_state <= UART_IDLE;
else
baud_counter <= baud_counter - 1;
end if;
end case;
end if;
end process;
--------------------------------------------------------------------
-- Loader
-- 실행 중 새 UART 데이터가 들어오면 자동 초기화 후 재다운로드
--------------------------------------------------------------------
process(clk, reset)
variable word_data : std_logic_vector(15 downto 0);
begin
if reset = '1' then
byte_high <= (others => '0');
rx_phase <= '0';
wr_addr <= 0;
cpu_run <= '0';
elsif rising_edge(clk) then
if rx_valid = '1' then
-- CPU 실행 중 새 데이터가 들어오면 기존 실행 중지 후 재다운로드 시작
if cpu_state /= CPU_LOAD_PROGRAM then
wr_addr <= 0;
rx_phase <= '0';
cpu_run <= '0';
byte_high <= rx_byte;
rx_phase <= '1';
else
if rx_phase = '0' then
byte_high <= rx_byte;
rx_phase <= '1';
else
word_data := byte_high & rx_byte;
if word_data = x"FFFF" then
cpu_run <= '1';
rx_phase <= '0';
else
prog_ram(wr_addr) <= word_data;
if wr_addr < 255 then
wr_addr <= wr_addr + 1;
end if;
rx_phase <= '0';
end if;
end if;
end if;
end if;
end if;
end process;
--------------------------------------------------------------------
-- CPU
--------------------------------------------------------------------
process(clk, reset)
begin
if reset = '1' then
cpu_state <= CPU_LOAD_PROGRAM;
pc <= 0;
inst <= x"0000";
r0 <= (others => '0');
zflag <= '0';
delay_counter <= (others => '0');
led <= '0';
elsif rising_edge(clk) then
-- 실행 중 UART 데이터가 들어오면 CPU를 초기화하고 다운로드 모드로 전환
if rx_valid = '1' and cpu_state /= CPU_LOAD_PROGRAM then
cpu_state <= CPU_LOAD_PROGRAM;
pc <= 0;
inst <= x"0000";
r0 <= (others => '0');
zflag <= '0';
delay_counter <= (others => '0');
led <= '0';
else
case cpu_state is
when CPU_LOAD_PROGRAM =>
if cpu_run = '1' then
pc <= 0;
cpu_state <= CPU_FETCH;
end if;
when CPU_FETCH =>
inst <= prog_ram(pc);
if pc < 255 then
pc <= pc + 1;
end if;
cpu_state <= CPU_DECODE;
when CPU_DECODE =>
case opcode is
when x"0" =>
cpu_state <= CPU_FETCH;
when x"1" =>
r0 <= resize(operand, 16);
if operand = 0 then
zflag <= '1';
else
zflag <= '0';
end if;
cpu_state <= CPU_FETCH;
when x"2" =>
r0 <= r0 + 1;
if r0 + 1 = 0 then
zflag <= '1';
else
zflag <= '0';
end if;
cpu_state <= CPU_FETCH;
when x"3" =>
r0 <= r0 - 1;
if r0 - 1 = 0 then
zflag <= '1';
else
zflag <= '0';
end if;
cpu_state <= CPU_FETCH;
when x"4" =>
pc <= to_integer(operand(7 downto 0));
cpu_state <= CPU_FETCH;
when x"5" =>
if zflag = '1' then
pc <= to_integer(operand(7 downto 0));
end if;
cpu_state <= CPU_FETCH;
when x"6" =>
if zflag = '0' then
pc <= to_integer(operand(7 downto 0));
end if;
cpu_state <= CPU_FETCH;
when x"7" =>
led <= '1';
cpu_state <= CPU_FETCH;
when x"8" =>
led <= '0';
cpu_state <= CPU_FETCH;
when x"9" =>
delay_counter <= to_unsigned(to_integer(operand) * 50000, 32);
cpu_state <= CPU_DELAY;
when others =>
cpu_state <= CPU_FETCH;
end case;
when CPU_DELAY =>
if delay_counter = 0 then
cpu_state <= CPU_FETCH;
else
delay_counter <= delay_counter - 1;
end if;
end case;
end if;
end if;
end process;
end architecture;
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 359 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

+94
View File
@@ -0,0 +1,94 @@
# RCO ALTERA FPGA 설계
RCO ALTERA FPGA IV KIT를 이용한 FPGA 실습을 하도록 지원한다.
![내 사진](imgs/fpga_b.png)
---
## FPGA CORE MODULE
![내 사진](imgs/fpga_core.png)
![내 사진](imgs/pins.png)
| **J1** | | | | **J2** | | | |
|:------:|:------|:------:|:------|:------:|:------|:------:|:------|
| 핀번호 | 핀이름 | 핀번호 | 핀이름 | 핀번호 | 핀이름 | 핀번호 | 핀이름 |
| 1 | GND | 2 | GND | 1 | GND | 2 | GND |
| 3 | +3.3V | 4 | +3.3V | 3 | +3.3V | 4 | +3.3V |
| 5 | PIN_R1 | 6 | PIN_R2 | 5 | PIN_AA11 | 6 | PIN_AB11 |
| 7 | PIN_P1 | 8 | PIN_P2 | 7 | PIN_AA13 | 8 | PIN_AB13 |
| 9 | PIN_N1 | 10 | PIN_N2 | 9 | PIN_AA14 | 10 | PIN_AB14 |
| 11 | PIN_M1 | 12 | PIN_M2 | 11 | PIN_AA15 | 12 | PIN_AB15 |
| 13 | PIN_J1 | 14 | PIN_J2 | 13 | PIN_AA16 | 14 | PIN_AB16 |
| 15 | PIN_H1 | 16 | PIN_H2 | 15 | PIN_AA17 | 16 | PIN_AB17 |
| 17 | PIN_F1 | 18 | PIN_F2 | 17 | PIN_AA18 | 18 | PIN_AB18 |
| 19 | PIN_E1 | 20 | PIN_D2 | 19 | PIN_AA19 | 20 | PIN_AB19 |
| 21 | PIN_C1 | 22 | PIN_C2 | 21 | PIN_AA20 | 22 | PIN_AB20 |
| 23 | PIN_B1 | 24 | PIN_B2 | 23 | PIN_Y22 | 24 | PIN_Y21 |
| 25 | - | 26 | - | 25 | PIN_W22 | 26 | PIN_W21 |
| 27 | PIN_B3 | 28 | PIN_A3 | 27 | PIN_V22 | 28 | PIN_V21 |
| 29 | PIN_B4 | 30 | PIN_A4 | 29 | PIN_U22 | 30 | PIN_U21 |
| 31 | PIN_C4 | 32 | PIN_C3 | 31 | PIN_R22 | 32 | PIN_R21 |
| 33 | PIN_B5 | 34 | PIN_A5 | 33 | PIN_P22 | 34 | PIN_P21 |
| 35 | PIN_B6 | 36 | PIN_A6 | 35 | PIN_N22 | 36 | PIN_N21 |
| 37 | PIN_B7 | 38 | PIN_A7 | 37 | PIN_M22 | 38 | PIN_M21 |
| 39 | PIN_B8 | 40 | PIN_A8 | 39 | PIN_L22 | 40 | PIN_L21 |
| 41 | PIN_B9 | 42 | PIN_A9 | 41 | PIN_K22 | 42 | PIN_K21 |
| 43 | PIN_B10 | 44 | PIN_A10 | 43 | PIN_J22 | 44 | PIN_J21 |
| 45 | PIN_B13 | 46 | PIN_A13 | 45 | PIN_H22 | 46 | PIN_H21 |
| 47 | PIN_B14 | 48 | PIN_A14 | 47 | PIN_F22 | 48 | PIN_F21 |
| 49 | PIN_B15 | 50 | PIN_A15 | 49 | PIN_E22 | 50 | PIN_E21 |
| 51 | PIN_B16 | 52 | PIN_A16 | 51 | PIN_D22 | 52 | PIN_D21 |
| 53 | PIN_B17 | 54 | PIN_A17 | 53 | PIN_C22 | 54 | PIN_C21 |
| 55 | PIN_B18 | 56 | PIN_A18 | 55 | PIN_B22 | 56 | PIN_B21 |
| 57 | PIN_B19 | 58 | PIN_A19 | 57 | PIN_N20 | 58 | PIN_N19 |
| 59 | PIN_B20 | 60 | PIN_A20 | 59 | PIN_M20 | 60 | PIN_M19 |
| 61 | GND | 62 | GND | 61 | GND | 62 | GND |
| 63 | VIN | 64 | VIN | 63 | VIN | 64 | VIN |
---
## 주요기능 테스트
### 기초실습 항목 실습
1. LED ON/OFF:
2. IN_OUT:
3. CLK:
4. 7SEG:
5. KEY_7SEG:
6. CLK_7SEG:
7. MODE_SW:
---
### 소형 마이컴 제작
1. 마이컴설계:
2. cmd_set:
3. 어셈블리작성:
4. 컴파일과작성:
5. 다운로드작성:
6. FPGA제작:
7. 프로그램실습:
---
### 모델기반설계(MATLAB/SIMULINK)
1. FPGA모델기반설계:
2. 기능정의:
3. 시뮬링크작성:
4. VHDL코드생성:
+5
View File
@@ -0,0 +1,5 @@
window.MathJax = {
tex: {
tags: 'ams'
}
};
+47
View File
@@ -0,0 +1,47 @@
# FPGA 모델기반설계
MATLAB/Simulink + HDL Coder를 사용하면 블록 다이어그램으로 설계한 후 자동으로 VHDL 또는 Verilog 코드를 생성할 수 있습니다.
이 과정을 수행하여, 모델기반 설계에 대한 실습을 진행한다.
여기서는 간단한 LED 제어를 위한 모델 기반 설계를 전체 과정을 수행하여, 전체 제작에 대한 이해를 지원한다.
### 주요흐름
```
Simulink 모델 작성
↓
HDL Coder 설정
↓
고정소수점(Fixed Point) 변환
↓
HDL Workflow Advisor 실행
↓
VHDL 생성
↓
Quartus/Vivado 합성
↓
FPGA 다운로드
```
## 응용 예제
FPGA 개발자들이 가장 많이 사용하는 자동 HDL 생성 예제는 다음과 같은 것이 있다.
- UART TX/RX
- FIR Filter
- FFT
- PID Controller
- Motor Control
- PWM Generator
- CNN AI Accelerator
- Ethernet MAC
- Video Processing Pipeline
+133
View File
@@ -0,0 +1,133 @@
# 기능정의
## 동작 정의
키를 입력하면 해당하는 동작을 하도록 한다.
---
![내 사진](imgs/key4.png)
---
| KEY 입력 | LED 동작 |
| --------- | -------- |
| KEY0 = 1 | LED OFF |
| KEY1 = 1 | 느리게 깜빡임 |
| KEY2 = 1 | 보통 속도 |
| KEY3 = 1 | 빠르게 깜빡임 |
| 아무 KEY 없음 | 이전 상태 유지 |
핵심은 LED 상태를 바로 결정하는 것이 아니라, 현재 동작 모드를 레지스터에 저장하는 것입니다.
```
KEY 입력
↓
동작 모드 저장 레지스터
↓
Blink 속도 선택
↓
Counter
↓
LED 출력
```
---
![내 사진](imgs/ledonoff.png)
---
## 모드값 정의
모드에 따른 속도 정의
```
MODE_OFF = 0
MODE_SLOW = 1
MODE_NORMAL = 2
MODE_FAST = 3
```
## KEY 처리 논리
```
if KEY0 = 1
mode = OFF
elseif KEY1 = 1
mode = SLOW
elseif KEY2 = 1
mode = NORMAL
elseif KEY3 = 1
mode = FAST
else
mode = mode 유지
end
```
## Simulink 블록 구성
```
KEY0 ─┐
KEY1 ─┤
KEY2 ─┤→ Mode Select Logic → Unit Delay → mode
KEY3 ─┘
mode → Period Select → Counter → Compare → LED
```
## MTLAB BLOCK 작성
필요한 블록은 직접 MATLAB 코드 블록으로 작성하여 추가하도록 한다.
```
+---------+
| KEY[3:0]|
+---------+
|
v
+----------------+
| MATLAB Function|
| key_led_blink |
+----------------+
|
v
+---------+
| LED |
+---------+
```
## Simulink 입출력
```
입력:
key[4] : Boolean 또는 uint8 벡터
출력:
led : Boolean
```
## VHDL 코드 생성
```
entity key_led_blink is
port(
clk : in std_logic;
reset : in std_logic;
key : in std_logic_vector(3 downto 0);
led : out std_logic
);
end entity;
```
+113
View File
@@ -0,0 +1,113 @@
# 시뮬링크작성
## 기본블록 구성
MATLAB FUNC 블록 코드들 다음과 같이 작성한다.
![내그림](imgs/sim_blk.png)
## MATLAB FUN 블록 작성
MATLAB FUNC 블록을 더블 클릭다여 아래 코드를 작성한다.
---
![내그림](imgs/code.png)
---
```c
function led = fcn(key0, key1, key2, key3)
%#codegen
persistent mode;
persistent cnt;
persistent led_state;
if isempty(mode)
mode = uint8(0); % 0 = OFF
end
if isempty(cnt)
cnt = uint32(0);
end
if isempty(led_state)
led_state = false;
end
% -----------------------------
% 1. KEY 입력에 따라 모드 저장
% -----------------------------
if key0
mode = uint8(0); % OFF
elseif key1
mode = uint8(1); % SLOW
elseif key2
mode = uint8(2); % NORMAL
elseif key3
mode = uint8(3); % FAST
end
% -----------------------------
% 2. 모드에 따라 깜빡임 주기 선택
% 50MHz 클럭 기준
% -----------------------------
period = uint32(0);
if mode == uint8(0)
period = uint32(0); % OFF
elseif mode == uint8(1)
period = uint32(50000000); % 느림
elseif mode == uint8(2)
period = uint32(25000000); % 보통
else
period = uint32(5000000); % 빠름
end
% -----------------------------
% 3. LED 출력 생성
% -----------------------------
if mode == uint8(0)
led_state = false;
cnt = uint32(0);
else
if cnt >= period
cnt = uint32(0);
led_state = ~led_state; % LED 반전
else
cnt = cnt + uint32(1);
end
end
led = led_state;
end
```
## 블록작성완료
선으로 연결하여, 최종 블록 작성을 완료한다. Key 입력이 되도록 블록을 그려준다.
![내그림](imgs/sim_blk_2.png)
---
+145
View File
@@ -0,0 +1,145 @@
# VHDL 코드
HDL Coder 을 이용하여 VHDL 코드를 생성한다.
## 생성된 코드
```
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity led_blink is
port(
clk : in std_logic;
rst : in std_logic;
key0 : in std_logic;
key1 : in std_logic;
key2 : in std_logic;
key3 : in std_logic;
led : out std_logic
);
end entity;
architecture rtl of led_blink is
signal mode : unsigned(1 downto 0) := "00";
signal cnt : unsigned(31 downto 0) := (others=>'0');
signal period : unsigned(31 downto 0);
signal led_state : std_logic := '0';
begin
------------------------------------------------------------------
-- period 결정
------------------------------------------------------------------
process(mode)
begin
case mode is
when "00" =>
period <= to_unsigned(0,32);
when "01" =>
period <= to_unsigned(50000000,32);
when "10" =>
period <= to_unsigned(25000000,32);
when others =>
period <= to_unsigned(5000000,32);
end case;
end process;
------------------------------------------------------------------
-- 메인 상태기계
------------------------------------------------------------------
process(clk,rst)
begin
if rst='1' then
mode <= "00";
cnt <= (others=>'0');
led_state <= '0';
elsif rising_edge(clk) then
----------------------------------------------------------
-- mode 저장
----------------------------------------------------------
if key0='1' then
mode <= "00";
elsif key1='1' then
mode <= "01";
elsif key2='1' then
mode <= "10";
elsif key3='1' then
mode <= "11";
end if;
----------------------------------------------------------
-- LED 생성
----------------------------------------------------------
if mode = "00" then
cnt <= (others=>'0');
led_state <= '0';
else
if cnt >= period then
cnt <= (others=>'0');
led_state <= not led_state;
else
cnt <= cnt + 1;
end if;
end if;
end if;
end process;
led <= led_state;
end architecture;
```
## 핀배치
| 핀 번호 | 신호 |
|---------|------|
| PIN_T2 | clk |
| PIN_E4 | rst |
| PIN_A3 | key0 |
| PIN_A5 | key1 |
| PIN_A6 | key2 |
| PIN_A20 | key3 |
| PIN_B3 | led |
## 테스트 진행
해당 코드를 Quartus 를 이용하여 컴파일 하고, 동작 과정을 실습한다.
+51
View File
@@ -0,0 +1,51 @@
사용법
1. ASM을 HEX로 변환
python asmtohex.py led.asm
결과:
led.hex
2. HEX를 COM3로 전송
python hexsend.py led.hex
pyserial 설치:
pip install pyserial
명령어 포맷:
16bit = opcode[15:12] + operand[11:0]
명령어:
NOP 0x0
LOAD n 0x1
INC 0x2
DEC 0x3
JMP addr 0x4
JZ addr 0x5
JNZ addr 0x6
LED_ON 0x7
LED_OFF 0x8
DELAY n 0x9
led.asm 변환 결과:
1005
7000
9064
8000
9064
3000
6001
5008
7000
4008
시리얼 전송 바이트:
10 05 70 00 90 64 80 00 90 64 30 00 60 01 50 08 70 00 40 08
+132
View File
@@ -0,0 +1,132 @@
#!/usr/bin/env python3
import sys
from pathlib import Path
OPCODE = {
"NOP": 0x0,
"LOAD": 0x1,
"INC": 0x2,
"DEC": 0x3,
"JMP": 0x4,
"JZ": 0x5,
"JNZ": 0x6,
"LED_ON": 0x7,
"LED_OFF": 0x8,
"DELAY": 0x9,
}
def remove_comment(line):
return line.split(";")[0].strip()
def parse_number(text):
text = text.strip()
if text.lower().startswith("0x"):
return int(text, 16)
if text.lower().startswith("0b"):
return int(text, 2)
return int(text, 10)
def assemble(asm_text):
labels = {}
instructions = []
pc = 0
# 1차 패스: 라벨 주소 수집
for raw_line in asm_text.splitlines():
line = remove_comment(raw_line)
if not line:
continue
if line.endswith(":"):
label = line[:-1].strip()
if label in labels:
raise ValueError(f"중복 라벨: {label}")
labels[label] = pc
continue
if ":" in line:
label_part, inst_part = line.split(":", 1)
label = label_part.strip()
inst_line = inst_part.strip()
if label in labels:
raise ValueError(f"중복 라벨: {label}")
labels[label] = pc
if inst_line:
instructions.append(inst_line)
pc += 1
continue
instructions.append(line)
pc += 1
machine = []
# 2차 패스: 명령어 변환
for addr, line in enumerate(instructions):
parts = line.replace(",", " ").split()
if not parts:
continue
mnemonic = parts[0].upper()
if mnemonic not in OPCODE:
raise ValueError(f"{addr}: 알 수 없는 명령어: {mnemonic}")
opcode = OPCODE[mnemonic]
operand = 0
if len(parts) >= 2:
arg = parts[1]
if arg in labels:
operand = labels[arg]
else:
operand = parse_number(arg)
if operand < 0 or operand > 0x0FFF:
raise ValueError(f"{addr}: operand 범위 초과 0~4095: {operand}")
word = (opcode << 12) | (operand & 0x0FFF)
machine.append(word)
return machine, labels, instructions
def main():
if len(sys.argv) != 2:
print("사용법: python asmtohex.py led.asm")
sys.exit(1)
asm_path = Path(sys.argv[1])
if not asm_path.exists():
print(f"파일 없음: {asm_path}")
sys.exit(1)
hex_path = asm_path.with_suffix(".hex")
asm_text = asm_path.read_text(encoding="utf-8")
machine, labels, instructions = assemble(asm_text)
with hex_path.open("w", encoding="utf-8") as f:
for word in machine:
f.write(f"{word:04X}\n")
print("라벨:")
for name, addr in labels.items():
print(f" {name} = {addr}")
print()
print("기계어:")
for addr, word in enumerate(machine):
print(f" {addr:02d}: {word:04X} ; {instructions[addr]}")
print()
print(f"HEX 생성 완료: {hex_path}")
if __name__ == "__main__":
main()
+85
View File
@@ -0,0 +1,85 @@
#!/usr/bin/env python3
import sys
import time
from pathlib import Path
try:
import serial
except ImportError:
print("pyserial이 필요합니다.")
print("설치: pip install pyserial")
sys.exit(1)
PORT = "COM3"
BAUD = 115200
def read_hex_file(hex_path):
data = bytearray()
for line_no, raw_line in enumerate(hex_path.read_text(encoding="utf-8").splitlines(), start=1):
line = raw_line.split(";")[0].strip()
if not line:
continue
line = line.replace("0x", "").replace("0X", "")
if len(line) != 4:
raise ValueError(f"{line_no}번째 줄 오류: 16비트 HEX 4자리여야 함: {raw_line}")
word = int(line, 16)
high = (word >> 8) & 0xFF
low = word & 0xFF
data.append(high)
data.append(low)
return data
def main():
if len(sys.argv) != 2:
print("사용법: python hexsend.py led.hex")
sys.exit(1)
hex_path = Path(sys.argv[1])
if not hex_path.exists():
print(f"파일 없음: {hex_path}")
sys.exit(1)
send_data = read_hex_file(hex_path)
send_data.append(0xFF)
send_data.append(0xFF)
print(f"파일: {hex_path}")
print(f"전송 바이트 수: {len(send_data)}")
print("전송 데이터:")
print(send_data.hex(" ").upper())
ser = serial.Serial(
port=PORT,
baudrate=BAUD,
bytesize=serial.EIGHTBITS,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
timeout=1
)
time.sleep(2)
ser.reset_input_buffer()
ser.reset_output_buffer()
ser.write(send_data)
ser.flush()
ser.close()
print()
print(f"{PORT}, {BAUD}bps 전송 완료")
if __name__ == "__main__":
main()
+18
View File
@@ -0,0 +1,18 @@
LOAD 1 ; R0 = 5
LOOP:
LED_ON ; LED 켜기
DELAY 300 ; 대기
LED_OFF ; LED 끄기
DELAY 300 ; 대기
DEC ; R0 = R0 - 1
JNZ LOOP ; R0 != 0이면 LOOP로 이동
JZ END_ON ; R0 == 0이면 END_ON으로 이동
END_ON:
LED_ON ; LED 켠 상태 유지
JMP END_ON ; 무한 반복
+10
View File
@@ -0,0 +1,10 @@
1001
7000
912C
8000
912C
3000
6001
5008
7000
4008
+315
View File
@@ -0,0 +1,315 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity micom is
port (
clk : in std_logic; -- 50MHz
reset : in std_logic; -- High reset
uart_rx : in std_logic;
led : out std_logic
);
end entity;
architecture rtl of micom is
constant CLK_FREQ : integer := 50000000;
constant BAUD_RATE : integer := 115200;
constant BAUD_CNT : integer := CLK_FREQ / BAUD_RATE;
type ram_type is array (0 to 255) of std_logic_vector(15 downto 0);
signal prog_ram : ram_type := (others => x"0000");
type uart_state_type is (
UART_IDLE,
UART_START,
UART_DATA,
UART_STOP
);
signal uart_state : uart_state_type := UART_IDLE;
signal baud_counter : integer range 0 to BAUD_CNT := 0;
signal bit_index : integer range 0 to 7 := 0;
signal rx_shift : std_logic_vector(7 downto 0) := (others => '0');
signal rx_byte : std_logic_vector(7 downto 0) := (others => '0');
signal rx_valid : std_logic := '0';
signal byte_high : std_logic_vector(7 downto 0) := (others => '0');
signal rx_phase : std_logic := '0';
signal wr_addr : integer range 0 to 255 := 0;
signal cpu_run : std_logic := '0';
type cpu_state_type is (
CPU_LOAD_PROGRAM,
CPU_FETCH,
CPU_DECODE,
CPU_DELAY
);
signal cpu_state : cpu_state_type := CPU_LOAD_PROGRAM;
signal pc : integer range 0 to 255 := 0;
signal inst : std_logic_vector(15 downto 0) := x"0000";
signal opcode : std_logic_vector(3 downto 0);
signal operand : unsigned(11 downto 0);
signal r0 : unsigned(15 downto 0) := (others => '0');
signal zflag : std_logic := '0';
signal delay_counter : unsigned(31 downto 0) := (others => '0');
begin
opcode <= inst(15 downto 12);
operand <= unsigned(inst(11 downto 0));
--------------------------------------------------------------------
-- UART RX
--------------------------------------------------------------------
process(clk, reset)
begin
if reset = '1' then
uart_state <= UART_IDLE;
baud_counter <= 0;
bit_index <= 0;
rx_shift <= (others => '0');
rx_byte <= (others => '0');
rx_valid <= '0';
elsif rising_edge(clk) then
rx_valid <= '0';
case uart_state is
when UART_IDLE =>
if uart_rx = '0' then
baud_counter <= BAUD_CNT / 2;
uart_state <= UART_START;
end if;
when UART_START =>
if baud_counter = 0 then
if uart_rx = '0' then
baud_counter <= BAUD_CNT - 1;
bit_index <= 0;
uart_state <= UART_DATA;
else
uart_state <= UART_IDLE;
end if;
else
baud_counter <= baud_counter - 1;
end if;
when UART_DATA =>
if baud_counter = 0 then
rx_shift(bit_index) <= uart_rx;
baud_counter <= BAUD_CNT - 1;
if bit_index = 7 then
uart_state <= UART_STOP;
else
bit_index <= bit_index + 1;
end if;
else
baud_counter <= baud_counter - 1;
end if;
when UART_STOP =>
if baud_counter = 0 then
rx_byte <= rx_shift;
rx_valid <= '1';
uart_state <= UART_IDLE;
else
baud_counter <= baud_counter - 1;
end if;
end case;
end if;
end process;
--------------------------------------------------------------------
-- Loader
-- 실행 중 새 UART 데이터가 들어오면 자동 초기화 후 재다운로드
--------------------------------------------------------------------
process(clk, reset)
variable word_data : std_logic_vector(15 downto 0);
begin
if reset = '1' then
byte_high <= (others => '0');
rx_phase <= '0';
wr_addr <= 0;
cpu_run <= '0';
elsif rising_edge(clk) then
if rx_valid = '1' then
-- CPU 실행 중 새 데이터가 들어오면 기존 실행 중지 후 재다운로드 시작
if cpu_state /= CPU_LOAD_PROGRAM then
wr_addr <= 0;
rx_phase <= '0';
cpu_run <= '0';
byte_high <= rx_byte;
rx_phase <= '1';
else
if rx_phase = '0' then
byte_high <= rx_byte;
rx_phase <= '1';
else
word_data := byte_high & rx_byte;
if word_data = x"FFFF" then
cpu_run <= '1';
rx_phase <= '0';
else
prog_ram(wr_addr) <= word_data;
if wr_addr < 255 then
wr_addr <= wr_addr + 1;
end if;
rx_phase <= '0';
end if;
end if;
end if;
end if;
end if;
end process;
--------------------------------------------------------------------
-- CPU
--------------------------------------------------------------------
process(clk, reset)
begin
if reset = '1' then
cpu_state <= CPU_LOAD_PROGRAM;
pc <= 0;
inst <= x"0000";
r0 <= (others => '0');
zflag <= '0';
delay_counter <= (others => '0');
led <= '0';
elsif rising_edge(clk) then
-- 실행 중 UART 데이터가 들어오면 CPU를 초기화하고 다운로드 모드로 전환
if rx_valid = '1' and cpu_state /= CPU_LOAD_PROGRAM then
cpu_state <= CPU_LOAD_PROGRAM;
pc <= 0;
inst <= x"0000";
r0 <= (others => '0');
zflag <= '0';
delay_counter <= (others => '0');
led <= '0';
else
case cpu_state is
when CPU_LOAD_PROGRAM =>
if cpu_run = '1' then
pc <= 0;
cpu_state <= CPU_FETCH;
end if;
when CPU_FETCH =>
inst <= prog_ram(pc);
if pc < 255 then
pc <= pc + 1;
end if;
cpu_state <= CPU_DECODE;
when CPU_DECODE =>
case opcode is
when x"0" =>
cpu_state <= CPU_FETCH;
when x"1" =>
r0 <= resize(operand, 16);
if operand = 0 then
zflag <= '1';
else
zflag <= '0';
end if;
cpu_state <= CPU_FETCH;
when x"2" =>
r0 <= r0 + 1;
if r0 + 1 = 0 then
zflag <= '1';
else
zflag <= '0';
end if;
cpu_state <= CPU_FETCH;
when x"3" =>
r0 <= r0 - 1;
if r0 - 1 = 0 then
zflag <= '1';
else
zflag <= '0';
end if;
cpu_state <= CPU_FETCH;
when x"4" =>
pc <= to_integer(operand(7 downto 0));
cpu_state <= CPU_FETCH;
when x"5" =>
if zflag = '1' then
pc <= to_integer(operand(7 downto 0));
end if;
cpu_state <= CPU_FETCH;
when x"6" =>
if zflag = '0' then
pc <= to_integer(operand(7 downto 0));
end if;
cpu_state <= CPU_FETCH;
when x"7" =>
led <= '1';
cpu_state <= CPU_FETCH;
when x"8" =>
led <= '0';
cpu_state <= CPU_FETCH;
when x"9" =>
delay_counter <= to_unsigned(to_integer(operand) * 50000, 32);
cpu_state <= CPU_DELAY;
when others =>
cpu_state <= CPU_FETCH;
end case;
when CPU_DELAY =>
if delay_counter = 0 then
cpu_state <= CPU_FETCH;
else
delay_counter <= delay_counter - 1;
end if;
end case;
end if;
end if;
end process;
end architecture;
Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

+35
View File
@@ -0,0 +1,35 @@
.md-typeset .md-typeset__table {
width: 100% !important;
}
.md-typeset .md-typeset__table table {
width: 100% !important;
display: table !important;
table-layout: fixed;
}
.md-typeset table:not([class]) th,
.md-typeset table:not([class]) td {
padding: 10px 16px;
}
.md-typeset table:not([class]) tr:nth-child(even) {
background-color: #f5f5f5;
}
.image-row {
display:flex;
gap:20px;
}
.image-box {
text-align:center;
}
.image-box img {
height:220px !important;
width:auto !important;
max-width:none !important;
}
+71
View File
@@ -0,0 +1,71 @@
# LED ON OFF
실습키트의 LED 16비트를 ONOFF하는 과정을 실습니다.
해당 값에 대한 비트에 LED 가 ON OFF되는지 확인한다.
![내 사진](imgs/led16.png)
## PIN 테이블
| 핀 번호 | 신호 |
|---------|------|
| PIN_B3 | LED_A[7] |
| PIN_B4 | LED_A[6] |
| PIN_B5 | LED_A[5] |
| PIN_B6 | LED_A[4] |
| PIN_B7 | LED_A[3] |
| PIN_B8 | LED_A[2] |
| PIN_B9 | LED_A[1] |
| PIN_B10 | LED_A[0] |
| PIN_B13 | LED_B[7] |
| PIN_B14 | LED_B[6] |
| PIN_B15 | LED_B[5] |
| PIN_B16 | LED_B[4] |
| PIN_B17 | LED_B[3] |
| PIN_B18 | LED_B[2] |
| PIN_B19 | LED_B[1] |
| PIN_B20 | LED_B[0] |
## VHDL 코드
```vhdl
library ieee;
use ieee.std_logic_1164.all;
entity led_test is
port( LED_A : out std_logic_vector(7 downto 0);
LED_B : out std_logic_vector(7 downto 0) );
end led_test;
architecture button_design of led_test is
begin
LED_A <= x"F0";
LED_B <= x"0F";
end button_design;
```
+70
View File
@@ -0,0 +1,70 @@
# IN_OUT
실습키트의 LED 16비트를 ONOFF하는 과정을 실습니다.
해당 값에 대한 비트에 LED 가 ON OFF되는지 확인한다.
![내 사진](imgs/in_out.png)
## PIN 테이블
| 핀 번호 | 신호 |
|---------|------|
| PIN_P21 | din[7] |
| PIN_N21 | din[6] |
| PIN_M21 | din[5] |
| PIN_L21 | din[4] |
| PIN_K21 | din[3] |
| PIN_J21 | din[2] |
| PIN_H21 | din[1] |
| PIN_F21 | din[0] |
| PIN_B3 | dout[7] |
| PIN_B4 | dout[6] |
| PIN_B5 | dout[5] |
| PIN_B6 | dout[4] |
| PIN_B7 | dout[3] |
| PIN_B8 | dout[2] |
| PIN_B9 | dout[1] |
| PIN_B10 | dout[0] |
## VHDL 코드
```vhdl
library ieee;
use ieee.std_logic_1164.all;
entity in_out is
port(
din : in std_logic_vector(7 downto 0); -- 8비트 입력
dout : out std_logic_vector(7 downto 0) -- 8비트 출력
);
end entity;
architecture rtl of in_out is
begin
-- 입력을 그대로 출력으로 전달
dout <= din;
end architecture;
```
+80
View File
@@ -0,0 +1,80 @@
# CLK
실습키트의 50MHz의 클럭을 받아서 원하는 시간으로 LED ON OFF 과정을 수행한다.
코어모듈에 적용된 LED 와 CLK 오실레이터의 입력을 사용한다.
![내 사진](imgs/fpga_core.png)
## PIN 테이블
| 핀 번호 | 신호 |
|---------|------|
| PIN_T2 | clk |
| PIN_E4 | led |
## VHDL 코드
```vhdl
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity clk is
port (
clk : in std_logic; -- PIN T2, 50MHz
led : out std_logic -- PIN E4 (active-high 가정)
);
end entity;
architecture rtl of clk is
signal cnt : integer range 0 to 49_999_999 := 0;
signal q : std_logic := '0';
begin
process(clk)
begin
if rising_edge(clk) then
if cnt = 49_999_999 / 5 then
cnt <= 0;
q <= not q; -- 1초마다 토글 (ON 1초, OFF 1초)
else
cnt <= cnt + 1;
end if;
end if;
end process;
led <= q; -- 보드가 active-low LED라면: led0 <= not q;
end architecture;
```
+99
View File
@@ -0,0 +1,99 @@
# 7SEG
실습키트의 7SEGMENT의 출력이 정상적으로 되는지 확인한다.
![내 사진](imgs/seg.png)
## PIN 테이블
| 핀 번호 | 신호 |
|---------|------|
| PIN_AA13 | led_out[0] |
| PIN_AA14 | led_out[1] |
| PIN_AA15 | led_out[2] |
| PIN_AA16 | led_out[3] |
| PIN_AA17 | led_out[4] |
| PIN_AA18 | led_out[5] |
| PIN_AA19 | led_out[6] |
| PIN_AA20 | led_out[7] |
| PIN_AB14 | seg[6] |
| PIN_AB15 | seg[5] |
| PIN_AB16 | seg[4] |
| PIN_AB17 | seg[3] |
| PIN_AB18 | seg[2] |
| PIN_AB19 | seg[1] |
| PIN_AB20 | seg[0] |
## VHDL 코드
```vhdl
library ieee;
use ieee.std_logic_1164.all;
entity seg_out is
port(
seg : out std_logic_vector(6 downto 0); -- 7-세그 출력 (g~a)
led_out : out std_logic_vector(0 to 7) -- 기존 인덱스(0 to 7)
);
end seg_out;
architecture SegmentDecoder of seg_out is
signal key : integer range 0 to 15 := 5; -- 표시할 숫자 (0~15)
begin
----------------------------------------------------------------
-- with-select: key 값 → seg 패턴 매핑 (VHDL-93 호환)
----------------------------------------------------------------
with key select
seg <=
"100" & "0000" when 0, -- 0
"111" & "1001" when 1, -- 1
"010" & "0100" when 2, -- 2
"011" & "0000" when 3, -- 3
"001" & "1001" when 4, -- 4
"001" & "0010" when 5, -- 5
"000" & "0010" when 6, -- 6
"111" & "1000" when 7, -- 7
"000" & "0000" when 8, -- 8
"001" & "0000" when 9, -- 9
"000" & "1000" when 10, -- A
"000" & "0011" when 11, -- b
"100" & "0110" when 12, -- C
"010" & "0001" when 13, -- d
"000" & "0110" when 14, -- E
"000" & "1110" when 15, -- F
"111" & "1111" when others; -- blank
----------------------------------------------------------------
-- LED 개별 비트 설정: 기존 코드 그대로 유지
----------------------------------------------------------------
led_out(7) <= '1'; -- LED 7번 ON
led_out(6) <= '1';
led_out(5) <= '1';
led_out(4) <= '0'; -- LED 4번 ON
led_out(3) <= '0';
led_out(2) <= '0';
led_out(1) <= '1';
led_out(0) <= '1'; -- LED 0번 ON
end architecture;
```
---
+109
View File
@@ -0,0 +1,109 @@
# KEY IN 7SEG
실습키트의 키의 입력을 받아, 7SEGMENT으로 출력, 출력이 정상적으로 되는지 확인한다.
<div class="image-row">
<div class="image-box">
<img src="../imgs/key_in.png">
<div><b>Keypad</b></div>
</div>
<div class="image-box">
<img src="../imgs/seg.png">
<div><b>7-Segment</b></div>
</div>
</div>
## PIN 테이블
| 핀 번호 | 신호 |
|---------|------|
| PIN_AA13 | led_out[0] |
| PIN_AA14 | led_out[1] |
| PIN_AA15 | led_out[2] |
| PIN_AA16 | led_out[3] |
| PIN_AA17 | led_out[4] |
| PIN_AA18 | led_out[5] |
| PIN_AA19 | led_out[6] |
| PIN_AA20 | led_out[7] |
| PIN_AB14 | seg[6] |
| PIN_AB15 | seg[5] |
| PIN_AB16 | seg[4] |
| PIN_AB17 | seg[3] |
| PIN_AB18 | seg[2] |
| PIN_AB19 | seg[1] |
| PIN_AB20 | seg[0] |
## VHDL 코드
```vhdl
library ieee;
use ieee.std_logic_1164.all;
entity seg_out is
port(
seg : out std_logic_vector(6 downto 0); -- 7-세그 출력 (g~a)
led_out : out std_logic_vector(0 to 7) -- 기존 인덱스(0 to 7)
);
end seg_out;
architecture SegmentDecoder of seg_out is
signal key : integer range 0 to 15 := 5; -- 표시할 숫자 (0~15)
begin
----------------------------------------------------------------
-- with-select: key 값 → seg 패턴 매핑 (VHDL-93 호환)
----------------------------------------------------------------
with key select
seg <=
"100" & "0000" when 0, -- 0
"111" & "1001" when 1, -- 1
"010" & "0100" when 2, -- 2
"011" & "0000" when 3, -- 3
"001" & "1001" when 4, -- 4
"001" & "0010" when 5, -- 5
"000" & "0010" when 6, -- 6
"111" & "1000" when 7, -- 7
"000" & "0000" when 8, -- 8
"001" & "0000" when 9, -- 9
"000" & "1000" when 10, -- A
"000" & "0011" when 11, -- b
"100" & "0110" when 12, -- C
"010" & "0001" when 13, -- d
"000" & "0110" when 14, -- E
"000" & "1110" when 15, -- F
"111" & "1111" when others; -- blank
----------------------------------------------------------------
-- LED 개별 비트 설정: 기존 코드 그대로 유지
----------------------------------------------------------------
led_out(7) <= '1'; -- LED 7번 ON
led_out(6) <= '1';
led_out(5) <= '1';
led_out(4) <= '0'; -- LED 4번 ON
led_out(3) <= '0';
led_out(2) <= '0';
led_out(1) <= '1';
led_out(0) <= '1'; -- LED 0번 ON
end architecture;
```
---
+138
View File
@@ -0,0 +1,138 @@
# CLK AT 7SEG
CLK을 입력받아. 7SEGMENT 값들이 증가되어 출력되도록 한다.
![내 사진](imgs/seg.png)
---
## PIN 테이블
| 핀 번호 | 신호 |
|---------|------|
| PIN_AA13 | led_out[0] |
| PIN_AA14 | led_out[1] |
| PIN_AA15 | led_out[2] |
| PIN_AA16 | led_out[3] |
| PIN_AA17 | led_out[4] |
| PIN_AA18 | led_out[5] |
| PIN_AA19 | led_out[6] |
| PIN_AA20 | led_out[7] |
| PIN_AB14 | seg[6] |
| PIN_AB15 | seg[5] |
| PIN_AB16 | seg[4] |
| PIN_AB17 | seg[3] |
| PIN_AB18 | seg[2] |
| PIN_AB19 | seg[1] |
| PIN_AB20 | seg[0] |
| PIN_T2 | clk |
---
## VHDL 코드
```vhdl
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all; -- 정수형 연산용
entity seg_clk is
port(
clk : in std_logic; -- 50MHz 클럭 입력
led_out : out std_logic_vector(0 to 7); -- LED 출력
seg : out std_logic_vector(6 downto 0) -- 7세그 출력
);
end entity;
architecture rtl of seg_clk is
----------------------------------------------------------------
-- 신호 선언
----------------------------------------------------------------
signal cnt : unsigned(25 downto 0) := (others => '0'); -- 50MHz → 1Hz 분주용
signal sec_tick : std_logic := '0'; -- 1초 펄스
signal num : unsigned(3 downto 0) := (others => '0'); -- 0~15 카운트
begin
----------------------------------------------------------------
-- 50MHz → 1Hz 분주기 (1초마다 sec_tick='1')
----------------------------------------------------------------
process(clk)
begin
if rising_edge(clk) then
if cnt = 49_999_999 then -- 50,000,000 - 1
cnt <= (others => '0');
sec_tick <= '1';
else
cnt <= cnt + 1;
sec_tick <= '0';
end if;
end if;
end process;
----------------------------------------------------------------
-- 초당 1회 숫자 증가 (0~15 순환)
----------------------------------------------------------------
process(clk)
begin
if rising_edge(clk) then
if sec_tick = '1' then
if num = 15 then
num <= (others => '0');
else
num <= num + 1;
end if;
end if;
end if;
end process;
----------------------------------------------------------------
-- 숫자 → 7세그 변환
----------------------------------------------------------------
with num select
seg <=
("100" & "0000") when "0000", -- 0
("111" & "1001") when "0001", -- 1
("010" & "0100") when "0010", -- 2
("011" & "0000") when "0011", -- 3
("001" & "1001") when "0100", -- 4
("001" & "0010") when "0101", -- 5
("000" & "0010") when "0110", -- 6
("111" & "1000") when "0111", -- 7
("000" & "0000") when "1000", -- 8
("001" & "0000") when "1001", -- 9
("000" & "1000") when "1010", -- A
("000" & "0011") when "1011", -- b
("100" & "0110") when "1100", -- C
("010" & "0001") when "1101", -- d
("000" & "0110") when "1110", -- E
("000" & "1110") when "1111", -- F
("111" & "1111") when others; -- blank
----------------------------------------------------------------
-- LED 출력 (기존 그대로 유지)
----------------------------------------------------------------
led_out(7) <= '1';
led_out(6) <= '0';
led_out(5) <= '0';
led_out(4) <= '0';
led_out(3) <= '0';
led_out(2) <= '0';
led_out(1) <= '0';
led_out(0) <= '1';
end architecture;
```
---
+58
View File
@@ -0,0 +1,58 @@
# MODE SWITCH
슬라이드 스위치를 이용한 모드 설정에 사용한다.
해당 슬라이드를 입력으로 설정하여 입력되는 값들을 사용한다.
![내 사진](imgs/modesw.png)
---
## PIN 테이블
| 핀 번호 | 신호 |
|---------|------|
| PIN_B3 | dout[1] |
| PIN_B4 | dout[0] |
| PIN_M2 | din[1] |
| PIN_J2 | din[0] |
---
## VHDL 코드
```vhdl
library ieee;
use ieee.std_logic_1164.all;
entity modsw is
port (
din : in std_logic_vector(1 downto 0); -- 8bit 입력
dout : out std_logic_vector(1 downto 0) -- 8bit 출력
);
end modsw;
architecture rtl of modsw is
begin
dout <= din; -- 입력을 그대로 출력
end rtl;
```
---
+51
View File
@@ -0,0 +1,51 @@
사용법
1. ASM을 HEX로 변환
python asmtohex.py led.asm
결과:
led.hex
2. HEX를 COM3로 전송
python hexsend.py led.hex
pyserial 설치:
pip install pyserial
명령어 포맷:
16bit = opcode[15:12] + operand[11:0]
명령어:
NOP 0x0
LOAD n 0x1
INC 0x2
DEC 0x3
JMP addr 0x4
JZ addr 0x5
JNZ addr 0x6
LED_ON 0x7
LED_OFF 0x8
DELAY n 0x9
led.asm 변환 결과:
1005
7000
9064
8000
9064
3000
6001
5008
7000
4008
시리얼 전송 바이트:
10 05 70 00 90 64 80 00 90 64 30 00 60 01 50 08 70 00 40 08
+132
View File
@@ -0,0 +1,132 @@
#!/usr/bin/env python3
import sys
from pathlib import Path
OPCODE = {
"NOP": 0x0,
"LOAD": 0x1,
"INC": 0x2,
"DEC": 0x3,
"JMP": 0x4,
"JZ": 0x5,
"JNZ": 0x6,
"LED_ON": 0x7,
"LED_OFF": 0x8,
"DELAY": 0x9,
}
def remove_comment(line):
return line.split(";")[0].strip()
def parse_number(text):
text = text.strip()
if text.lower().startswith("0x"):
return int(text, 16)
if text.lower().startswith("0b"):
return int(text, 2)
return int(text, 10)
def assemble(asm_text):
labels = {}
instructions = []
pc = 0
# 1차 패스: 라벨 주소 수집
for raw_line in asm_text.splitlines():
line = remove_comment(raw_line)
if not line:
continue
if line.endswith(":"):
label = line[:-1].strip()
if label in labels:
raise ValueError(f"중복 라벨: {label}")
labels[label] = pc
continue
if ":" in line:
label_part, inst_part = line.split(":", 1)
label = label_part.strip()
inst_line = inst_part.strip()
if label in labels:
raise ValueError(f"중복 라벨: {label}")
labels[label] = pc
if inst_line:
instructions.append(inst_line)
pc += 1
continue
instructions.append(line)
pc += 1
machine = []
# 2차 패스: 명령어 변환
for addr, line in enumerate(instructions):
parts = line.replace(",", " ").split()
if not parts:
continue
mnemonic = parts[0].upper()
if mnemonic not in OPCODE:
raise ValueError(f"{addr}: 알 수 없는 명령어: {mnemonic}")
opcode = OPCODE[mnemonic]
operand = 0
if len(parts) >= 2:
arg = parts[1]
if arg in labels:
operand = labels[arg]
else:
operand = parse_number(arg)
if operand < 0 or operand > 0x0FFF:
raise ValueError(f"{addr}: operand 범위 초과 0~4095: {operand}")
word = (opcode << 12) | (operand & 0x0FFF)
machine.append(word)
return machine, labels, instructions
def main():
if len(sys.argv) != 2:
print("사용법: python asmtohex.py led.asm")
sys.exit(1)
asm_path = Path(sys.argv[1])
if not asm_path.exists():
print(f"파일 없음: {asm_path}")
sys.exit(1)
hex_path = asm_path.with_suffix(".hex")
asm_text = asm_path.read_text(encoding="utf-8")
machine, labels, instructions = assemble(asm_text)
with hex_path.open("w", encoding="utf-8") as f:
for word in machine:
f.write(f"{word:04X}\n")
print("라벨:")
for name, addr in labels.items():
print(f" {name} = {addr}")
print()
print("기계어:")
for addr, word in enumerate(machine):
print(f" {addr:02d}: {word:04X} ; {instructions[addr]}")
print()
print(f"HEX 생성 완료: {hex_path}")
if __name__ == "__main__":
main()
+85
View File
@@ -0,0 +1,85 @@
#!/usr/bin/env python3
import sys
import time
from pathlib import Path
try:
import serial
except ImportError:
print("pyserial이 필요합니다.")
print("설치: pip install pyserial")
sys.exit(1)
PORT = "COM3"
BAUD = 115200
def read_hex_file(hex_path):
data = bytearray()
for line_no, raw_line in enumerate(hex_path.read_text(encoding="utf-8").splitlines(), start=1):
line = raw_line.split(";")[0].strip()
if not line:
continue
line = line.replace("0x", "").replace("0X", "")
if len(line) != 4:
raise ValueError(f"{line_no}번째 줄 오류: 16비트 HEX 4자리여야 함: {raw_line}")
word = int(line, 16)
high = (word >> 8) & 0xFF
low = word & 0xFF
data.append(high)
data.append(low)
return data
def main():
if len(sys.argv) != 2:
print("사용법: python hexsend.py led.hex")
sys.exit(1)
hex_path = Path(sys.argv[1])
if not hex_path.exists():
print(f"파일 없음: {hex_path}")
sys.exit(1)
send_data = read_hex_file(hex_path)
send_data.append(0xFF)
send_data.append(0xFF)
print(f"파일: {hex_path}")
print(f"전송 바이트 수: {len(send_data)}")
print("전송 데이터:")
print(send_data.hex(" ").upper())
ser = serial.Serial(
port=PORT,
baudrate=BAUD,
bytesize=serial.EIGHTBITS,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
timeout=1
)
time.sleep(2)
ser.reset_input_buffer()
ser.reset_output_buffer()
ser.write(send_data)
ser.flush()
ser.close()
print()
print(f"{PORT}, {BAUD}bps 전송 완료")
if __name__ == "__main__":
main()
+18
View File
@@ -0,0 +1,18 @@
LOAD 1 ; R0 = 5
LOOP:
LED_ON ; LED 켜기
DELAY 300 ; 대기
LED_OFF ; LED 끄기
DELAY 300 ; 대기
DEC ; R0 = R0 - 1
JNZ LOOP ; R0 != 0이면 LOOP로 이동
JZ END_ON ; R0 == 0이면 END_ON으로 이동
END_ON:
LED_ON ; LED 켠 상태 유지
JMP END_ON ; 무한 반복
+10
View File
@@ -0,0 +1,10 @@
1001
7000
912C
8000
912C
3000
6001
5008
7000
4008
+315
View File
@@ -0,0 +1,315 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity micom is
port (
clk : in std_logic; -- 50MHz
reset : in std_logic; -- High reset
uart_rx : in std_logic;
led : out std_logic
);
end entity;
architecture rtl of micom is
constant CLK_FREQ : integer := 50000000;
constant BAUD_RATE : integer := 115200;
constant BAUD_CNT : integer := CLK_FREQ / BAUD_RATE;
type ram_type is array (0 to 255) of std_logic_vector(15 downto 0);
signal prog_ram : ram_type := (others => x"0000");
type uart_state_type is (
UART_IDLE,
UART_START,
UART_DATA,
UART_STOP
);
signal uart_state : uart_state_type := UART_IDLE;
signal baud_counter : integer range 0 to BAUD_CNT := 0;
signal bit_index : integer range 0 to 7 := 0;
signal rx_shift : std_logic_vector(7 downto 0) := (others => '0');
signal rx_byte : std_logic_vector(7 downto 0) := (others => '0');
signal rx_valid : std_logic := '0';
signal byte_high : std_logic_vector(7 downto 0) := (others => '0');
signal rx_phase : std_logic := '0';
signal wr_addr : integer range 0 to 255 := 0;
signal cpu_run : std_logic := '0';
type cpu_state_type is (
CPU_LOAD_PROGRAM,
CPU_FETCH,
CPU_DECODE,
CPU_DELAY
);
signal cpu_state : cpu_state_type := CPU_LOAD_PROGRAM;
signal pc : integer range 0 to 255 := 0;
signal inst : std_logic_vector(15 downto 0) := x"0000";
signal opcode : std_logic_vector(3 downto 0);
signal operand : unsigned(11 downto 0);
signal r0 : unsigned(15 downto 0) := (others => '0');
signal zflag : std_logic := '0';
signal delay_counter : unsigned(31 downto 0) := (others => '0');
begin
opcode <= inst(15 downto 12);
operand <= unsigned(inst(11 downto 0));
--------------------------------------------------------------------
-- UART RX
--------------------------------------------------------------------
process(clk, reset)
begin
if reset = '1' then
uart_state <= UART_IDLE;
baud_counter <= 0;
bit_index <= 0;
rx_shift <= (others => '0');
rx_byte <= (others => '0');
rx_valid <= '0';
elsif rising_edge(clk) then
rx_valid <= '0';
case uart_state is
when UART_IDLE =>
if uart_rx = '0' then
baud_counter <= BAUD_CNT / 2;
uart_state <= UART_START;
end if;
when UART_START =>
if baud_counter = 0 then
if uart_rx = '0' then
baud_counter <= BAUD_CNT - 1;
bit_index <= 0;
uart_state <= UART_DATA;
else
uart_state <= UART_IDLE;
end if;
else
baud_counter <= baud_counter - 1;
end if;
when UART_DATA =>
if baud_counter = 0 then
rx_shift(bit_index) <= uart_rx;
baud_counter <= BAUD_CNT - 1;
if bit_index = 7 then
uart_state <= UART_STOP;
else
bit_index <= bit_index + 1;
end if;
else
baud_counter <= baud_counter - 1;
end if;
when UART_STOP =>
if baud_counter = 0 then
rx_byte <= rx_shift;
rx_valid <= '1';
uart_state <= UART_IDLE;
else
baud_counter <= baud_counter - 1;
end if;
end case;
end if;
end process;
--------------------------------------------------------------------
-- Loader
-- 실행 중 새 UART 데이터가 들어오면 자동 초기화 후 재다운로드
--------------------------------------------------------------------
process(clk, reset)
variable word_data : std_logic_vector(15 downto 0);
begin
if reset = '1' then
byte_high <= (others => '0');
rx_phase <= '0';
wr_addr <= 0;
cpu_run <= '0';
elsif rising_edge(clk) then
if rx_valid = '1' then
-- CPU 실행 중 새 데이터가 들어오면 기존 실행 중지 후 재다운로드 시작
if cpu_state /= CPU_LOAD_PROGRAM then
wr_addr <= 0;
rx_phase <= '0';
cpu_run <= '0';
byte_high <= rx_byte;
rx_phase <= '1';
else
if rx_phase = '0' then
byte_high <= rx_byte;
rx_phase <= '1';
else
word_data := byte_high & rx_byte;
if word_data = x"FFFF" then
cpu_run <= '1';
rx_phase <= '0';
else
prog_ram(wr_addr) <= word_data;
if wr_addr < 255 then
wr_addr <= wr_addr + 1;
end if;
rx_phase <= '0';
end if;
end if;
end if;
end if;
end if;
end process;
--------------------------------------------------------------------
-- CPU
--------------------------------------------------------------------
process(clk, reset)
begin
if reset = '1' then
cpu_state <= CPU_LOAD_PROGRAM;
pc <= 0;
inst <= x"0000";
r0 <= (others => '0');
zflag <= '0';
delay_counter <= (others => '0');
led <= '0';
elsif rising_edge(clk) then
-- 실행 중 UART 데이터가 들어오면 CPU를 초기화하고 다운로드 모드로 전환
if rx_valid = '1' and cpu_state /= CPU_LOAD_PROGRAM then
cpu_state <= CPU_LOAD_PROGRAM;
pc <= 0;
inst <= x"0000";
r0 <= (others => '0');
zflag <= '0';
delay_counter <= (others => '0');
led <= '0';
else
case cpu_state is
when CPU_LOAD_PROGRAM =>
if cpu_run = '1' then
pc <= 0;
cpu_state <= CPU_FETCH;
end if;
when CPU_FETCH =>
inst <= prog_ram(pc);
if pc < 255 then
pc <= pc + 1;
end if;
cpu_state <= CPU_DECODE;
when CPU_DECODE =>
case opcode is
when x"0" =>
cpu_state <= CPU_FETCH;
when x"1" =>
r0 <= resize(operand, 16);
if operand = 0 then
zflag <= '1';
else
zflag <= '0';
end if;
cpu_state <= CPU_FETCH;
when x"2" =>
r0 <= r0 + 1;
if r0 + 1 = 0 then
zflag <= '1';
else
zflag <= '0';
end if;
cpu_state <= CPU_FETCH;
when x"3" =>
r0 <= r0 - 1;
if r0 - 1 = 0 then
zflag <= '1';
else
zflag <= '0';
end if;
cpu_state <= CPU_FETCH;
when x"4" =>
pc <= to_integer(operand(7 downto 0));
cpu_state <= CPU_FETCH;
when x"5" =>
if zflag = '1' then
pc <= to_integer(operand(7 downto 0));
end if;
cpu_state <= CPU_FETCH;
when x"6" =>
if zflag = '0' then
pc <= to_integer(operand(7 downto 0));
end if;
cpu_state <= CPU_FETCH;
when x"7" =>
led <= '1';
cpu_state <= CPU_FETCH;
when x"8" =>
led <= '0';
cpu_state <= CPU_FETCH;
when x"9" =>
delay_counter <= to_unsigned(to_integer(operand) * 50000, 32);
cpu_state <= CPU_DELAY;
when others =>
cpu_state <= CPU_FETCH;
end case;
when CPU_DELAY =>
if delay_counter = 0 then
cpu_state <= CPU_FETCH;
else
delay_counter <= delay_counter - 1;
end if;
end case;
end if;
end if;
end process;
end architecture;
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 359 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

+78
View File
@@ -0,0 +1,78 @@
# 마이컴 설계
## 어셈블리 언어
```asm
LOAD 10 ; R0 = 5
LOOP:
LED_ON ; LED 켜기
DELAY 1000 ; 대기
LED_OFF ; LED 끄기
DELAY 1000 ; 대기
DEC ; R0 = R0 - 1
JNZ LOOP ; R0 != 0이면 LOOP로 이동
JZ END_ON ; R0 == 0이면 END_ON으로 이동
END_ON:
LED_ON ; LED 켠 상태 유지
JMP END_ON ; 무한 반복
```
## CPU 구성
CPU 내부의 구성은 다음과 같다.
* PC
* ROM
* Decoder
* GPIO
* Delay Counter
* R0
## 명령어
0x1 LOAD n <br>
0x2 INC <br>
0x3 DEC<br>
0x4 JMP addr<br>
0x5 JZ addr<br>
0x6 JNZ addr<br>
0x7 LED_ON<br>
0x8 LED_OFF<br>
0x9 DELAY n<br>
## 컴파일러
어셉블리로 작성된 프로그램을 명령어 코드로 변환된 기계어 언어로 변환해주는 프로그램
```bash
python asmtohex.py led.asm
```
## 프로그램 다운로드
시리얼을 통해서 기계어 hex 파일로 변환된 프로그램을 다운로드 한다.
```
python hexsend.py led.hex
```
+49
View File
@@ -0,0 +1,49 @@
# 명령어 만들기
TINY CPU MICOM을 이용한 LED 를 제어에 필요한 명령어 SET 구성을 한다.
## LED 켜는 명령어
LED를 제어하는데 필요한 어셈블리 언어에 필요한 명령어들어 16bit 단위로 동작하도록 작성한다.
### 명령어 포맷
16bit = opcode[15:12] + operand[11:0]
### 명령어
| Mnemonic | Operand | Opcode (Hex) | Description |
|-----------|---------|--------------|-------------|
| NOP | - | 0x0 | No Operation |
| LOAD | n | 0x1 | Load immediate value into register |
| INC | - | 0x2 | Increment register |
| DEC | - | 0x3 | Decrement register |
| JMP | addr | 0x4 | Unconditional jump |
| JZ | addr | 0x5 | Jump if zero |
| JNZ | addr | 0x6 | Jump if not zero |
| LED_ON | - | 0x7 | Turn LED on |
| LED_OFF | - | 0x8 | Turn LED off |
| DELAY | n | 0x9 | Delay for n time units |
만약 16비트 명령어 형식(상위 4비트 Opcode, 하위 12비트 Operand)을 사용한다면 다음과 같이 정리할 수도 있습니다.
| Opcode | Mnemonic | Format | Example |
|---------|----------|--------------|---------|
| 0x0 | NOP | NOP | 0x0000 |
| 0x1 | LOAD | LOAD n | 0x100A |
| 0x2 | INC | INC | 0x2000 |
| 0x3 | DEC | DEC | 0x3000 |
| 0x4 | JMP | JMP addr | 0x4005 |
| 0x5 | JZ | JZ addr | 0x500A |
| 0x6 | JNZ | JNZ addr | 0x6002 |
| 0x7 | LED_ON | LED_ON | 0x7000 |
| 0x8 | LED_OFF | LED_OFF | 0x8000 |
| 0x9 | DELAY | DELAY n | 0x93E8 |
@@ -0,0 +1,85 @@
# 어셈블러작성
## LED 프로그램작성
LED 를 제어하는 데 필요한 명령어를 구성을 한다.
### C 언어 표현
C 언어로 작성된 프로그램은 다음과 같이 동작하는 프로그램
```c
#include <stdint.h>
void LED_ON(void);
void LED_OFF(void);
void DELAY(uint32_t ms);
int main(void)
{
int R0;
R0 = 10;
LOOP:
LED_ON();
DELAY(1000);
LED_OFF();
DELAY(1000);
R0--;
if (R0 != 0)
goto LOOP;
END_ON:
LED_ON();
while (1)
{
// JMP END_ON
}
return 0;
}
```
### ASM 언어 표현
- [led.asm 다운로드](files/led.asm)
```asm
LOAD 10 ; R0 = 5
LOOP:
LED_ON ; LED 켜기
DELAY 1000 ; 대기
LED_OFF ; LED 끄기
DELAY 1000 ; 대기
DEC ; R0 = R0 - 1
JNZ LOOP ; R0 != 0이면 LOOP로 이동
JZ END_ON ; R0 == 0이면 END_ON으로 이동
END_ON:
LED_ON ; LED 켠 상태 유지
JMP END_ON ; 무한 반복
```
@@ -0,0 +1,169 @@
# 컴파일러작성
어셈블리 언어를 기계어 hex 파일로 변환한다.
## 변환 프로그램 구동
```bash
python asmtohex.py led.asm
```
- [led.asm 다운로드](files/led.asm)
- [led.hex 다운로드](files/led.hex)
![내 사진](imgs/asmtohex.png)
## 변환프로그램
asmtohex.py 파일 이름으로 다음과 파이썬 언어로 작성한다.
- [asmtohex.py 다운로드](files/asmtohex.py)
```python
import sys
from pathlib import Path
OPCODE = {
"NOP": 0x0,
"LOAD": 0x1,
"INC": 0x2,
"DEC": 0x3,
"JMP": 0x4,
"JZ": 0x5,
"JNZ": 0x6,
"LED_ON": 0x7,
"LED_OFF": 0x8,
"DELAY": 0x9,
}
def remove_comment(line):
return line.split(";")[0].strip()
def parse_number(text):
text = text.strip()
if text.lower().startswith("0x"):
return int(text, 16)
if text.lower().startswith("0b"):
return int(text, 2)
return int(text, 10)
def assemble(asm_text):
labels = {}
instructions = []
pc = 0
# 1차 패스: 라벨 주소 수집
for raw_line in asm_text.splitlines():
line = remove_comment(raw_line)
if not line:
continue
if line.endswith(":"):
label = line[:-1].strip()
if label in labels:
raise ValueError(f"중복 라벨: {label}")
labels[label] = pc
continue
if ":" in line:
label_part, inst_part = line.split(":", 1)
label = label_part.strip()
inst_line = inst_part.strip()
if label in labels:
raise ValueError(f"중복 라벨: {label}")
labels[label] = pc
if inst_line:
instructions.append(inst_line)
pc += 1
continue
instructions.append(line)
pc += 1
machine = []
# 2차 패스: 명령어 변환
for addr, line in enumerate(instructions):
parts = line.replace(",", " ").split()
if not parts:
continue
mnemonic = parts[0].upper()
if mnemonic not in OPCODE:
raise ValueError(f"{addr}: 알 수 없는 명령어: {mnemonic}")
opcode = OPCODE[mnemonic]
operand = 0
if len(parts) >= 2:
arg = parts[1]
if arg in labels:
operand = labels[arg]
else:
operand = parse_number(arg)
if operand < 0 or operand > 0x0FFF:
raise ValueError(f"{addr}: operand 범위 초과 0~4095: {operand}")
word = (opcode << 12) | (operand & 0x0FFF)
machine.append(word)
return machine, labels, instructions
def main():
if len(sys.argv) != 2:
print("사용법: python asmtohex.py led.asm")
sys.exit(1)
asm_path = Path(sys.argv[1])
if not asm_path.exists():
print(f"파일 없음: {asm_path}")
sys.exit(1)
hex_path = asm_path.with_suffix(".hex")
asm_text = asm_path.read_text(encoding="utf-8")
machine, labels, instructions = assemble(asm_text)
with hex_path.open("w", encoding="utf-8") as f:
for word in machine:
f.write(f"{word:04X}\n")
print("라벨:")
for name, addr in labels.items():
print(f" {name} = {addr}")
print()
print("기계어:")
for addr, word in enumerate(machine):
print(f" {addr:02d}: {word:04X} ; {instructions[addr]}")
print()
print(f"HEX 생성 완료: {hex_path}")
if __name__ == "__main__":
main()
```
@@ -0,0 +1,111 @@
# 다운로더 작성
기계어 hex 파일로 FPGA 코어로 전송한다.
## 변환 프로그램 구동
```bash
python hexsend.py led.hex
```
![내 사진](imgs/asmtohex.png)
## 변환프로그램
hexsend.py 파일 이름으로 다음과 파이썬 언어로 작성한다.
[hexsend.py 다운로드](files/hexsend.py)
```python
import sys
import time
from pathlib import Path
try:
import serial
except ImportError:
print("pyserial이 필요합니다.")
print("설치: pip install pyserial")
sys.exit(1)
PORT = "COM3"
BAUD = 115200
def read_hex_file(hex_path):
data = bytearray()
for line_no, raw_line in enumerate(hex_path.read_text(encoding="utf-8").splitlines(), start=1):
line = raw_line.split(";")[0].strip()
if not line:
continue
line = line.replace("0x", "").replace("0X", "")
if len(line) != 4:
raise ValueError(f"{line_no}번째 줄 오류: 16비트 HEX 4자리여야 함: {raw_line}")
word = int(line, 16)
high = (word >> 8) & 0xFF
low = word & 0xFF
data.append(high)
data.append(low)
return data
def main():
if len(sys.argv) != 2:
print("사용법: python hexsend.py led.hex")
sys.exit(1)
hex_path = Path(sys.argv[1])
if not hex_path.exists():
print(f"파일 없음: {hex_path}")
sys.exit(1)
send_data = read_hex_file(hex_path)
send_data.append(0xFF)
send_data.append(0xFF)
print(f"파일: {hex_path}")
print(f"전송 바이트 수: {len(send_data)}")
print("전송 데이터:")
print(send_data.hex(" ").upper())
ser = serial.Serial(
port=PORT,
baudrate=BAUD,
bytesize=serial.EIGHTBITS,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
timeout=1
)
time.sleep(2)
ser.reset_input_buffer()
ser.reset_output_buffer()
ser.write(send_data)
ser.flush()
ser.close()
print()
print(f"{PORT}, {BAUD}bps 전송 완료")
if __name__ == "__main__":
main()
```
+417
View File
@@ -0,0 +1,417 @@
# FPGA제작
어셈블리에서 hex 기계어로 변환된 코드를 시리얼로 부터 받아서, 구동하는 프로그램을 VHDL로 작성을 한다.
지금까지 만든 CPU를 이용한다면 구조는 다음과 같습니다.
hex 1차 다운로드 → FF FF → 자동 실행
실행 중 새 hexsend.py 전송
→ 첫 바이트 수신 순간 CPU 정지
→ RAM 주소 0부터 다시 저장
→ FF FF 수신
→ 새 프로그램 자동 실행
## 동작과정 설명
## CPU 구성 블록 설명
| 구성요소 | 역할 | 저장 데이터 | 주요 동작 |
| -------------------- | ---------------- | --------------- | ------------------- |
| PC (Program Counter) | 현재 실행할 명령어 주소 저장 | 명령어 주소 | 다음 명령어 위치 관리 |
| Program RAM | 프로그램 저장 | 기계어(16비트 명령어) | UART로 다운로드된 프로그램 저장 |
| Instruction Decoder | 명령어 해석 | Opcode, Operand | 명령어 종류 판별 |
| R0 Register | 범용 레지스터 | 연산 데이터 | LOAD, INC, DEC 수행 |
| Delay Block | 시간 지연 | Delay Counter | 지정 시간 동안 대기 |
| GPIO | 외부 핀 제어 | LED 상태 | LED ON/OFF |
| UART RX | 프로그램 다운로드 | 수신 데이터 | PC로부터 프로그램 수신 |
| Boot Loader | 프로그램 적재 제어 | RAM 주소 | RAM 저장 및 실행 시작 |
즉 현재 설계는 **UART Bootloader + Program RAM + Tiny CPU** 구조로, Quartus 재합성 없이 `ASM → HEX → UART 다운로드 → 즉시 실행`이 가능한 간단한 MCU 형태입니다.
## 동작 시나리오
```
전원인가
│
▼
CPU_LOAD_PROGRAM
│
UART 프로그램 수신
│
FF FF 수신
│
▼
CPU_FETCH
│
▼
CPU_DECODE
│
▼
CPU_DELAY
│
└───────┐
│
▼
CPU_FETCH
실행 중 UART 데이터 수신
│
▼
CPU_LOAD_PROGRAM
│
새 프로그램 수신
│
FF FF
│
▼
새 프로그램 실행
```
---
## 핀테이블
아래와 같이, VHDL에 사용되는 핀을 대한 할당을 한다.
![내 사진](imgs/pintable.png)
---
## VHDL CODE
[micom.vhdl 다운로드](files/micom.vhdl)
```
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity micom is
port (
clk : in std_logic; -- 50MHz
reset : in std_logic; -- High reset
uart_rx : in std_logic;
led : out std_logic
);
end entity;
architecture rtl of micom is
constant CLK_FREQ : integer := 50000000;
constant BAUD_RATE : integer := 115200;
constant BAUD_CNT : integer := CLK_FREQ / BAUD_RATE;
type ram_type is array (0 to 255) of std_logic_vector(15 downto 0);
signal prog_ram : ram_type := (others => x"0000");
type uart_state_type is (
UART_IDLE,
UART_START,
UART_DATA,
UART_STOP
);
signal uart_state : uart_state_type := UART_IDLE;
signal baud_counter : integer range 0 to BAUD_CNT := 0;
signal bit_index : integer range 0 to 7 := 0;
signal rx_shift : std_logic_vector(7 downto 0) := (others => '0');
signal rx_byte : std_logic_vector(7 downto 0) := (others => '0');
signal rx_valid : std_logic := '0';
signal byte_high : std_logic_vector(7 downto 0) := (others => '0');
signal rx_phase : std_logic := '0';
signal wr_addr : integer range 0 to 255 := 0;
signal cpu_run : std_logic := '0';
type cpu_state_type is (
CPU_LOAD_PROGRAM,
CPU_FETCH,
CPU_DECODE,
CPU_DELAY
);
signal cpu_state : cpu_state_type := CPU_LOAD_PROGRAM;
signal pc : integer range 0 to 255 := 0;
signal inst : std_logic_vector(15 downto 0) := x"0000";
signal opcode : std_logic_vector(3 downto 0);
signal operand : unsigned(11 downto 0);
signal r0 : unsigned(15 downto 0) := (others => '0');
signal zflag : std_logic := '0';
signal delay_counter : unsigned(31 downto 0) := (others => '0');
begin
opcode <= inst(15 downto 12);
operand <= unsigned(inst(11 downto 0));
--------------------------------------------------------------------
-- UART RX
--------------------------------------------------------------------
process(clk, reset)
begin
if reset = '1' then
uart_state <= UART_IDLE;
baud_counter <= 0;
bit_index <= 0;
rx_shift <= (others => '0');
rx_byte <= (others => '0');
rx_valid <= '0';
elsif rising_edge(clk) then
rx_valid <= '0';
case uart_state is
when UART_IDLE =>
if uart_rx = '0' then
baud_counter <= BAUD_CNT / 2;
uart_state <= UART_START;
end if;
when UART_START =>
if baud_counter = 0 then
if uart_rx = '0' then
baud_counter <= BAUD_CNT - 1;
bit_index <= 0;
uart_state <= UART_DATA;
else
uart_state <= UART_IDLE;
end if;
else
baud_counter <= baud_counter - 1;
end if;
when UART_DATA =>
if baud_counter = 0 then
rx_shift(bit_index) <= uart_rx;
baud_counter <= BAUD_CNT - 1;
if bit_index = 7 then
uart_state <= UART_STOP;
else
bit_index <= bit_index + 1;
end if;
else
baud_counter <= baud_counter - 1;
end if;
when UART_STOP =>
if baud_counter = 0 then
rx_byte <= rx_shift;
rx_valid <= '1';
uart_state <= UART_IDLE;
else
baud_counter <= baud_counter - 1;
end if;
end case;
end if;
end process;
--------------------------------------------------------------------
-- Loader
-- 실행 중 새 UART 데이터가 들어오면 자동 초기화 후 재다운로드
--------------------------------------------------------------------
process(clk, reset)
variable word_data : std_logic_vector(15 downto 0);
begin
if reset = '1' then
byte_high <= (others => '0');
rx_phase <= '0';
wr_addr <= 0;
cpu_run <= '0';
elsif rising_edge(clk) then
if rx_valid = '1' then
-- CPU 실행 중 새 데이터가 들어오면 기존 실행 중지 후 재다운로드 시작
if cpu_state /= CPU_LOAD_PROGRAM then
wr_addr <= 0;
rx_phase <= '0';
cpu_run <= '0';
byte_high <= rx_byte;
rx_phase <= '1';
else
if rx_phase = '0' then
byte_high <= rx_byte;
rx_phase <= '1';
else
word_data := byte_high & rx_byte;
if word_data = x"FFFF" then
cpu_run <= '1';
rx_phase <= '0';
else
prog_ram(wr_addr) <= word_data;
if wr_addr < 255 then
wr_addr <= wr_addr + 1;
end if;
rx_phase <= '0';
end if;
end if;
end if;
end if;
end if;
end process;
--------------------------------------------------------------------
-- CPU
--------------------------------------------------------------------
process(clk, reset)
begin
if reset = '1' then
cpu_state <= CPU_LOAD_PROGRAM;
pc <= 0;
inst <= x"0000";
r0 <= (others => '0');
zflag <= '0';
delay_counter <= (others => '0');
led <= '0';
elsif rising_edge(clk) then
-- 실행 중 UART 데이터가 들어오면 CPU를 초기화하고 다운로드 모드로 전환
if rx_valid = '1' and cpu_state /= CPU_LOAD_PROGRAM then
cpu_state <= CPU_LOAD_PROGRAM;
pc <= 0;
inst <= x"0000";
r0 <= (others => '0');
zflag <= '0';
delay_counter <= (others => '0');
led <= '0';
else
case cpu_state is
when CPU_LOAD_PROGRAM =>
if cpu_run = '1' then
pc <= 0;
cpu_state <= CPU_FETCH;
end if;
when CPU_FETCH =>
inst <= prog_ram(pc);
if pc < 255 then
pc <= pc + 1;
end if;
cpu_state <= CPU_DECODE;
when CPU_DECODE =>
case opcode is
when x"0" =>
cpu_state <= CPU_FETCH;
when x"1" =>
r0 <= resize(operand, 16);
if operand = 0 then
zflag <= '1';
else
zflag <= '0';
end if;
cpu_state <= CPU_FETCH;
when x"2" =>
r0 <= r0 + 1;
if r0 + 1 = 0 then
zflag <= '1';
else
zflag <= '0';
end if;
cpu_state <= CPU_FETCH;
when x"3" =>
r0 <= r0 - 1;
if r0 - 1 = 0 then
zflag <= '1';
else
zflag <= '0';
end if;
cpu_state <= CPU_FETCH;
when x"4" =>
pc <= to_integer(operand(7 downto 0));
cpu_state <= CPU_FETCH;
when x"5" =>
if zflag = '1' then
pc <= to_integer(operand(7 downto 0));
end if;
cpu_state <= CPU_FETCH;
when x"6" =>
if zflag = '0' then
pc <= to_integer(operand(7 downto 0));
end if;
cpu_state <= CPU_FETCH;
when x"7" =>
led <= '1';
cpu_state <= CPU_FETCH;
when x"8" =>
led <= '0';
cpu_state <= CPU_FETCH;
when x"9" =>
delay_counter <= to_unsigned(to_integer(operand) * 50000, 32);
cpu_state <= CPU_DELAY;
when others =>
cpu_state <= CPU_FETCH;
end case;
when CPU_DELAY =>
if delay_counter = 0 then
cpu_state <= CPU_FETCH;
else
delay_counter <= delay_counter - 1;
end if;
end case;
end if;
end if;
end process;
end architecture;
```
@@ -0,0 +1,66 @@
# 프로그램 실습
1. 어셈블리 언어로 프로그램을 작성하고
2. 컴파일 하고
3. hex 파일을 다운로드
4. FPGA 실습키트에서 동작을 확인한다.
5. VHDL을 매번 수정,컴파일,다운로드하지 않아도, 프로그램 코드를 변경하여 원하는동작을 바로 실행할 수 있다.
## 프로그램 작성
![내 사진](imgs/asm.png)
R0 의 값을 변경하거나, DELAY 의 값을 변경하여 프로그램을 수정한다.
R0 는 LED가 깜빡이는 횟수를 설정하는 것이며, DELAY 에 설정되는 값은 ms의 값으로 지연값을 나타낸다.
## 프로그램 컴파일
```bash
python asmtohex.py led.asm
```
![내 사진](imgs/asmtohex.png)
led.hex 파일을 출력한다.
## 프로그램 전송
hexsend.py 을 이용해서 프로그램을 FPGA 로 동작코드를 전송한다.
```bash
python hexsend.py led.hex
```
![내 사진](imgs/hexsend.png)
## 동작상태 확인
프로그램을 수정하여 컴파일 하여 전송하므로써, 속도, 횟수를 자유롭게 변경하여 프로그램 적용하여 구동할 수 있다.
프로그램을 다운로드 하여 즉시 반영된 동작을 확인한다.
![내 사진](imgs/ledonoff.png)
+51
View File
@@ -0,0 +1,51 @@
사용법
1. ASM을 HEX로 변환
python asmtohex.py led.asm
결과:
led.hex
2. HEX를 COM3로 전송
python hexsend.py led.hex
pyserial 설치:
pip install pyserial
명령어 포맷:
16bit = opcode[15:12] + operand[11:0]
명령어:
NOP 0x0
LOAD n 0x1
INC 0x2
DEC 0x3
JMP addr 0x4
JZ addr 0x5
JNZ addr 0x6
LED_ON 0x7
LED_OFF 0x8
DELAY n 0x9
led.asm 변환 결과:
1005
7000
9064
8000
9064
3000
6001
5008
7000
4008
시리얼 전송 바이트:
10 05 70 00 90 64 80 00 90 64 30 00 60 01 50 08 70 00 40 08
+132
View File
@@ -0,0 +1,132 @@
#!/usr/bin/env python3
import sys
from pathlib import Path
OPCODE = {
"NOP": 0x0,
"LOAD": 0x1,
"INC": 0x2,
"DEC": 0x3,
"JMP": 0x4,
"JZ": 0x5,
"JNZ": 0x6,
"LED_ON": 0x7,
"LED_OFF": 0x8,
"DELAY": 0x9,
}
def remove_comment(line):
return line.split(";")[0].strip()
def parse_number(text):
text = text.strip()
if text.lower().startswith("0x"):
return int(text, 16)
if text.lower().startswith("0b"):
return int(text, 2)
return int(text, 10)
def assemble(asm_text):
labels = {}
instructions = []
pc = 0
# 1차 패스: 라벨 주소 수집
for raw_line in asm_text.splitlines():
line = remove_comment(raw_line)
if not line:
continue
if line.endswith(":"):
label = line[:-1].strip()
if label in labels:
raise ValueError(f"중복 라벨: {label}")
labels[label] = pc
continue
if ":" in line:
label_part, inst_part = line.split(":", 1)
label = label_part.strip()
inst_line = inst_part.strip()
if label in labels:
raise ValueError(f"중복 라벨: {label}")
labels[label] = pc
if inst_line:
instructions.append(inst_line)
pc += 1
continue
instructions.append(line)
pc += 1
machine = []
# 2차 패스: 명령어 변환
for addr, line in enumerate(instructions):
parts = line.replace(",", " ").split()
if not parts:
continue
mnemonic = parts[0].upper()
if mnemonic not in OPCODE:
raise ValueError(f"{addr}: 알 수 없는 명령어: {mnemonic}")
opcode = OPCODE[mnemonic]
operand = 0
if len(parts) >= 2:
arg = parts[1]
if arg in labels:
operand = labels[arg]
else:
operand = parse_number(arg)
if operand < 0 or operand > 0x0FFF:
raise ValueError(f"{addr}: operand 범위 초과 0~4095: {operand}")
word = (opcode << 12) | (operand & 0x0FFF)
machine.append(word)
return machine, labels, instructions
def main():
if len(sys.argv) != 2:
print("사용법: python asmtohex.py led.asm")
sys.exit(1)
asm_path = Path(sys.argv[1])
if not asm_path.exists():
print(f"파일 없음: {asm_path}")
sys.exit(1)
hex_path = asm_path.with_suffix(".hex")
asm_text = asm_path.read_text(encoding="utf-8")
machine, labels, instructions = assemble(asm_text)
with hex_path.open("w", encoding="utf-8") as f:
for word in machine:
f.write(f"{word:04X}\n")
print("라벨:")
for name, addr in labels.items():
print(f" {name} = {addr}")
print()
print("기계어:")
for addr, word in enumerate(machine):
print(f" {addr:02d}: {word:04X} ; {instructions[addr]}")
print()
print(f"HEX 생성 완료: {hex_path}")
if __name__ == "__main__":
main()
+85
View File
@@ -0,0 +1,85 @@
#!/usr/bin/env python3
import sys
import time
from pathlib import Path
try:
import serial
except ImportError:
print("pyserial이 필요합니다.")
print("설치: pip install pyserial")
sys.exit(1)
PORT = "COM3"
BAUD = 115200
def read_hex_file(hex_path):
data = bytearray()
for line_no, raw_line in enumerate(hex_path.read_text(encoding="utf-8").splitlines(), start=1):
line = raw_line.split(";")[0].strip()
if not line:
continue
line = line.replace("0x", "").replace("0X", "")
if len(line) != 4:
raise ValueError(f"{line_no}번째 줄 오류: 16비트 HEX 4자리여야 함: {raw_line}")
word = int(line, 16)
high = (word >> 8) & 0xFF
low = word & 0xFF
data.append(high)
data.append(low)
return data
def main():
if len(sys.argv) != 2:
print("사용법: python hexsend.py led.hex")
sys.exit(1)
hex_path = Path(sys.argv[1])
if not hex_path.exists():
print(f"파일 없음: {hex_path}")
sys.exit(1)
send_data = read_hex_file(hex_path)
send_data.append(0xFF)
send_data.append(0xFF)
print(f"파일: {hex_path}")
print(f"전송 바이트 수: {len(send_data)}")
print("전송 데이터:")
print(send_data.hex(" ").upper())
ser = serial.Serial(
port=PORT,
baudrate=BAUD,
bytesize=serial.EIGHTBITS,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
timeout=1
)
time.sleep(2)
ser.reset_input_buffer()
ser.reset_output_buffer()
ser.write(send_data)
ser.flush()
ser.close()
print()
print(f"{PORT}, {BAUD}bps 전송 완료")
if __name__ == "__main__":
main()
+18
View File
@@ -0,0 +1,18 @@
LOAD 1 ; R0 = 5
LOOP:
LED_ON ; LED 켜기
DELAY 300 ; 대기
LED_OFF ; LED 끄기
DELAY 300 ; 대기
DEC ; R0 = R0 - 1
JNZ LOOP ; R0 != 0이면 LOOP로 이동
JZ END_ON ; R0 == 0이면 END_ON으로 이동
END_ON:
LED_ON ; LED 켠 상태 유지
JMP END_ON ; 무한 반복
+10
View File
@@ -0,0 +1,10 @@
1001
7000
912C
8000
912C
3000
6001
5008
7000
4008
+315
View File
@@ -0,0 +1,315 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity micom is
port (
clk : in std_logic; -- 50MHz
reset : in std_logic; -- High reset
uart_rx : in std_logic;
led : out std_logic
);
end entity;
architecture rtl of micom is
constant CLK_FREQ : integer := 50000000;
constant BAUD_RATE : integer := 115200;
constant BAUD_CNT : integer := CLK_FREQ / BAUD_RATE;
type ram_type is array (0 to 255) of std_logic_vector(15 downto 0);
signal prog_ram : ram_type := (others => x"0000");
type uart_state_type is (
UART_IDLE,
UART_START,
UART_DATA,
UART_STOP
);
signal uart_state : uart_state_type := UART_IDLE;
signal baud_counter : integer range 0 to BAUD_CNT := 0;
signal bit_index : integer range 0 to 7 := 0;
signal rx_shift : std_logic_vector(7 downto 0) := (others => '0');
signal rx_byte : std_logic_vector(7 downto 0) := (others => '0');
signal rx_valid : std_logic := '0';
signal byte_high : std_logic_vector(7 downto 0) := (others => '0');
signal rx_phase : std_logic := '0';
signal wr_addr : integer range 0 to 255 := 0;
signal cpu_run : std_logic := '0';
type cpu_state_type is (
CPU_LOAD_PROGRAM,
CPU_FETCH,
CPU_DECODE,
CPU_DELAY
);
signal cpu_state : cpu_state_type := CPU_LOAD_PROGRAM;
signal pc : integer range 0 to 255 := 0;
signal inst : std_logic_vector(15 downto 0) := x"0000";
signal opcode : std_logic_vector(3 downto 0);
signal operand : unsigned(11 downto 0);
signal r0 : unsigned(15 downto 0) := (others => '0');
signal zflag : std_logic := '0';
signal delay_counter : unsigned(31 downto 0) := (others => '0');
begin
opcode <= inst(15 downto 12);
operand <= unsigned(inst(11 downto 0));
--------------------------------------------------------------------
-- UART RX
--------------------------------------------------------------------
process(clk, reset)
begin
if reset = '1' then
uart_state <= UART_IDLE;
baud_counter <= 0;
bit_index <= 0;
rx_shift <= (others => '0');
rx_byte <= (others => '0');
rx_valid <= '0';
elsif rising_edge(clk) then
rx_valid <= '0';
case uart_state is
when UART_IDLE =>
if uart_rx = '0' then
baud_counter <= BAUD_CNT / 2;
uart_state <= UART_START;
end if;
when UART_START =>
if baud_counter = 0 then
if uart_rx = '0' then
baud_counter <= BAUD_CNT - 1;
bit_index <= 0;
uart_state <= UART_DATA;
else
uart_state <= UART_IDLE;
end if;
else
baud_counter <= baud_counter - 1;
end if;
when UART_DATA =>
if baud_counter = 0 then
rx_shift(bit_index) <= uart_rx;
baud_counter <= BAUD_CNT - 1;
if bit_index = 7 then
uart_state <= UART_STOP;
else
bit_index <= bit_index + 1;
end if;
else
baud_counter <= baud_counter - 1;
end if;
when UART_STOP =>
if baud_counter = 0 then
rx_byte <= rx_shift;
rx_valid <= '1';
uart_state <= UART_IDLE;
else
baud_counter <= baud_counter - 1;
end if;
end case;
end if;
end process;
--------------------------------------------------------------------
-- Loader
-- 실행 중 새 UART 데이터가 들어오면 자동 초기화 후 재다운로드
--------------------------------------------------------------------
process(clk, reset)
variable word_data : std_logic_vector(15 downto 0);
begin
if reset = '1' then
byte_high <= (others => '0');
rx_phase <= '0';
wr_addr <= 0;
cpu_run <= '0';
elsif rising_edge(clk) then
if rx_valid = '1' then
-- CPU 실행 중 새 데이터가 들어오면 기존 실행 중지 후 재다운로드 시작
if cpu_state /= CPU_LOAD_PROGRAM then
wr_addr <= 0;
rx_phase <= '0';
cpu_run <= '0';
byte_high <= rx_byte;
rx_phase <= '1';
else
if rx_phase = '0' then
byte_high <= rx_byte;
rx_phase <= '1';
else
word_data := byte_high & rx_byte;
if word_data = x"FFFF" then
cpu_run <= '1';
rx_phase <= '0';
else
prog_ram(wr_addr) <= word_data;
if wr_addr < 255 then
wr_addr <= wr_addr + 1;
end if;
rx_phase <= '0';
end if;
end if;
end if;
end if;
end if;
end process;
--------------------------------------------------------------------
-- CPU
--------------------------------------------------------------------
process(clk, reset)
begin
if reset = '1' then
cpu_state <= CPU_LOAD_PROGRAM;
pc <= 0;
inst <= x"0000";
r0 <= (others => '0');
zflag <= '0';
delay_counter <= (others => '0');
led <= '0';
elsif rising_edge(clk) then
-- 실행 중 UART 데이터가 들어오면 CPU를 초기화하고 다운로드 모드로 전환
if rx_valid = '1' and cpu_state /= CPU_LOAD_PROGRAM then
cpu_state <= CPU_LOAD_PROGRAM;
pc <= 0;
inst <= x"0000";
r0 <= (others => '0');
zflag <= '0';
delay_counter <= (others => '0');
led <= '0';
else
case cpu_state is
when CPU_LOAD_PROGRAM =>
if cpu_run = '1' then
pc <= 0;
cpu_state <= CPU_FETCH;
end if;
when CPU_FETCH =>
inst <= prog_ram(pc);
if pc < 255 then
pc <= pc + 1;
end if;
cpu_state <= CPU_DECODE;
when CPU_DECODE =>
case opcode is
when x"0" =>
cpu_state <= CPU_FETCH;
when x"1" =>
r0 <= resize(operand, 16);
if operand = 0 then
zflag <= '1';
else
zflag <= '0';
end if;
cpu_state <= CPU_FETCH;
when x"2" =>
r0 <= r0 + 1;
if r0 + 1 = 0 then
zflag <= '1';
else
zflag <= '0';
end if;
cpu_state <= CPU_FETCH;
when x"3" =>
r0 <= r0 - 1;
if r0 - 1 = 0 then
zflag <= '1';
else
zflag <= '0';
end if;
cpu_state <= CPU_FETCH;
when x"4" =>
pc <= to_integer(operand(7 downto 0));
cpu_state <= CPU_FETCH;
when x"5" =>
if zflag = '1' then
pc <= to_integer(operand(7 downto 0));
end if;
cpu_state <= CPU_FETCH;
when x"6" =>
if zflag = '0' then
pc <= to_integer(operand(7 downto 0));
end if;
cpu_state <= CPU_FETCH;
when x"7" =>
led <= '1';
cpu_state <= CPU_FETCH;
when x"8" =>
led <= '0';
cpu_state <= CPU_FETCH;
when x"9" =>
delay_counter <= to_unsigned(to_integer(operand) * 50000, 32);
cpu_state <= CPU_DELAY;
when others =>
cpu_state <= CPU_FETCH;
end case;
when CPU_DELAY =>
if delay_counter = 0 then
cpu_state <= CPU_FETCH;
else
delay_counter <= delay_counter - 1;
end if;
end case;
end if;
end if;
end process;
end architecture;
Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

+49
View File
@@ -0,0 +1,49 @@
site_name: FPGA 설계 (RCO ALTERA FPGA IV KIT)
theme:
name: material
nav:
- 시작하기: index.md
- 기초실습:
- 1.LEDONOFF: 기초실습/1.LEDONOFF.md
- 2.IN_OUT: 기초실습/2.IN_OUT.md
- 3.CLK: 기초실습/3.CLK.md
- 4.7SEG: 기초실습/4.7SEG.md
- 5.KEY_7SEG: 기초실습/5.KEY_7SEG.md
- 6.CLK_7SEG: 기초실습/6.CLK_7SEG.md
- 7.MODE_SW: 기초실습/7.MODE_SW.md
- 마이컴설계:
- 1.마이컴설계: 소형마이컴/1.마이컴설계.md
- 2.명령어구성: 소형마이컴/2.cmd_set.md
- 3.어셈블러작성: 소형마이컴/3.어셈블러작성.md
- 4.컴파일러작성: 소형마이컴/4.컴파일러작성.md
- 5.다운로더작성: 소형마이컴/5.다운로더작성.md
- 6.FPGA제작: 소형마이컴/6.FPGA제작.md
- 7.프로그램실습: 소형마이컴/7.프로그램실습.md
- MATLAB/SIMULINK:
- 1.FPGA모델기반설계: simulink/1.모델기반설계.md
- 2.기능정의: simulink/2.기능정의.md
- 3.시뮬링크작성: simulink/3.시뮬링크작성.md
- 4.VHDL코드생성: simulink/4.VHDL코드.md
markdown_extensions:
- pymdownx.arithmatex:
generic: true
extra_javascript:
- js/mathjax.js
- https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js
extra_css:
- stylesheets/extra.css
+778
View File
@@ -0,0 +1,778 @@
<!doctype html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="icon" href="/assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.5.36">
<title>FPGA 설계 (RCO ALTERA FPGA IV KIT)</title>
<link rel="stylesheet" href="/assets/stylesheets/main.06209087.min.css">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&display=fallback">
<style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style>
<link rel="stylesheet" href="/stylesheets/extra.css">
<script>__md_scope=new URL("/",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
</head>
<body dir="ltr">
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" for="__drawer"></label>
<div data-md-component="skip">
</div>
<div data-md-component="announce">
</div>
<header class="md-header md-header--shadow" data-md-component="header">
<nav class="md-header__inner md-grid" aria-label="Header">
<a href="/." title="FPGA 설계 (RCO ALTERA FPGA IV KIT)" class="md-header__button md-logo" aria-label="FPGA 설계 (RCO ALTERA FPGA IV KIT)" data-md-component="logo">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"/></svg>
</a>
<label class="md-header__button md-icon" for="__drawer">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg>
</label>
<div class="md-header__title" data-md-component="header-title">
<div class="md-header__ellipsis">
<div class="md-header__topic">
<span class="md-ellipsis">
FPGA 설계 (RCO ALTERA FPGA IV KIT)
</span>
</div>
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
</span>
</div>
</div>
</div>
<script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script>
<label class="md-header__button md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
</label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
<label class="md-search__icon md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg>
</label>
<nav class="md-search__options" aria-label="Search">
<button type="reset" class="md-search__icon md-icon" title="Clear" aria-label="Clear" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
</button>
</nav>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" tabindex="0" data-md-scrollfix>
<div class="md-search-result" data-md-component="search-result">
<div class="md-search-result__meta">
Initializing search
</div>
<ol class="md-search-result__list" role="presentation"></ol>
</div>
</div>
</div>
</div>
</div>
</nav>
</header>
<div class="md-container" data-md-component="container">
<main class="md-main" data-md-component="main">
<div class="md-main__inner md-grid">
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary" aria-label="Navigation" data-md-level="0">
<label class="md-nav__title" for="__drawer">
<a href="/." title="FPGA 설계 (RCO ALTERA FPGA IV KIT)" class="md-nav__button md-logo" aria-label="FPGA 설계 (RCO ALTERA FPGA IV KIT)" data-md-component="logo">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"/></svg>
</a>
FPGA 설계 (RCO ALTERA FPGA IV KIT)
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="/." class="md-nav__link">
<span class="md-ellipsis">
시작하기
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2" >
<label class="md-nav__link" for="__nav_2" id="__nav_2_label" tabindex="0">
<span class="md-ellipsis">
기초실습
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_2_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_2">
<span class="md-nav__icon md-icon"></span>
기초실습
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="/%EA%B8%B0%EC%B4%88%EC%8B%A4%EC%8A%B5/1.LEDONOFF/" class="md-nav__link">
<span class="md-ellipsis">
1.LEDONOFF
</span>
</a>
</li>
<li class="md-nav__item">
<a href="/%EA%B8%B0%EC%B4%88%EC%8B%A4%EC%8A%B5/2.IN_OUT/" class="md-nav__link">
<span class="md-ellipsis">
2.IN_OUT
</span>
</a>
</li>
<li class="md-nav__item">
<a href="/%EA%B8%B0%EC%B4%88%EC%8B%A4%EC%8A%B5/3.CLK/" class="md-nav__link">
<span class="md-ellipsis">
3.CLK
</span>
</a>
</li>
<li class="md-nav__item">
<a href="/%EA%B8%B0%EC%B4%88%EC%8B%A4%EC%8A%B5/4.7SEG/" class="md-nav__link">
<span class="md-ellipsis">
4.7SEG
</span>
</a>
</li>
<li class="md-nav__item">
<a href="/%EA%B8%B0%EC%B4%88%EC%8B%A4%EC%8A%B5/5.KEY_7SEG/" class="md-nav__link">
<span class="md-ellipsis">
5.KEY_7SEG
</span>
</a>
</li>
<li class="md-nav__item">
<a href="/%EA%B8%B0%EC%B4%88%EC%8B%A4%EC%8A%B5/6.CLK_7SEG/" class="md-nav__link">
<span class="md-ellipsis">
6.CLK_7SEG
</span>
</a>
</li>
<li class="md-nav__item">
<a href="/%EA%B8%B0%EC%B4%88%EC%8B%A4%EC%8A%B5/7.MODE_SW/" class="md-nav__link">
<span class="md-ellipsis">
7.MODE_SW
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_3" >
<label class="md-nav__link" for="__nav_3" id="__nav_3_label" tabindex="0">
<span class="md-ellipsis">
마이컴설계
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_3_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_3">
<span class="md-nav__icon md-icon"></span>
마이컴설계
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="/%EC%86%8C%ED%98%95%EB%A7%88%EC%9D%B4%EC%BB%B4/1.%EB%A7%88%EC%9D%B4%EC%BB%B4%EC%84%A4%EA%B3%84/" class="md-nav__link">
<span class="md-ellipsis">
1.마이컴설계
</span>
</a>
</li>
<li class="md-nav__item">
<a href="/%EC%86%8C%ED%98%95%EB%A7%88%EC%9D%B4%EC%BB%B4/2.cmd_set/" class="md-nav__link">
<span class="md-ellipsis">
2.명령어구성
</span>
</a>
</li>
<li class="md-nav__item">
<a href="/%EC%86%8C%ED%98%95%EB%A7%88%EC%9D%B4%EC%BB%B4/3.%EC%96%B4%EC%85%88%EB%B8%94%EB%9F%AC%EC%9E%91%EC%84%B1/" class="md-nav__link">
<span class="md-ellipsis">
3.어셈블러작성
</span>
</a>
</li>
<li class="md-nav__item">
<a href="/%EC%86%8C%ED%98%95%EB%A7%88%EC%9D%B4%EC%BB%B4/4.%EC%BB%B4%ED%8C%8C%EC%9D%BC%EB%9F%AC%EC%9E%91%EC%84%B1/" class="md-nav__link">
<span class="md-ellipsis">
4.컴파일러작성
</span>
</a>
</li>
<li class="md-nav__item">
<a href="/%EC%86%8C%ED%98%95%EB%A7%88%EC%9D%B4%EC%BB%B4/5.%EB%8B%A4%EC%9A%B4%EB%A1%9C%EB%8D%94%EC%9E%91%EC%84%B1/" class="md-nav__link">
<span class="md-ellipsis">
5.다운로더작성
</span>
</a>
</li>
<li class="md-nav__item">
<a href="/%EC%86%8C%ED%98%95%EB%A7%88%EC%9D%B4%EC%BB%B4/6.FPGA%EC%A0%9C%EC%9E%91/" class="md-nav__link">
<span class="md-ellipsis">
6.FPGA제작
</span>
</a>
</li>
<li class="md-nav__item">
<a href="/%EC%86%8C%ED%98%95%EB%A7%88%EC%9D%B4%EC%BB%B4/7.%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8%EC%8B%A4%EC%8A%B5/" class="md-nav__link">
<span class="md-ellipsis">
7.프로그램실습
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_4" >
<label class="md-nav__link" for="__nav_4" id="__nav_4_label" tabindex="0">
<span class="md-ellipsis">
MATLAB/SIMULINK
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_4_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_4">
<span class="md-nav__icon md-icon"></span>
MATLAB/SIMULINK
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="/simulink/1.%EB%AA%A8%EB%8D%B8%EA%B8%B0%EB%B0%98%EC%84%A4%EA%B3%84/" class="md-nav__link">
<span class="md-ellipsis">
1.FPGA모델기반설계
</span>
</a>
</li>
<li class="md-nav__item">
<a href="/simulink/2.%EA%B8%B0%EB%8A%A5%EC%A0%95%EC%9D%98/" class="md-nav__link">
<span class="md-ellipsis">
2.기능정의
</span>
</a>
</li>
<li class="md-nav__item">
<a href="/simulink/3.%EC%8B%9C%EB%AE%AC%EB%A7%81%ED%81%AC%EC%9E%91%EC%84%B1/" class="md-nav__link">
<span class="md-ellipsis">
3.시뮬링크작성
</span>
</a>
</li>
<li class="md-nav__item">
<a href="/simulink/4.VHDL%EC%BD%94%EB%93%9C/" class="md-nav__link">
<span class="md-ellipsis">
4.VHDL코드생성
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
</nav>
</div>
</div>
</div>
<div class="md-content" data-md-component="content">
<article class="md-content__inner md-typeset">
<h1>404 - Not found</h1>
</article>
</div>
<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
</div>
</main>
<footer class="md-footer">
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-copyright">
Made with
<a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
Material for MkDocs
</a>
</div>
</div>
</div>
</footer>
</div>
<div class="md-dialog" data-md-component="dialog">
<div class="md-dialog__inner md-typeset"></div>
</div>
<script id="__config" type="application/json">{"base": "/", "features": [], "search": "/assets/javascripts/workers/search.6ce7567c.min.js", "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}}</script>
<script src="/assets/javascripts/bundle.56dfad97.min.js"></script>
<script src="/js/mathjax.js"></script>
<script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
</body>
</html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+18
View File
@@ -0,0 +1,18 @@
/*!
* Lunr languages, `Danish` language
* https://github.com/MihaiValentin/lunr-languages
*
* Copyright 2014, Mihai Valentin
* http://www.mozilla.org/MPL/
*/
/*!
* based on
* Snowball JavaScript Library v0.3
* http://code.google.com/p/urim/
* http://snowball.tartarus.org/
*
* Copyright 2010, Oleg Mazko
* http://www.mozilla.org/MPL/
*/
!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.da=function(){this.pipeline.reset(),this.pipeline.add(e.da.trimmer,e.da.stopWordFilter,e.da.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.da.stemmer))},e.da.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.da.trimmer=e.trimmerSupport.generateTrimmer(e.da.wordCharacters),e.Pipeline.registerFunction(e.da.trimmer,"trimmer-da"),e.da.stemmer=function(){var r=e.stemmerSupport.Among,i=e.stemmerSupport.SnowballProgram,n=new function(){function e(){var e,r=f.cursor+3;if(d=f.limit,0<=r&&r<=f.limit){for(a=r;;){if(e=f.cursor,f.in_grouping(w,97,248)){f.cursor=e;break}if(f.cursor=e,e>=f.limit)return;f.cursor++}for(;!f.out_grouping(w,97,248);){if(f.cursor>=f.limit)return;f.cursor++}d=f.cursor,d<a&&(d=a)}}function n(){var e,r;if(f.cursor>=d&&(r=f.limit_backward,f.limit_backward=d,f.ket=f.cursor,e=f.find_among_b(c,32),f.limit_backward=r,e))switch(f.bra=f.cursor,e){case 1:f.slice_del();break;case 2:f.in_grouping_b(p,97,229)&&f.slice_del()}}function t(){var e,r=f.limit-f.cursor;f.cursor>=d&&(e=f.limit_backward,f.limit_backward=d,f.ket=f.cursor,f.find_among_b(l,4)?(f.bra=f.cursor,f.limit_backward=e,f.cursor=f.limit-r,f.cursor>f.limit_backward&&(f.cursor--,f.bra=f.cursor,f.slice_del())):f.limit_backward=e)}function s(){var e,r,i,n=f.limit-f.cursor;if(f.ket=f.cursor,f.eq_s_b(2,"st")&&(f.bra=f.cursor,f.eq_s_b(2,"ig")&&f.slice_del()),f.cursor=f.limit-n,f.cursor>=d&&(r=f.limit_backward,f.limit_backward=d,f.ket=f.cursor,e=f.find_among_b(m,5),f.limit_backward=r,e))switch(f.bra=f.cursor,e){case 1:f.slice_del(),i=f.limit-f.cursor,t(),f.cursor=f.limit-i;break;case 2:f.slice_from("løs")}}function o(){var e;f.cursor>=d&&(e=f.limit_backward,f.limit_backward=d,f.ket=f.cursor,f.out_grouping_b(w,97,248)?(f.bra=f.cursor,u=f.slice_to(u),f.limit_backward=e,f.eq_v_b(u)&&f.slice_del()):f.limit_backward=e)}var a,d,u,c=[new r("hed",-1,1),new r("ethed",0,1),new r("ered",-1,1),new r("e",-1,1),new r("erede",3,1),new r("ende",3,1),new r("erende",5,1),new r("ene",3,1),new r("erne",3,1),new r("ere",3,1),new r("en",-1,1),new r("heden",10,1),new r("eren",10,1),new r("er",-1,1),new r("heder",13,1),new r("erer",13,1),new r("s",-1,2),new r("heds",16,1),new r("es",16,1),new r("endes",18,1),new r("erendes",19,1),new r("enes",18,1),new r("ernes",18,1),new r("eres",18,1),new r("ens",16,1),new r("hedens",24,1),new r("erens",24,1),new r("ers",16,1),new r("ets",16,1),new r("erets",28,1),new r("et",-1,1),new r("eret",30,1)],l=[new r("gd",-1,-1),new r("dt",-1,-1),new r("gt",-1,-1),new r("kt",-1,-1)],m=[new r("ig",-1,1),new r("lig",0,1),new r("elig",1,1),new r("els",-1,1),new r("løst",-1,2)],w=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,48,0,128],p=[239,254,42,3,0,0,0,0,0,0,0,0,0,0,0,0,16],f=new i;this.setCurrent=function(e){f.setCurrent(e)},this.getCurrent=function(){return f.getCurrent()},this.stem=function(){var r=f.cursor;return e(),f.limit_backward=r,f.cursor=f.limit,n(),f.cursor=f.limit,t(),f.cursor=f.limit,s(),f.cursor=f.limit,o(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}}(),e.Pipeline.registerFunction(e.da.stemmer,"stemmer-da"),e.da.stopWordFilter=e.generateStopWordFilter("ad af alle alt anden at blev blive bliver da de dem den denne der deres det dette dig din disse dog du efter eller en end er et for fra ham han hans har havde have hende hendes her hos hun hvad hvis hvor i ikke ind jeg jer jo kunne man mange med meget men mig min mine mit mod ned noget nogle nu når og også om op os over på selv sig sin sine sit skal skulle som sådan thi til ud under var vi vil ville vor være været".split(" ")),e.Pipeline.registerFunction(e.da.stopWordFilter,"stopWordFilter-da")}});
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.hi=function(){this.pipeline.reset(),this.pipeline.add(e.hi.trimmer,e.hi.stopWordFilter,e.hi.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.hi.stemmer))},e.hi.wordCharacters="ऀ-ःऄ-एऐ-टठ-यर-िी-ॏॐ-य़ॠ-९॰-ॿa-zA-Za-zA-Z0-90-9",e.hi.trimmer=e.trimmerSupport.generateTrimmer(e.hi.wordCharacters),e.Pipeline.registerFunction(e.hi.trimmer,"trimmer-hi"),e.hi.stopWordFilter=e.generateStopWordFilter("अत अपना अपनी अपने अभी अंदर आदि आप इत्यादि इन इनका इन्हीं इन्हें इन्हों इस इसका इसकी इसके इसमें इसी इसे उन उनका उनकी उनके उनको उन्हीं उन्हें उन्हों उस उसके उसी उसे एक एवं एस ऐसे और कई कर करता करते करना करने करें कहते कहा का काफ़ी कि कितना किन्हें किन्हों किया किर किस किसी किसे की कुछ कुल के को कोई कौन कौनसा गया घर जब जहाँ जा जितना जिन जिन्हें जिन्हों जिस जिसे जीधर जैसा जैसे जो तक तब तरह तिन तिन्हें तिन्हों तिस तिसे तो था थी थे दबारा दिया दुसरा दूसरे दो द्वारा न नके नहीं ना निहायत नीचे ने पर पहले पूरा पे फिर बनी बही बहुत बाद बाला बिलकुल भी भीतर मगर मानो मे में यदि यह यहाँ यही या यिह ये रखें रहा रहे ऱ्वासा लिए लिये लेकिन व वग़ैरह वर्ग वह वहाँ वहीं वाले वुह वे वो सकता सकते सबसे सभी साथ साबुत साभ सारा से सो संग ही हुआ हुई हुए है हैं हो होता होती होते होना होने".split(" ")),e.hi.stemmer=function(){return function(e){return"function"==typeof e.update?e.update(function(e){return e}):e}}();var r=e.wordcut;r.init(),e.hi.tokenizer=function(i){if(!arguments.length||null==i||void 0==i)return[];if(Array.isArray(i))return i.map(function(r){return isLunr2?new e.Token(r.toLowerCase()):r.toLowerCase()});var t=i.toString().toLowerCase().replace(/^\s+/,"");return r.cut(t).split("|")},e.Pipeline.registerFunction(e.hi.stemmer,"stemmer-hi"),e.Pipeline.registerFunction(e.hi.stopWordFilter,"stopWordFilter-hi")}});
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.hy=function(){this.pipeline.reset(),this.pipeline.add(e.hy.trimmer,e.hy.stopWordFilter)},e.hy.wordCharacters="[A-Za-z԰-֏ff-ﭏ]",e.hy.trimmer=e.trimmerSupport.generateTrimmer(e.hy.wordCharacters),e.Pipeline.registerFunction(e.hy.trimmer,"trimmer-hy"),e.hy.stopWordFilter=e.generateStopWordFilter("դու և եք էիր էիք հետո նաև նրանք որը վրա է որ պիտի են այս մեջ ն իր ու ի այդ որոնք այն կամ էր մի ես համար այլ իսկ էին ենք հետ ին թ էինք մենք նրա նա դուք եմ էի ըստ որպես ում".split(" ")),e.Pipeline.registerFunction(e.hy.stopWordFilter,"stopWordFilter-hy"),e.hy.stemmer=function(){return function(e){return"function"==typeof e.update?e.update(function(e){return e}):e}}(),e.Pipeline.registerFunction(e.hy.stemmer,"stemmer-hy")}});
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var r="2"==e.version[0];e.ja=function(){this.pipeline.reset(),this.pipeline.add(e.ja.trimmer,e.ja.stopWordFilter,e.ja.stemmer),r?this.tokenizer=e.ja.tokenizer:(e.tokenizer&&(e.tokenizer=e.ja.tokenizer),this.tokenizerFn&&(this.tokenizerFn=e.ja.tokenizer))};var t=new e.TinySegmenter;e.ja.tokenizer=function(i){var n,o,s,p,a,u,m,l,c,f;if(!arguments.length||null==i||void 0==i)return[];if(Array.isArray(i))return i.map(function(t){return r?new e.Token(t.toLowerCase()):t.toLowerCase()});for(o=i.toString().toLowerCase().replace(/^\s+/,""),n=o.length-1;n>=0;n--)if(/\S/.test(o.charAt(n))){o=o.substring(0,n+1);break}for(a=[],s=o.length,c=0,l=0;c<=s;c++)if(u=o.charAt(c),m=c-l,u.match(/\s/)||c==s){if(m>0)for(p=t.segment(o.slice(l,c)).filter(function(e){return!!e}),f=l,n=0;n<p.length;n++)r?a.push(new e.Token(p[n],{position:[f,p[n].length],index:a.length})):a.push(p[n]),f+=p[n].length;l=c+1}return a},e.ja.stemmer=function(){return function(e){return e}}(),e.Pipeline.registerFunction(e.ja.stemmer,"stemmer-ja"),e.ja.wordCharacters="一二三四五六七八九十百千万億兆一-龠々〆ヵヶぁ-んァ-ヴーア-ン゙a-zA-Za-zA-Z0-90-9",e.ja.trimmer=e.trimmerSupport.generateTrimmer(e.ja.wordCharacters),e.Pipeline.registerFunction(e.ja.trimmer,"trimmer-ja"),e.ja.stopWordFilter=e.generateStopWordFilter("これ それ あれ この その あの ここ そこ あそこ こちら どこ だれ なに なん 何 私 貴方 貴方方 我々 私達 あの人 あのかた 彼女 彼 です あります おります います は が の に を で え から まで より も どの と し それで しかし".split(" ")),e.Pipeline.registerFunction(e.ja.stopWordFilter,"stopWordFilter-ja"),e.jp=e.ja,e.Pipeline.registerFunction(e.jp.stemmer,"stemmer-jp"),e.Pipeline.registerFunction(e.jp.trimmer,"trimmer-jp"),e.Pipeline.registerFunction(e.jp.stopWordFilter,"stopWordFilter-jp")}});
+1
View File
@@ -0,0 +1 @@
module.exports=require("./lunr.ja");
+1
View File
@@ -0,0 +1 @@
!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.kn=function(){this.pipeline.reset(),this.pipeline.add(e.kn.trimmer,e.kn.stopWordFilter,e.kn.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.kn.stemmer))},e.kn.wordCharacters="ಀ-಄ಅ-ಔಕ-ಹಾ-ೌ಼-ಽೕ-ೖೝ-ೞೠ-ೡೢ-ೣ೤೥೦-೯ೱ-ೳ",e.kn.trimmer=e.trimmerSupport.generateTrimmer(e.kn.wordCharacters),e.Pipeline.registerFunction(e.kn.trimmer,"trimmer-kn"),e.kn.stopWordFilter=e.generateStopWordFilter("ಮತ್ತು ಈ ಒಂದು ರಲ್ಲಿ ಹಾಗೂ ಎಂದು ಅಥವಾ ಇದು ರ ಅವರು ಎಂಬ ಮೇಲೆ ಅವರ ತನ್ನ ಆದರೆ ತಮ್ಮ ನಂತರ ಮೂಲಕ ಹೆಚ್ಚು ನ ಆ ಕೆಲವು ಅನೇಕ ಎರಡು ಹಾಗು ಪ್ರಮುಖ ಇದನ್ನು ಇದರ ಸುಮಾರು ಅದರ ಅದು ಮೊದಲ ಬಗ್ಗೆ ನಲ್ಲಿ ರಂದು ಇತರ ಅತ್ಯಂತ ಹೆಚ್ಚಿನ ಸಹ ಸಾಮಾನ್ಯವಾಗಿ ನೇ ಹಲವಾರು ಹೊಸ ದಿ ಕಡಿಮೆ ಯಾವುದೇ ಹೊಂದಿದೆ ದೊಡ್ಡ ಅನ್ನು ಇವರು ಪ್ರಕಾರ ಇದೆ ಮಾತ್ರ ಕೂಡ ಇಲ್ಲಿ ಎಲ್ಲಾ ವಿವಿಧ ಅದನ್ನು ಹಲವು ರಿಂದ ಕೇವಲ ದ ದಕ್ಷಿಣ ಗೆ ಅವನ ಅತಿ ನೆಯ ಬಹಳ ಕೆಲಸ ಎಲ್ಲ ಪ್ರತಿ ಇತ್ಯಾದಿ ಇವು ಬೇರೆ ಹೀಗೆ ನಡುವೆ ಇದಕ್ಕೆ ಎಸ್ ಇವರ ಮೊದಲು ಶ್ರೀ ಮಾಡುವ ಇದರಲ್ಲಿ ರೀತಿಯ ಮಾಡಿದ ಕಾಲ ಅಲ್ಲಿ ಮಾಡಲು ಅದೇ ಈಗ ಅವು ಗಳು ಎ ಎಂಬುದು ಅವನು ಅಂದರೆ ಅವರಿಗೆ ಇರುವ ವಿಶೇಷ ಮುಂದೆ ಅವುಗಳ ಮುಂತಾದ ಮೂಲ ಬಿ ಮೀ ಒಂದೇ ಇನ್ನೂ ಹೆಚ್ಚಾಗಿ ಮಾಡಿ ಅವರನ್ನು ಇದೇ ಯ ರೀತಿಯಲ್ಲಿ ಜೊತೆ ಅದರಲ್ಲಿ ಮಾಡಿದರು ನಡೆದ ಆಗ ಮತ್ತೆ ಪೂರ್ವ ಆತ ಬಂದ ಯಾವ ಒಟ್ಟು ಇತರೆ ಹಿಂದೆ ಪ್ರಮಾಣದ ಗಳನ್ನು ಕುರಿತು ಯು ಆದ್ದರಿಂದ ಅಲ್ಲದೆ ನಗರದ ಮೇಲಿನ ಏಕೆಂದರೆ ರಷ್ಟು ಎಂಬುದನ್ನು ಬಾರಿ ಎಂದರೆ ಹಿಂದಿನ ಆದರೂ ಆದ ಸಂಬಂಧಿಸಿದ ಮತ್ತೊಂದು ಸಿ ಆತನ ".split(" ")),e.kn.stemmer=function(){return function(e){return"function"==typeof e.update?e.update(function(e){return e}):e}}();var r=e.wordcut;r.init(),e.kn.tokenizer=function(t){if(!arguments.length||null==t||void 0==t)return[];if(Array.isArray(t))return t.map(function(r){return isLunr2?new e.Token(r.toLowerCase()):r.toLowerCase()});var n=t.toString().toLowerCase().replace(/^\s+/,"");return r.cut(n).split("|")},e.Pipeline.registerFunction(e.kn.stemmer,"stemmer-kn"),e.Pipeline.registerFunction(e.kn.stopWordFilter,"stopWordFilter-kn")}});
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
!function(e,t){"function"==typeof define&&define.amd?define(t):"object"==typeof exports?module.exports=t():t()(e.lunr)}(this,function(){return function(e){e.multiLanguage=function(){for(var t=Array.prototype.slice.call(arguments),i=t.join("-"),r="",n=[],s=[],p=0;p<t.length;++p)"en"==t[p]?(r+="\\w",n.unshift(e.stopWordFilter),n.push(e.stemmer),s.push(e.stemmer)):(r+=e[t[p]].wordCharacters,e[t[p]].stopWordFilter&&n.unshift(e[t[p]].stopWordFilter),e[t[p]].stemmer&&(n.push(e[t[p]].stemmer),s.push(e[t[p]].stemmer)));var o=e.trimmerSupport.generateTrimmer(r);return e.Pipeline.registerFunction(o,"lunr-multi-trimmer-"+i),n.unshift(o),function(){this.pipeline.reset(),this.pipeline.add.apply(this.pipeline,n),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add.apply(this.searchPipeline,s))}}}});
File diff suppressed because one or more lines are too long
+18
View File
@@ -0,0 +1,18 @@
/*!
* Lunr languages, `Norwegian` language
* https://github.com/MihaiValentin/lunr-languages
*
* Copyright 2014, Mihai Valentin
* http://www.mozilla.org/MPL/
*/
/*!
* based on
* Snowball JavaScript Library v0.3
* http://code.google.com/p/urim/
* http://snowball.tartarus.org/
*
* Copyright 2010, Oleg Mazko
* http://www.mozilla.org/MPL/
*/
!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.no=function(){this.pipeline.reset(),this.pipeline.add(e.no.trimmer,e.no.stopWordFilter,e.no.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.no.stemmer))},e.no.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.no.trimmer=e.trimmerSupport.generateTrimmer(e.no.wordCharacters),e.Pipeline.registerFunction(e.no.trimmer,"trimmer-no"),e.no.stemmer=function(){var r=e.stemmerSupport.Among,n=e.stemmerSupport.SnowballProgram,i=new function(){function e(){var e,r=w.cursor+3;if(a=w.limit,0<=r||r<=w.limit){for(s=r;;){if(e=w.cursor,w.in_grouping(d,97,248)){w.cursor=e;break}if(e>=w.limit)return;w.cursor=e+1}for(;!w.out_grouping(d,97,248);){if(w.cursor>=w.limit)return;w.cursor++}a=w.cursor,a<s&&(a=s)}}function i(){var e,r,n;if(w.cursor>=a&&(r=w.limit_backward,w.limit_backward=a,w.ket=w.cursor,e=w.find_among_b(m,29),w.limit_backward=r,e))switch(w.bra=w.cursor,e){case 1:w.slice_del();break;case 2:n=w.limit-w.cursor,w.in_grouping_b(c,98,122)?w.slice_del():(w.cursor=w.limit-n,w.eq_s_b(1,"k")&&w.out_grouping_b(d,97,248)&&w.slice_del());break;case 3:w.slice_from("er")}}function t(){var e,r=w.limit-w.cursor;w.cursor>=a&&(e=w.limit_backward,w.limit_backward=a,w.ket=w.cursor,w.find_among_b(u,2)?(w.bra=w.cursor,w.limit_backward=e,w.cursor=w.limit-r,w.cursor>w.limit_backward&&(w.cursor--,w.bra=w.cursor,w.slice_del())):w.limit_backward=e)}function o(){var e,r;w.cursor>=a&&(r=w.limit_backward,w.limit_backward=a,w.ket=w.cursor,e=w.find_among_b(l,11),e?(w.bra=w.cursor,w.limit_backward=r,1==e&&w.slice_del()):w.limit_backward=r)}var s,a,m=[new r("a",-1,1),new r("e",-1,1),new r("ede",1,1),new r("ande",1,1),new r("ende",1,1),new r("ane",1,1),new r("ene",1,1),new r("hetene",6,1),new r("erte",1,3),new r("en",-1,1),new r("heten",9,1),new r("ar",-1,1),new r("er",-1,1),new r("heter",12,1),new r("s",-1,2),new r("as",14,1),new r("es",14,1),new r("edes",16,1),new r("endes",16,1),new r("enes",16,1),new r("hetenes",19,1),new r("ens",14,1),new r("hetens",21,1),new r("ers",14,1),new r("ets",14,1),new r("et",-1,1),new r("het",25,1),new r("ert",-1,3),new r("ast",-1,1)],u=[new r("dt",-1,-1),new r("vt",-1,-1)],l=[new r("leg",-1,1),new r("eleg",0,1),new r("ig",-1,1),new r("eig",2,1),new r("lig",2,1),new r("elig",4,1),new r("els",-1,1),new r("lov",-1,1),new r("elov",7,1),new r("slov",7,1),new r("hetslov",9,1)],d=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,48,0,128],c=[119,125,149,1],w=new n;this.setCurrent=function(e){w.setCurrent(e)},this.getCurrent=function(){return w.getCurrent()},this.stem=function(){var r=w.cursor;return e(),w.limit_backward=r,w.cursor=w.limit,i(),w.cursor=w.limit,t(),w.cursor=w.limit,o(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}}(),e.Pipeline.registerFunction(e.no.stemmer,"stemmer-no"),e.no.stopWordFilter=e.generateStopWordFilter("alle at av bare begge ble blei bli blir blitt både båe da de deg dei deim deira deires dem den denne der dere deres det dette di din disse ditt du dykk dykkar då eg ein eit eitt eller elles en enn er et ett etter for fordi fra før ha hadde han hans har hennar henne hennes her hjå ho hoe honom hoss hossen hun hva hvem hver hvilke hvilken hvis hvor hvordan hvorfor i ikke ikkje ikkje ingen ingi inkje inn inni ja jeg kan kom korleis korso kun kunne kva kvar kvarhelst kven kvi kvifor man mange me med medan meg meget mellom men mi min mine mitt mot mykje ned no noe noen noka noko nokon nokor nokre nå når og også om opp oss over på samme seg selv si si sia sidan siden sin sine sitt sjøl skal skulle slik so som som somme somt så sånn til um upp ut uten var vart varte ved vere verte vi vil ville vore vors vort vår være være vært å".split(" ")),e.Pipeline.registerFunction(e.no.stopWordFilter,"stopWordFilter-no")}});

Some files were not shown because too many files have changed in this diff Show More