hong.com
Final
2025-08-06
2025-08-07
2025-08-08
2025-08-11
2025-08-12
2025-08-13
2025-08-14
2025-08-18
2025-08-19
2025-08-20
2025-08-21
2025-08-27
2025-08-28
2025-08-29
2025-09-01
2025-09-02
2025-09-03
2025-09-04
2025-09-05
2025-09-08
2025-09-09
2025-09-10
2025-09-11
Project
C Language
game instructions
FFT
game instructions
Study
C Language
ARM System Programming
C Programming - Challenges
C programming
Linux
Day1
Day2
Day3
Day4
Day5
Day6
Day7
Day8
SKIN_Project copy
SKIN_Project
perceptron
System Verilog
Day1
Day2
Day3
VLSI Circuits Design
Day1
Subsubcategory 1
Subsubcategory 2
example
Home
Contact
Copyright ยฉ 2024 |
Yankos
Home
> Final
๐ ๆ้ใขใค (โโขแดโขโ)โก โง*ใ
Final
2025-09-11
๋งค๋ฒ ๋นํธ์คํธ๋ฆผํ์ง ์๊ณ ๋ณด๋ ์ผ๋ฉด ๋ฐ๋ก ์ฌ๋ฆด ์ ์๋ ๋ฐฉ๋ฒ ๋นํธ์คํธ๋ฆผ ๋ง๋ ๊ฑธ ๋ณด๋์ ๋ค์ด๋ก๋ํด์ ์ ์ฅ SPI Quad mode Flash : ๋นํธ์คํธ๋ฆผ ๋ค์ด๋ฐ์ ๊ฑธ ์ฝ์ด์ด Settings -> Bitstream -> -bin_file (Check) Generate Bitstream -> binary ํ์ผ์ ๋ง๋ค์ด์ Flash Memory ์ ์ ์ฅ Path : โC:\Working\FPGA_AI_25_2\250910_VGA_OV7670\250910_VGA_OV7670.runs\impl_1\VGA_Camera_Display.binโ Open Target Add Configuration Memory Device -> (Basys3) Manufacturer = Macronix, Density = 32, Name = mx25l3233f-spi-x1_x2_x4 (OK) mx25l3233f-spi-x1_x2_x4 ์ฐํด๋ฆญ -> Program Configuration Memory Device -> Configuration file -> VGA_Camera_Display.bin (OK) FPGA ๋ณด๋ ์ฌ๋ถํ ์ Roding ํ ์๊ฐ์ด ํ์ํจ (QSPI Flash Mode, ์ ์์ธ๊ฐ ์ Data Loading ์๊ฐ์ด 10์ด~1๋ถ ์ ๋)
Final
ยท 2025-09-11
2025-09-10
HW Setting < ov7670 datasheet > SCCB ์ธํฐํ์ด์ค๋ก ํต์ = I2C ์ต๋ 30 frames RGB565/555/444 ์ง์ ์์ฒด Clock์ด ์๊ธฐ ๋๋ฌธ์ ์ธ๋ถ Clock์ ์จ์ผํจ (XCLK) porch๊ฐ ์์. posedge์์ HREF = 1 ์ด๊ณ ์ด๋ ๋์ค๋ Data ์ ํจ 640, 480 ๋ผ์ธ์กด์ฌ VSYNC=H : 1 Frame์ด ๋๋๊ณ ๋ค์ Line์ ๋ฐ์ Back Porch, Front Porch ์ฌ์ด์ ์์์ฒ๋ฆฌ๋ฅผ ๋๋ด์ผ ํจ, Line Buffer ํ์ RGB565 : 16bit Data Format First Byte(8bit) + Second Byte(8bit) = Pixel Data(16bit) Pixel Data Bit = | 76543 | 210 / 765 | 43210 | HREF=H, VSYNC=L ์ผ๋ Data ๋ฐ์ < Block Diagram> ์์ ํ์ํจ Data 2๋ฒ ๋ฐ์์ Memory ์ 1๋ฒ ์ ์ฅ (8bit, 8bit ๋ฐ์์ 16bit ์ ์ฅ) ๊ฐ Data ๋ง๋ค ๊ตฌ๋ถ์ด ํ์ํจ 16bit ๋ฅผ ๋ค ๋ฐ์์ ๋ Address์ Data, WriteEnable ์ ํธ๋ฅผ ๋ด๋ณด๋ ํ Frame ์ ๋ํด ๋ด๋ณด๋ธ ์ ํธ๋ฅผ ์ฒ๋ฆฌํ ๋๋ VGA Decoder ์์ Pclk์ ๋ฐ์์ Frame Buffer ์์ Read Clock ์ผ๋ก ์ฌ์ฉ Frame Buffer ๋ฅผ ๊ธฐ์ค์ผ๋ก ์ข, ์ฐ๋ ๋ค๋ฅธ ํด๋ญ์ด๋ค.(Camera Domain, VGA Display Domain) -> CDC (Clock Domain Crossing) ์นด๋ฉ๋ผ์์๋ QVGA๋ก ๋ค์ด์ด < STM32 CubeIDE > ์ด๋ฐ์ ์นด๋ฉ๋ผ ๋ด๋ถ ์ค์ ์ STM32์์ ๋ด๋ ค์ฃผ๊ธฐ ์ํด ์์ STM32 create Project f411re ๊ฒ์ ํ STM32F411RETx LQFP64 < ๊ธฐ๋ณธ์ค์ > System Core -> RCC (Clock ์ค์ ) : HSE = Crystal/Ceramic Resonator Connectivity -> USART2 (Uart ์ค์ ) : Mode = Asynchronous Connectivity -> I2C1 (I2C ์ค์ ) : I2C = I2C Clock Configuration ๋ค์ด๊ฐ์ ์ค์ ํฑ๋๋ฐํด๋ชจ์ ํด๋ฆญ -> C์ฝ๋๊ฐ ์๋์ผ๋ก ์์ฑ๋จ /* USER CODE BEGIN Header */ /** ****************************************************************************** * @file : main.c * @brief : Main program body ****************************************************************************** * @attention * * Copyright (c) 2025 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** */ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "main.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ I2C_HandleTypeDef hi2c1; UART_HandleTypeDef huart2; /* USER CODE BEGIN PV */ /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_I2C1_Init(void); static void MX_USART2_UART_Init(void); /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ /** * @brief The application entry point. * @retval int */ int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_I2C1_Init(); MX_USART2_UART_Init(); /* USER CODE BEGIN 2 */ /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5); HAL_Delay(300); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ } /** * @brief System Clock Configuration * @retval None */ void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; /** Configure the main internal regulator output voltage */ __HAL_RCC_PWR_CLK_ENABLE(); __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); /** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = 4; RCC_OscInitStruct.PLL.PLLN = 100; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = 4; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } /** Initializes the CPU, AHB and APB buses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK) { Error_Handler(); } } /** * @brief I2C1 Initialization Function * @param None * @retval None */ static void MX_I2C1_Init(void) { /* USER CODE BEGIN I2C1_Init 0 */ /* USER CODE END I2C1_Init 0 */ /* USER CODE BEGIN I2C1_Init 1 */ /* USER CODE END I2C1_Init 1 */ hi2c1.Instance = I2C1; hi2c1.Init.ClockSpeed = 100000; hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2; hi2c1.Init.OwnAddress1 = 0; hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; hi2c1.Init.OwnAddress2 = 0; hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; if (HAL_I2C_Init(&hi2c1) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN I2C1_Init 2 */ /* USER CODE END I2C1_Init 2 */ } /** * @brief USART2 Initialization Function * @param None * @retval None */ static void MX_USART2_UART_Init(void) { /* USER CODE BEGIN USART2_Init 0 */ /* USER CODE END USART2_Init 0 */ /* USER CODE BEGIN USART2_Init 1 */ /* USER CODE END USART2_Init 1 */ huart2.Instance = USART2; huart2.Init.BaudRate = 115200; huart2.Init.WordLength = UART_WORDLENGTH_8B; huart2.Init.StopBits = UART_STOPBITS_1; huart2.Init.Parity = UART_PARITY_NONE; huart2.Init.Mode = UART_MODE_TX_RX; huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart2.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_UART_Init(&huart2) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN USART2_Init 2 */ /* USER CODE END USART2_Init 2 */ } /** * @brief GPIO Initialization Function * @param None * @retval None */ static void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; /* USER CODE BEGIN MX_GPIO_Init_1 */ /* USER CODE END MX_GPIO_Init_1 */ /* GPIO Ports Clock Enable */ __HAL_RCC_GPIOH_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET); /*Configure GPIO pin : PA5 */ GPIO_InitStruct.Pin = GPIO_PIN_5; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* USER CODE BEGIN MX_GPIO_Init_2 */ /* USER CODE END MX_GPIO_Init_2 */ } /* USER CODE BEGIN 4 */ /* USER CODE END 4 */ /** * @brief This function is executed in case of error occurrence. * @retval None */ void Error_Handler(void) { /* USER CODE BEGIN Error_Handler_Debug */ /* User can add his own implementation to report the HAL error return state */ __disable_irq(); while (1) { } /* USER CODE END Error_Handler_Debug */ } #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */ void assert_failed(uint8_t *file, uint32_t line) { /* USER CODE BEGIN 6 */ /* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* USER CODE END 6 */ } #endif /* USE_FULL_ASSERT */ ๋ง์น์ง ํ๋ฉด ๊น๋นก๊ฑฐ๋ฆผ ์ฌ์๋ฒํผ, OK ๋๋ฅด๋ฉด ๋ค์ด๋ก๋ํจ (Upgrage) ๋ณด๋๋์์! drag and drop : OV7670.c -> 250910_OV7670/Core/Src drag and drop : OV7670.h, OV7670_REG.h -> 250910_OV7670/Core/Src /* USER CODE BEGIN Includes */ #include "OV7670.h" // ... /* USER CODE BEGIN 2 */ OV7670_Init(&hi2c1); OV7670_ResetSW(); OV7670_SetResolution(QVGA); OV7670_SetColorFormat(RGB565); OV7670_ShowColorBar(1); main.c ์ ์ฝ๋ ์ถ๊ฐ ํ ํ๋ก๊ทธ๋จ ์ฌ๋ฆฌ๊ณ Vivado ๋ก ๋์์์ xdc ํ์ผ ์์ฑ xdc ํ์ผ์์ ov7670_pclk์ JB10 ์ผ๋ก ์ฎ๊ธฐ๊ณ ๋ค์ Bitstream /* USER CODE BEGIN 2 */ OV7670_Init(&hi2c1); OV7670_ResetSW(); OV7670_SetResolution(QVGA); OV7670_SetColorFormat(RGB565); //OV7670_ShowColorBar(1); OV7670_AutoExposureMode(1); OV7670_SetBrightness(120); OV7670_AutoGainMode(1); ShowColorBar ๋์ ์นด๋ฉ๋ผ ์ธ์์ํด. ๋ง๋ฌด๋ฆฌ stm32 nucleo-f411re ๋ณด๋๋ฅผ FPGA์์ ๋์์์ผ์ผ ํจ. ์ค์ ํ์ผ์ ๋ํ ์ ๋ณด๋ฅผ ๋กฌํ์ผ์ ๋ค ๋ฃ์ด์ผํจ (SCCB Interface) ์ญํ ์ ๋๋ ์ ํํฐ์ค๊ณ, ๋กฌํ์ผ ๋ฑ๋ฑ < ํ์ผ > sources (HW) VGA_Camera_Display.sv OV7670_MemController.sv frame_buffer.sv VGA_MemController.sv GrayScaleFilter.sv VGA_Decoder.sv constrs (HW) Basys-3-Master.xdc
Final
ยท 2025-09-10
2025-09-09
MUX -> Switch Color / Color Bar < Block Diagram> color bar ๋ชจ๋ ๋ฐ๋ก ๋ง๋ค๊ณ ํ์์ ๋จน์ค์ถ๊ฐํด์ ๊ฒฐ๊ณผ์๋์ด < ํ์ผ > sources (Class) VGA_Display_Switch.sv VGA_Decoder.sv VGA_RGB_SWITCH.sv VGA_Color_Bar.sv constrs (Class) Basys-3-Master.xdc ROM ์ ์ด๋ฏธ์ง ๋ฃ์ด์ ๊ณ ๊ณ ์ด๋ฏธ์ง ๋ฐ์ดํฐ๋ 16bit data, ๋ณดํต RGB888 RGB565 ์ ์์จ ๋ค์ด๋ก๋ ezBMP.exe Tool ๋ค์ด๋ก๋ < ImgROM ์ถ๊ฐ > (0,0) โฆ (639,0) (0,2) โฆ (639,1) < ImgReader ์ถ๊ฐ > RGB565 -> RGB444๋ก ํ์๋นํธ๋ฅผ ์๋ผ์ค์ผ ํจ (๋น data ์ ์) ๋ํ ROM ์ฌ์ด์ฆ 640x480 ๊ฐ ์๋์์ 320x240 ๋ก ์๋ฅด๊ฑฐ๋ ๋ฎ์ถฐ์ผํจ < ์์จ > ๊พธ๋ฏธ๊ธฐ ์๋ฅด๊ธฐ 4:3 ์ ์ฉ (์๋ฅด๊ธฐ ๋น์จ ์ ์ง, ๊ฐ๋ก๋ก ๊ธธ๊ฒ) ํฌ๊ธฐ๋ณ๊ฒฝ 320x240 ์ ์ฉ (ํด์๋๋ก ์กฐ์ ) ๋ชจ๋ ์ ์ฅ < ezBMP > ๊ทธ๋ฆผ์ฝ๊ธฐ RGB565 ๋ณํ ์ ์ฅ ํ์ผ์ด๋ฆ ๋ณ๊ฒฝํ ์ ์ฅ(cํ์ผ) < .c ํ์ผ ์์ > 16bit ๋ถ๋ถ๋ง ๋จ๊ธฐ๊ณ ์ญ์ (imgReader ์ ๋ ฅ๋ฐ์ดํฐ 16bit) โ0xโ -> โโ (๊ณต๋ฐฑ) โ,โ -> โ โ Vivado -> Memory File ์ถ๊ฐ ํ ํ์ผ ๋ด์ฉ ๋ถ์ฌ๋ฃ๊ธฐ < imgReader ์์ > //assign addr = DE ? (320 * y + x) : 17'bz; assign addr = (DE && (x < 320) && (y < 240)) ? (320 * y + x) : 17'bz; ํ๋ฉด์์ ์ฌ์ง์ธ์ ๋๋จธ์ง ๋ถ๋ถ์๋ data๊ฐ ๋ค์ด๊ฐ๋ฏ๋ก ์ฝ๋ ์์ logic img_show; assign img_show = (DE && (x < 320) && (y < 240)); assign addr = img_show ? (320 * y + x) : 17'bz; assign r_port = img_show ? data[15:12] : 4'bz; assign g_port = img_show ? data[10:7] : 4'bz; assign b_port = img_show ? data[4:1] : 4'bz; ๋๋จธ์ง ๋ถ๋ถ์ ๊ฒ์์์ด ์๋ ๋ ๋์์ผ๋ก ์ฑ์์น๋ฏ๋ก ์ฝ๋ ์์ < ImgROM > LUT๋ก ์กํ ๊ฑฐ๋ ํ๋ก๊ฐ ์๋์ผ๋ก ์์ฑ๋๊ฑฐ์ - ๋น๋๊ธฐ์ ํ๋ก๋ก ๋ง๋ค๋ฉด LUT ํ๋ก ์์ฑ - clk์ ๋ฐ์์ค์ ๋๊ธฐ์ ํ๋ก๋ก ๋ง๋ค๋ฉด BRAM์ผ๋ก ํ๋ก๊ฐ ์์ฑ๋จ VGA_Decoder ์์ pclk ๋ฅผ ๋ฝ์์, ImgROM ์ clk ์ผ๋ก ๋ฃ์ด์ค BRAM ์ ์ก์์ผ๋ก LUT์ ํ๋ก๋ฅผ ๋ ๊ตฌ์ฑํ ์ ์์ < Result > ์์์ฒ๋ฆฌ์ ํจ๊ป ํํฐ ๊ณ ์ RAM์ ์ฃผ๊ธฐ์ ์ผ๋ก ๊ณ์ ์ฝ๊ณ ์จ์ฃผ๋ฉด์ memory ์ ๋ฐ์ดํธ ์ดํ ํํฐ์ ์ํ์ ์๊ณ ๋ฆฌ์ฆ์ ์ถ๊ฐํ ์ ์์ < ์์ ํํฐ ๊ตฌํ > RGB_OnOff_Filter ๋ชจ๋ ์ค๊ณ ! < Gray Filter > GrayScaleFilter ๋ชจ๋ ์ค๊ณ, ์์ 4๋นํธ๋ง ์ฌ์ฉ ๋งค๋ฒ ๋นํธ์คํธ๋ฆผํ๊ธฐ ๋นก์ธ๋๊น bmp ํ์ผ ์ฝ๊ณ ์ฐ๋๊ฑฐ ํด๋ณด์ < ์์จ > ๊พธ๋ฏธ๊ธฐ ์๋ฅด๊ธฐ 4:3 ์ ์ฉ (์๋ฅด๊ธฐ ๋น์จ ์ ์ง, ๊ฐ๋ก๋ก ๊ธธ๊ฒ) ํฌ๊ธฐ๋ณ๊ฒฝ 640x480 ์ ์ฉ ๋ชจ๋ ์ ์ฅ -> BMP ํ์์ผ๋ก ์ ์ฅ (24bit) < TestBench ์์ฑ (SW) > ์ดํ sim ๋์๋๋ ์์น์ bmp ํ์ผ์ ๋ฃ์ด์ผํจ -> ProjectName.sim/sim_1/behav/xsim/ ์ฌ๊ธฐ์๋ฃ๊ณ ์๋ฎฌ๋ ์ด์ `timescale 1ns / 1ps module tb_VGA (); byte bmp_total[640*480*3+54]; byte bmp_header[54]; byte bmp_data[640*480*3]; int bmp_size, bmp_data_offset, bmp_width, bmp_height, biBitCount; string sourcefileName = "Rengoku_640x480.bmp"; string targetfileName = "target_640x480.bmp"; task ReadBMP(); int fileID, readSize; fileID = $fopen(sourcefileName, "rb"); if (!fileID) begin $display("Open [%s] BMP File Error!", sourcefileName); $finish; end readSize = $fread(bmp_total, fileID); $fclose(fileID); $display("[%s] read size : %0d", sourcefileName, readSize); bmp_size = {bmp_total[5], bmp_total[4], bmp_total[3], bmp_total[2]}; $display("[%s] bmp size : %0d", sourcefileName, bmp_size); bmp_data_offset = { bmp_total[13], bmp_total[12], bmp_total[11], bmp_total[10] }; $display("[%s] bmp image offset : %0d", sourcefileName, bmp_data_offset); bmp_width = { bmp_total[21], bmp_total[20], bmp_total[19], bmp_total[18] }; bmp_height = { bmp_total[25], bmp_total[24], bmp_total[23], bmp_total[22] }; $display("[%s] bmp image %0d x %0d", sourcefileName, bmp_width, bmp_height); biBitCount = {bmp_total[29], bmp_total[28]}; $display("[%s] bmp bit %0d", sourcefileName, biBitCount); if (biBitCount != 24) begin $display("[%s] biBitCount need to be 24bit", sourcefileName); $finish; end if (bmp_width % 4) begin $display("[%s] bmp width %% 4 need to be zero!", sourcefileName); $finish; end // copy header for (int i = 0; i < bmp_data_offset; i++) begin bmp_header[i] = bmp_total[i]; end // copy image for (int i = bmp_data_offset; i < 640 * 480 * 3; i++) begin bmp_data[i-bmp_data_offset] = bmp_total[i]; end endtask task WriteBMP(); int fileID; fileID = $fopen(targetfileName, "wb"); for (int i = 0; i < bmp_data_offset; i++) begin $fwrite(fileID, "%c", bmp_header[i]); end for (int i = 0; i < bmp_size - bmp_data_offset; i++) begin $fwrite(fileID, "%c", bmp_data[i]); end $fclose(fileID); $display("Write BMP File Done!"); endtask initial begin ReadBMP(); WriteBMP(); end endmodule Class ๋ก TestBench ์์ // ์๋จ < ํ์ผ > sources (Class) imgReader.sv ImgROM.sv VGA_Display_Switch.sv GrayScaleFilter.sv RGB_OnOff_Filter.sv VGA_Color_Bar.sv VGA_Decoder.sv VGA_RGB_SWITCH.sv Lenna.mem Rengoku.mem sim (Class) tb_VGA.sv constrs (Class) Basys-3-Master.xdc
Final
ยท 2025-09-09
2025-09-08
VGA(Video Graphics Array) Cathode Ray Tube ํ๋ฉด์ด ๋์ค๋ ๊ธฐ๋ณธ์ ์ธ ์๋ฆฌ(๋ธ๋ผ์ด๊ด, Cathode Ray Tube) : ํธํฅํ(+)์ ์ ์์ ์ธ๊ฐํ์ฌ ํต๊ณผํ๋ ์ ์๋ฅผ ํน์ ๋ฐฉํฅ(์/ํ/์ข/์ฐ)์ผ๋ก ๋์ด๋น๊ฒจ์ ํ๊ด๋ฌผ์ง์ด ๋ฐ๋ ค์ง ํ๋ฉด์ ์ํ๋ ์์น์ ์ ์๊ฐ ๋์ฐฉํจ Heater : ์ด์ ๋ฐ์์ํด (์ ์์ ์ด๋๋ ์ฆ๊ฐ), electronic gun ์ญํ ์ ํจ Cathode : ์ ์๊ฐ ๋ชจ์ accelerating anode / focusing anode : ์ ์์ ์ด๋์ ๊ฐ์์ํด, ์ ์์ ์ด๋ ์๋์ ๋ฐ๋ฅธ ๋ช ์ ์กฐ์ ์ด ๊ฐ๋ฅ(๋ฐ๊ธฐ) plates for horizontal deflection / plates for vertical deflection : +์ ์์ ์ธ๊ฐํ์ฌ ์ ์์ ์ด๋ ๊ฒฝ๋ก๋ฅผ ์กฐ์ 1 ํฝ์ ๋น 8bit ์ง๋ฆฌ R, G, B ๋ฌถ์ VGA (640x480 size) ํธํฅํ์ ์ค๋ฅธ์ชฝ์ผ๋ก ๊ฐ์๋ก ๊ฐ๋๊ฐ ์ธ์ง = ์ ๋ฅ๊ฐ ์ธ์ง Display Surface ์ ์ผ์ชฝ์์ ์ค๋ฅธ์ชฝ์ผ๋ก ์ ์๊ฐ ๋์ฐฉํจ. ์ค๋ฅธ์ชฝ์ ๋ค๋ค๋ฅด๋ฉด ๋ค์ ์ผ์ชฝ์ผ๋ก ๋์๊ฐ์ผํจ. ์ด๋ ์ ๋ฅ์ ์ธ๊ธฐ๋ฅผ ๋ฎ์ถฐ์ ๋์๊ฐ. ์ ๋ฅ์ ์ธ๊ธฐ๊ฐ ์ค๋ฌด์คํ๊ฒ ๋จ์ด์ง๋ ๊ตฌ๊ฐ์๋ ๋ง์ง์ด ํ์ํ๊ฒ ๋จ -> porch porch : ์๋ Tv์ ๊ฐ์ฅ์๋ฆฌ ๋ถ๋ถ(๊ฐ๋ ค๋์), ๋์์ค๋ ๊ตฌ๊ฐ(Retrace), ํธํฅํ ๋ฐฉ์ front porch : sync ์ ํธ ์์ ์์ back porch : sync ์ ํธ ๋ค์ ์์ Display -> Front Portch -> Sync Pulse -> Back Porch ์ ์์ ์ฃผ๋ฉด ์ ํธ ๋ฌดํ ๋ฐ๋ณต VGA Signal 640x480 ๋ค์ด๊ฐ๋ฉด ์ฌ์ด์ฆ ๋์ด ํ ํ๋ ์์ ์ฐ๊ธฐ ์ํด800, 525 ๋งํผ์ ์ /์๊ฐ์ด ํ์ํจ 1์ด : 800Pix * 525Line * 60Frame = 25.2MHz =~ 25MHz Scanline part Pixels Frame part Lines Visible area 640 Visible area 480 Front porch 16 Front porch 10 Sync pulse 96 Sync pulse 2 Back porch 48 Back porch 33 ํฌํธ์ ๊ตฌ์กฐ๋ ์ด๋ฐ ์์ผ๋ก display ์ค๊ณ ๊ฐ๋ฅ < Block Diagram > VGA ์์ sync๋ฅผ ๋ง์ถ๋ ์ ํธ๊ฐ ํ์ํจ. pixels ๊ฐ์ ๊ฒฝ์ฐ 640+16 ๊น์ง High, 96 ๊น์ง Low, 48 ๊น์ง High x, y ์ขํ์ ๋ง๋ display๋ฅผ ํ ์ ์๊ฒ ํด์ผํจ (640 x 840 ์์ญ์์๋ง!) pixel clock ์ ๋ฐ์์ ์์์ฒ๋ฆฌ์ ๋ํ ๋ชจ๋์ ๋์์ํค๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ pixel_counter์์ pclk ์ ๋ํด negedge ์ผ๋ ์ฒ๋ฆฌํ๋ ์ด์ ๋? ์์ ์ ์ผ๋ก RGB Data๋ฅผ ์ฝ๊ธฐ ์ํจ ์ถํ ISP ์ค๊ณ์ posedge, regedge๋ฅผ ์ ์ ํ ๋ถ๋ฐฐํ ํ์๊ฐ ์์ (Timing ๊ณ ๋ ค) < Simulation > < ํ์ผ > sources (Class) VGA_Display_Switch.sv VGA_Decoder.sv VGA_RGB_SWITCH.sv sim (Class) tb_vga_sw.sv constrs (Class) tb_vga_sw.sv HW < Design Specification > < Result > < ํ์ผ > sources (HW) VGA_Display_Switch.sv VGA_Decoder.sv VGA_RGB_SWITCH.sv constrs (HW) Basys-3-Master.xdc
Final
ยท 2025-09-08
2025-09-05
AXI_Introduction_to_AMBA_AXI < READ Transaction : R, AR Channel transfer > ์ฝ๋ฉ ์ญ์ญ ์๋ฎฌ๊ฒฐ๊ณผ ์ฌ์ง1 ์ฝ๋๋ค ์ฌ์ง2 < Vivado : ์ค์์น๊ฐ์๊ฑฐ > ๋ง๋ IP์ ๋ง๊ฒ ์์ ํด์ ์ฌ์ฉํ ์ ์์ ๋ธ๋ก๋ ์ฌ์ง3 ๋จ๊ณ ๋ญ๊ฐ ๋ง๋ค (ํด๋์ค๋ฃธ๋ ธํธ์ฐธ๊ณ ) ์ฝ๋๋ถ์ ๋๊ฐ์ // Width of S_AXI data bus parameter integer C_S_AXI_DATA_WIDTH = 32, // Width of S_AXI address bus parameter integer C_S_AXI_ADDR_WIDTH = 4 // Example-specific design signals // local parameter for addressing 32 bit / 64 bit C_S_AXI_DATA_WIDTH // ADDR_LSB is used for addressing 32/64 bit registers/memories // ADDR_LSB = 2 for 32 bits (n downto 2) // ADDR_LSB = 3 for 64 bits (n downto 3) localparam integer ADDR_LSB = (C_S_AXI_DATA_WIDTH/32) + 1; localparam integer OPT_MEM_ADDR_BITS = 1; ADDR_LSB = (32/32) + 1 = 2 // AXI4LITE signals reg [C_S_AXI_ADDR_WIDTH-1 : 0] axi_awaddr; reg axi_awready; reg axi_wready; reg [1 : 0] axi_bresp; reg axi_bvalid; reg [C_S_AXI_ADDR_WIDTH-1 : 0] axi_araddr; reg axi_arready; reg [C_S_AXI_DATA_WIDTH-1 : 0] axi_rdata; reg [1 : 0] axi_rresp; reg axi_rvalid; [3:0] axi_awaddr [3:0] axi_araddr [31:0] axi_rdata //---------------------------------------------- //-- Signals for user logic register space example //------------------------------------------------ //-- Number of Slave Registers 4 reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg0; reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg1; reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg2; reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg3; wire slv_reg_rden; wire slv_reg_wren; reg [C_S_AXI_DATA_WIDTH-1:0] reg_data_out; integer byte_index; reg aw_en; slv_reg0, slv_reg1, slv_reg2, slv_reg3 : 32bit // Implement axi_awready generation // axi_awready is asserted for one S_AXI_ACLK clock cycle when both // S_AXI_AWVALID and S_AXI_WVALID are asserted. axi_awready is // de-asserted when reset is low. always @( posedge S_AXI_ACLK ) begin if ( S_AXI_ARESETN == 1'b0 ) begin axi_awready <= 1'b0; aw_en <= 1'b1; end else begin if (~axi_awready && S_AXI_AWVALID && S_AXI_WVALID && aw_en) begin // slave is ready to accept write address when // there is a valid write address and write data // on the write address and data bus. This design // expects no outstanding transactions. axi_awready <= 1'b1; aw_en <= 1'b0; end else if (S_AXI_BREADY && axi_bvalid) begin aw_en <= 1'b1; axi_awready <= 1'b0; end else begin axi_awready <= 1'b0; end end end ์ฒซ ๋ฒ์งธ if : (๋ฆฌ์ ) ๋ ๋ฒ์งธ if : (ready 0, AWADDr ์ ๋ ฅ, WDATA ์ ๋ ฅ, ์ฒ์์ํ) ์ด๋ฉด ์กฐ๊ฑด๋ฌธ ์คํ else if : (Bchannel handshaking) write transaction์ด ๋๋๋ฉด else : write transaction ์ํ์ค // Implement axi_awaddr latching // This process is used to latch the address when both // S_AXI_AWVALID and S_AXI_WVALID are valid. always @( posedge S_AXI_ACLK ) begin if ( S_AXI_ARESETN == 1'b0 ) begin axi_awaddr <= 0; end else begin if (~axi_awready && S_AXI_AWVALID && S_AXI_WVALID && aw_en) begin // Write Address latching axi_awaddr <= S_AXI_AWADDR; end end end ์ ๋ ฅ๋ AWADDR ์์ ์ ์ฅ ๋ค์ ํด๋ญ์์๋ ready=1 ์ด๋ฏ๋ก ํ ๋ฒ๋ง ๋์ // Implement axi_wready generation // axi_wready is asserted for one S_AXI_ACLK clock cycle when both // S_AXI_AWVALID and S_AXI_WVALID are asserted. axi_wready is // de-asserted when reset is low. always @( posedge S_AXI_ACLK ) begin if ( S_AXI_ARESETN == 1'b0 ) begin axi_wready <= 1'b0; end else begin if (~axi_wready && S_AXI_WVALID && S_AXI_AWVALID && aw_en ) begin // slave is ready to accept write data when // there is a valid write address and write data // on the write address and data bus. This design // expects no outstanding transactions. axi_wready <= 1'b1; end else begin axi_wready <= 1'b0; end end end (WDATA ์ ๋ ฅ, AWADDR ์ ๋ ฅ, write tansaction ์ฒ์ ์ํ) // Implement memory mapped register select and write logic generation // The write data is accepted and written to memory mapped registers when // axi_awready, S_AXI_WVALID, axi_wready and S_AXI_WVALID are asserted. Write strobes are used to // select byte enables of slave registers while writing. // These registers are cleared when reset (active low) is applied. // Slave register write enable is asserted when valid address and data are available // and the slave is ready to accept the write address and write data. assign slv_reg_wren = axi_wready && S_AXI_WVALID && axi_awready && S_AXI_AWVALID; always @( posedge S_AXI_ACLK ) if ( S_AXI_ARESETN == 1'b0 ) begin slv_reg0 <= 0; slv_reg1 <= 0; slv_reg2 <= 0; slv_reg3 <= 0; end else begin if (slv_reg_wren) begin case ( axi_awaddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB] ) 2'h0: for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 ) if ( S_AXI_WSTRB[byte_index] == 1 ) begin // Respective byte enables are asserted as per write strobes // Slave register 0 slv_reg0[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8]; end 2'h1: for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 ) if ( S_AXI_WSTRB[byte_index] == 1 ) begin // Respective byte enables are asserted as per write strobes // Slave register 1 slv_reg1[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8]; end 2'h2: for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 ) if ( S_AXI_WSTRB[byte_index] == 1 ) begin // Respective byte enables are asserted as per write strobes // Slave register 2 slv_reg2[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8]; end 2'h3: for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 ) if ( S_AXI_WSTRB[byte_index] == 1 ) begin // Respective byte enables are asserted as per write strobes // Slave register 3 slv_reg3[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8]; end default : begin slv_reg0 <= slv_reg0; slv_reg1 <= slv_reg1; slv_reg2 <= slv_reg2; slv_reg3 <= slv_reg3; end endcase end end end handshaking ์ผ์ด๋ฌ์ ๋ ์ ์ฅํ๊ฒ ๋ค๋ ๋ป case ([3:2]) : 4์ ๋ฐฐ์๋ฅผ 1, 2, 3, 4๋ก ๋ณด๊ฒ ์ byte_index : 0์ผ๋ // Implement write response logic generation // The write response and response valid signals are asserted by the slave // when axi_wready, S_AXI_WVALID, axi_wready and S_AXI_WVALID are asserted. // This marks the acceptance of address and indicates the status of // write transaction. always @( posedge S_AXI_ACLK ) begin if ( S_AXI_ARESETN == 1'b0 ) begin axi_bvalid <= 0; axi_bresp <= 2'b0; end else begin if (axi_awready && S_AXI_AWVALID && ~axi_bvalid && axi_wready && S_AXI_WVALID) begin // indicates a valid write response is available axi_bvalid <= 1'b1; axi_bresp <= 2'b0; // 'OKAY' response end // work error responses in future else begin if (S_AXI_BREADY && axi_bvalid) //check if bready is asserted while bvalid is high) //(there is a possibility that bready is always asserted high) begin axi_bvalid <= 1'b0; end end end end READY์ VALID ๊ฐ 1์ด๋ฉด ์์์ ready๊ฐ 0์ด ๋จ, write transaction ๋๋๋ฉด ์ฃผ์๋ฅผ ๋ฐ์ง ์๊ฒ ๋ค write transaction ์ํ ์ค ์บก์ฒ์ฌ์ง ์ฃผ๋ฅด๋ฅต IP ๊ฐ๋ค์ฐ๋ฉด๋จ CPU ๋ถ๋ฌ์ ์ฌ๊ธฐ์ ์ฌ๋ฆฌ๊ณ ๋ฐฉ๊ธ๋ง๋ IP๋ฅผ ๋ถํ๊ฑฐ์ ๋ฐฅ๋จน๊ณ ์์ GPIO IP ๋ง๋ค๊ณ ๋น๋ฐ๋ ์์ฒด ๋ฒ๊ทธ, Makefile ์์ ํด์ผ๋จ makefile ๊ฒฝ๋ก์บก์ฒ,
Final
ยท 2025-09-05
2025-09-04
AXI_Introduction_to_AMBA_AXI RISC-V ์ง์ ์ฌ์ฉ๊ณผ๋ ๋ณ๊ฐ๋ก, Xilinx Vivado์์๋ MicroBlaze soft CPU + AXI Interconnect (Switch) ๊ตฌ์กฐ๋ฅผ ๊ธฐ๋ณธ์ผ๋ก ์ ๊ณต. FPGA์ ์ฌ๋ฆด๋ ค๋ฉด ๋ง์ดํฌ๋ก ๋ธ๋ ์ด์ฆ, AXI ์ค์์น ์ฌ์ฉ < AXI protocol overview > AXI๋ BUS๊ฐ ์๋๋ผ protocol โ ์ฉ์ด์ โAXI busโ๋ผ ํ์ง ์๊ณ AXI protocol์ด๋ผ๊ณ ํจ. Point-to-Point ์ฐ๊ฒฐ: Master์ Slave๊ฐ ์ง์ ์ฐ๊ฒฐ๋๋ฉฐ, Interconnect๊ฐ ์ค์ฌ ์ญํ ์ ํจ. ๋ฐ๋ผ์ Master1โSlave1 ํต์ ๊ณผ ๋์์ Master2โSlave2 ํต์ ๊ฐ๋ฅ โ ๋ณ๋ ฌ์ฑ ๋ณด์ฅ. < AXI Channels ์ ๋ฆฌ > AXI ์ธํฐํ์ด์ค ๊ธฐ๋ณธ ๊ตฌ์กฐ AXI๋ point-to-point protocol Master โ Slave ๊ฐ ํต์ ์ 5๊ฐ์ ์ฑ๋์ ํตํด ์ด๋ฃจ์ด์ง: Write Address (AW) Write Data (W) Write Response (B) Read Address (AR) Read Data (R) Write Operation (์ฐ๊ธฐ ๋์) Master โ Slave: AW ์ฑ๋: ์ฐ๊ธฐ ์ฃผ์ ์ ๋ฌ W ์ฑ๋: ์ค์ ๋ฐ์ดํฐ ์ ๋ฌ Slave โ Master: B ์ฑ๋: ์ฐ๊ธฐ ์๋ฃ ํ ์๋ต(Return message) Read Operation (์ฝ๊ธฐ ๋์) Master โ Slave: AR ์ฑ๋: ์ฝ๊ณ ์ถ์ ์ฃผ์ ์ ๋ฌ Slave โ Master: R ์ฑ๋: ์์ฒญ๋ ์ฃผ์์ ๋ฐ์ดํฐ ๋ฐํ ์ค๋ฅ ์ โ Read Data ์ฑ๋์์ ์๋ฌ ๋ฉ์์ง ์ ๋ฌ (์ฃผ์ ๋ฌดํจ, ๋ฐ์ดํฐ ์ค๋ฅ, ๊ถํ ์์ ๋ฑ) ์ฑ๋ ํน์ฑ ๊ฐ ์ฑ๋์ ๋จ๋ฐฉํฅ(unidirectional) ๊ตฌ์กฐ. ๋ฐ๋ผ์ Write Response(B) ์ฑ๋์ด ๋ณ๋๋ก ํ์ํจ. ๋ฐ๋ฉด ์ฝ๊ธฐ์๋ ๋ณ๋์ Response ์ฑ๋์ด ํ์ ์์ โ Read Data(R)์ ํฌํจ๋จ. Read ์ฑ๋๊ณผ Write ์ฑ๋์ ์๋ก ๋ ๋ฆฝ โ ๋์์ ๋์ ๊ฐ๋ฅ โ ๋์ญํญ ์ต์ ํ. ์ ํธ ์ ๋(prefix) AW : Write Address ์ฑ๋ ์ ํธ AR : Read Address ์ฑ๋ ์ ํธ W : Write Data ์ฑ๋ ์ ํธ R : Read Data ์ฑ๋ ์ ํธ B : Write Response ์ฑ๋ ์ ํธ B = buffered โ Slave๊ฐ ๋ชจ๋ Write ์๋ฃ ํ ์๋ตํ๋ ์๋ฏธ < Channel handshake ์ ๋ฆฌ > ๊ธฐ๋ณธ ๊ฐ๋ AXI4์ ๋ชจ๋ 5๊ฐ ์ฑ๋์ VALID/READY ํธ๋์ ฐ์ดํฌ ๋ฉ์ปค๋์ฆ์ ์ฌ์ฉ. VALID: Source(์ก์ ์ โ Master or Slave)์์ Destination์ผ๋ก ์ ์ก. READY: Destination(์์ ์ โ Master or Slave)์์ Source๋ก ์ ์ก. ๋ ์ ํธ๊ฐ ๋ชจ๋ High์ผ ๋ ๋ฐ์ดํฐ ์ ์ก์ด ์ ํจํ๊ฒ ์ด๋ฃจ์ด์ง. ๋์ ๋ฐฉ์ Source ์ญํ ์ ํจํ ๋ฐ์ดํฐ๊ฐ ์ค๋น๋๋ฉด VALID=1๋ก ์ค์ . Destination์ด ์๋ฝํ ๋๊น์ง VALID๋ ์ ์งํด์ผ ํจ. ์ด๋ ๊ฒ ์ ์ง๋๋ VALID๋ฅผ โsticky signalโ์ด๋ผ๊ณ ๋ถ๋ฆ. Destination ์ญํ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ ์ ์์ผ๋ฉด READY=1๋ก ์ค์ . READY๋ Destination โ Source๋ก ์ ๋ฌ๋จ. ๋ฐ์ดํฐ ์ ์ก ์กฐ๊ฑด VALID=1 & READY=1 โ rising edge์์ ๋ฐ์ดํฐ ์ ์ก ์ฑ๊ณต. Master / Slave์ ์์น Master/Slave๊ฐ Source์ธ์ง Destination์ธ์ง๋ ์ฑ๋์ ๋ฐ๋ผ ๋ค๋ฆ. ์: Read Address ์ฑ๋์์๋ Master๊ฐ Source, Slave๊ฐ Destination. ์: Read Data ์ฑ๋์์๋ Slave๊ฐ Source, Master๊ฐ Destination. ํน์ฑ ์ด ๋ฉ์ปค๋์ฆ์ ๋น๋๊ธฐ(asynchronous) ํธ๋์ ฐ์ดํฌ๊ฐ ์๋. ํด๋ก์ ์์น ์์ง(rising edge)์์ ์ ์ก์ด ํ์ ๋จ. < Transfers vs Transactions ์ ๋ฆฌ > Transfer VALID + READY ํธ๋์ ฐ์ดํฌ ํ ๋ฒ์ผ๋ก ์ด๋ฃจ์ด์ง๋ ๋จ์ผ ๋ฐ์ดํฐ ๊ตํ. ๊ตฌ์ฑ: Source โ Destination : VALID + INFO(๋ฐ์ดํฐ/์ฃผ์ ๋ฑ) Destination โ Source : READY ์ฆ, ํ๋์ ๋ฐ์ดํฐ ์ ์ก ๋จ์. Transaction ์ฌ๋ฌ ๊ฐ์ Transfer ๋ฌถ์ โ ํ๋์ ์ ์ฒด ๋์. ์์: Write Transaction Address Transfer Write Address ์ฑ๋: Master๊ฐ ์ฃผ์ ์ ๋ฌ (VALID + ADDRESS) Slave๊ฐ ์๋ฝ ์ READY Data Transfer(s) Write Data ์ฑ๋: Master๊ฐ ์ค์ ๋ฐ์ดํฐ ์ ์ก (VALID + DATA) Slave๊ฐ ์๋ฝ ์ READY ๋ฐ์ดํฐ๋ ์ฌ๋ฌ ๊ฐ์ burst transfer ๊ฐ๋ฅ Response Transfer Write Response ์ฑ๋: Slave โ Master ์๋ต (VALID + RESPONSE) Master๊ฐ ์๋ฝ ์ READY ํต์ฌ ์ฐจ์ด Transfer = ๋จ์ผ ๊ตํ (VALID/READY 1๋ฒ) Transaction = ์ฌ๋ฌ Transfer์ ์งํฉ (Address + Data + Response๋ก ๊ตฌ์ฑ, burst๋ ํฌํจ ๊ฐ๋ฅ) VALID ์ ํธ๊ฐ ๋ค์ด์ค๋ฉด MASTER ์ชฝ์ READY๋ฅผ ๋ค์ ์ค -> HAND SHAKE๊ฐ ์ด๋ฃจ์ด์ง๊ณ ๋ ํ์ ๋จ์ด์ง ํ์ดํ 2๊ฐ : ๋ฐ๋์ ์์ด์ผํจ ํ์ดํ 1๊ฐ : ์ต์ ๋๋ ๋ฒ์คํธ์ ํธ๊ฐ ์๋ ๊ฒ์ด Lite ๋ ์ ๋ฆฌ? ํ์ด๋ฐ๋ณ๋ก ๊ธฐ๋ค๋ฆฌ๋ ์ ์ฅ ๋ฑ๋ฑ < Block Diagram > < FSM > < Simulation > < ํ์ผ > sources (Class) AXI4_Lite_Master.sv AXI4_Lite_Slave.sv simulation (Class) tb_AXI4_Lite.sv
Final
ยท 2025-09-04
2025-09-03
SystemVerilog ๊ฒ์ฆ (RAM) < SystemVerilog ๊ธฐ๋ฐ RAM ๊ฒ์ฆ์ ํต์ฌ ํฌ์ธํธ > ์ ๋ ฅ๊ฐ ์๋ํ (randomization ํ์ฉ) Testbench์์ Stimulus(์ ๋ ฅ๊ฐ)๋ฅผ ์๋ ์์ฑํ๊ธฐ ์ํด class + randomize() ์ฌ์ฉ ํนํ ์ฃผ์, ๋ฐ์ดํฐ, ์ ์ด ์ ํธ(write/read enable) ๋ฑ์ ๋๋คํ๊ฒ ์์ฑํด corner case ๊ฒ์ฆ ๊ฐ๋ฅ Class์ ์ญํ (HW ์ ๊ทผ ๋ถ๊ฐ) class๋ ์ํํธ์จ์ด์ ๊ฐ๋ transaction(๋ฐ์ดํฐ ๋ฌถ์)์ ์ ์ํ๊ณ , ๋๋ค ์์ฑ ๋ฐ ์ฒ๋ฆฌํ๋ ์ญํ ์ง์ DUT์ ํ์ ์ ๊ทผํ ์ ์์ ๋ฐ๋ผ์ driver๊ฐ class ๊ฐ์ฒด(transaction)๋ฅผ ๋ฐ์์ โ interface๋ฅผ ํตํด HW ์ ํธ๋ก ๋ณํ Interface์ ์ญํ (HW ์ ํธ ๋ฌถ์) interface๋ ํ๋์จ์ด์ ๊ฐ๋ DUT์ testbench ๊ฐ์ ์ ํธ(์ฃผ์, ๋ฐ์ดํฐ, write enable ๋ฑ)๋ฅผ ๋ฌถ์ด์ฃผ๋ ์ญํ Virtual Interface (SW โ HW ์ฐ๊ฒฐ ๋ค๋ฆฌ) class๋ HW์ ์ง์ ์ ๊ทผ ๋ถ๊ฐ โ interface ํธ๋ค์ ์ฐธ์กฐํด์ผ ํจ ํ์ง๋ง class ๋ด๋ถ์์ interface ์ธ์คํด์ค๋ฅผ ๋ฐ๋ก ์ฌ์ฉํ ์ ์์ < Block Diagram > < Timing Diagram > // ram ์ write task run(); forever begin gen2drv_mbox.get(tr); ram_if.addr = tr.addr; ram_if.we = tr.we; if (tr.we) ram_if.wdata = tr.wdata; @(posedge ram_if.clk); end endtask โ===โ : ์กฐ๊ฑด๋ฌธ ๋ด์์ x(Impedance)๊ฐ ํ๋จ ๊ฐ๋ฅ < ํ์ผ > sources (Class) ram.sv simulation (Class) tb_ram.sv FND_periph Design < Block Diagram > < Design Specification > (en ์ ํธ) clk_div_1khz ์ ์ด -> ์นด์ดํฐ ๋ฉ์ถค (en ์ ํธ) decoder_2x4 ์ ์ด -> ๋์คํ๋ ์ด ๊บผ์ค < SW ๊ฒ์ฆ, C์ธ์ด ๋ถ์ > #include<stdint.h> typedef struct { uint32_t CR; uint32_t FDR; } FND_TypeDef; #define APB_BASE 0x10000000 #define FND_BASE (APB_BASE + 0x4000) #define FND ((FND_TypeDef *)(FND_BASE)) // #define FND_CR (*(uint32_t *)(FND_BASE + 0x00)) // #define FND_FDR (*(uint32_t *)(FND_BASE + 0x04)) void FND_Init(FND_TypeDef *fnd); void FND_WriteData(FND_TypeDef *fnd, uint32_t d); void delay(uint32_t t); int main() { // FND_CR = 0x01; // FND_FDR = 1234; // FND->CR = 0x01; // FND->FDR = 1234; FND_Init(FND); uint32_t data = 0; while (1) { // FND->FDR = data; FND_WriteData(FND, data); data++; delay(1000); } return 0; } void FND_WriteData(FND_TypeDef *fnd, uint32_t d) { fnd->FDR = d; } void FND_Init(FND_TypeDef *fnd) { fnd->CR = 0x01; } void delay(uint32_t t) { for (int i=0; i<t; i++) { for (int j=0; j<1000; j++); } } (์๋ ํด์์ ์์ ์ค ํด์์ด๊ณ GPT ๋ด์ฉ๊ณผ ๋ถ๋ถ์ ์ผ๋ก ํ๋ฆผ) (int *)0x10000000 Data Type : ์๋ฃํ, Data ํํ, Data ๋ชจ์, Data ํฌ๊ธฐ Data : Memory ์์ ์๋ ๊ฐ Type : int๋ฅผ ๋ปํจ (4byte) => int ์๋ฃํ์ด ์๋ฏธํ๋ ์ฃผ์์ 4byte์ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ ํ ๋น (char *)0x10000008 0x1000_0008 : ์ฃผ์ => 1Byte ๋งํผ ํ ๋น (FND_Typedef *)0x10004000 FND_Typedef : Data Type ์ผ๋ก ์๊ฐ 4byte 2๊ฐ๊ฐ ๋ถ์ด์๋ 8byte ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํ ๋นํ๋ฉฐ CR, FDR ์ด๋ผ๋ ์ด๋ฆ์ ๋ถํ์ ๋ฟ ((FND_Typedef *)(0x10004000))->CR = 0x01; ((FND_Typedef *)(0x1000_4000)).CR : ์ฃผ์๋ฅผ ์๋ฏธํจ ((FND_Typedef *)(0x1000_4000))->CR : ํด๋น ์ฃผ์์ ๋ฐ์ดํฐ๋ฅผ ์๋งํจ (FND_TypeDef *) : type ์บ์คํ , ์ฃผ์๋ฅผ ํด๋น ํ์ ์ ํฌ์ธํฐ๋ก ํด์ ํฌ์ธํฐ ์ดํด +โโโโโโ-+ | 4 byte | <- FDR +โโโโโโ-+ | 4 byte | <- CR +โโโโโโ-+ ์ด์ค ํฌ์ธํฐ ์์ +โโโโโโ-+ | 10 | <- A +โโโโโโ-+ | 0x1000_0000 | <- pA +โโโโโโ-+ | 0x1000_1000 | <- ppA +โโโโโโ-+ (0x1000_0000) A = 10 ๊ฐ (0x1000_1000) pA = 0x1000_0000 ์ฃผ์ (0x1000_2000) ppA = 0x1000_1000 ์ฃผ์ **ppA == 10 (A์ ๊ฐ) ๋จธ์ ์ฝ๋๋ก ๋ณ๊ฒฝ ์ ์ฐธ๊ณ li sp,0x10001000 < ํ์ผ > sources (Class) APB_Master.sv APB_Slave.sv code.mem ControlUnit.sv CPU_RV32I.sv DataPath.sv defines.sv fndController.sv GPI.sv GPIO.sv GPO.sv MCU.sv RAM.sv ROM.sv constrs (Class) Basys-3-Master.xdc
Final
ยท 2025-09-03
2025-09-02
UVM ๊ฒ์ฆ System Verilog : ๊ฒ์ฆ์ ๋ํ ํ์ค์ด ๋์ด๊ฐ๊ณ ์์ UVM : ๊ฒ์ฆ Framework, System Verilog ๋ก ์ค๊ณ ย Verilog System Verilog OOP(๊ฐ์ฒด์งํฅ) X(Class X) O(Class ๋ฌธ๋ฒ ์ฌ์ฉ) DataType H/W ์ค์ฌ DataType S/W ์ค์ฌ DataType(S/W ๊ธฐ๋ฅ ์ถ๊ฐ) interface X SW <=> HW ์ฐ๊ฒฐ๊ฒ์ฆ์ฉ SW <=> DUT HW randomization random์ ํ์ ๊ธฐ๋ฅ ๊ฐ ๋ณ์์ random ์์ฑconstraint ๊ธฐ๋ฅcorner case ์์ฑ System Verilog Data Type 4-state(๋ฒกํฐ) : 0, 1, x, z -> logic, reg, wire 2-state(๋ฒกํฐ) : 0, 1 -> bit 4-state(์ ์) : integer(32bit) 2-state(์ ์) : byte(8), shortint(16), int(32), longint(64) ๋ฐฐ์ด (SW ์๋ฃํ) ๊ณ ์ ๊ธธ์ด ๋ฐฐ์ด (fixed-size array, static array) ์ ์ธ ์ ํฌ๊ธฐ๊ฐ ๊ณ ์ ๋๊ณ runtime์ ํฌ๊ธฐ ๋ณ๊ฒฝ๋ถ๊ฐ ์: bit arr[8]; // 8๊ฐ์ bit ์์ byte arr2[4]; // 4๊ฐ์ byte ์์ int arr3[16]; // 16๊ฐ์ int ์์ ๋์ ๋ฐฐ์ด (dynamic array) ์ ์ธ๋ง ํด๋๊ณ , runtime์ new๋ฅผ ํตํด ํฌ๊ธฐ ๊ฒฐ์ ํ์ ์ ํฌ๊ธฐ ๋ณ๊ฒฝ ๊ฐ๋ฅ (new[] ์ฌํธ์ถ) ์: bit arr[]; arr = new[8]; // ํฌ๊ธฐ 8๋ก ํ ๋น int arr2[]; arr2 = new[16]; // ํฌ๊ธฐ 16์ผ๋ก ์ฌํ ๋น ๊ฐ๋ฅ delete() ์ฌ์ฉ ์ ๋ฉ๋ชจ๋ฆฌ ํด์ ๊ฐ๋ฅ ๊ณ ์ ๊ธธ์ด ๋ฐฐ์ด์ ํ๋์จ์ด์ ๊ฐ๊น๊ณ (Verilog ์คํ์ผ), ๋์ ๋ฐฐ์ด์ ์ํํธ์จ์ด์ ์ฑ๊ฒฉ (ํ ์คํธ๋ฒค์น, ๊ฒ์ฆ ํ๊ฒฝ)์์ ์ฃผ๋ก ํ์ฉ Queue Type (FIFO) ํฌ๊ธฐ๊ฐ ๊ฐ๋ณ์ ์ด๊ณ , ์๋ค๋ก push/pop ๊ฐ๋ฅ ์ ์ธ: bit que[$]; // bit ํ์ queue int que2[$]; // int ํ์ queue ์ฃผ์ ๋ฉ์๋: que.push_back(1); // ๋ค์ ์ฝ์ que.push_front(4); // ์์ ์ฝ์ que.pop_front(); // ์์์ ๊บผ๋ que.pop_back(); // ๋ค์์ ๊บผ๋ ๊ทธ ์ธ ์์ฃผ ์ฐ์ด๋ ๋ฉ์๋: que.size() // ํ์ฌ ํฌ๊ธฐ ๋ฐํ que.delete() // ๋ชจ๋ ์์ ์ญ์ que.insert(idx, value) // ํน์ ์์น์ ์ฝ์ que.delete(idx) // ํน์ ์์น ์์ ์ญ์ Queue๋ UVM testbench์์ transaction ์ ์ฅ/์ ๋ฌ, mailbox ๋์ฒด ์ฉ๋ ๋ฑ์ผ๋ก ์์ฃผ ํ์ฉ Test Bench, UVM ๊ตฌ์กฐ์ System Verilog ๊ฒ์ฆ Test Bench generator(์ ๋ ฅ data ์์ฑ) : stimulus ์์ฑ (transaction ๋จ์) driver(์ ๋ฌ) : transaction์ ํ ๋ ๋ฒจ ์ ํธ๋ก ๋ณํํด DUT ์ ๋ ฅ์ ์ ์ฉ monitor(๊ฐ์) : DUT ์ ์ถ๋ ฅ์ ํธ๋์ญ์ ์ผ๋ก ๋ณํํด ์ ๋ฌ scoreboard(pass/fail ํ๋จ) : ์์ธก๊ฐ๊ณผ DUT ์ถ๋ ฅ์ ๋น๊ต, ๊ฒ์ฆ ์ํ interface(์ฐ๊ฒฐ) : ์ ํธ ๋ฌถ์๊ณผ ๋ฐฉํฅ ์ ์ด, driver/monitor์ DUT ๊ฐ ์ฐ๊ฒฐ DUT(HW) : testbench๊ฐ ์๊ทน์ ์ฃผ๊ณ , ์๋ต์ ํ๊ฐํ๋ ๋์ ์ค์ต class : generator, driver ๋ง๋ค๊ณ ๊ฐ์ธ๋ env ๋ง๋ค๊ณ interface, dut ๋ง๋ค๋ฉด ๋จ ๋ฐ์ดํฐ ๋ฌถ์์ ์ ๋ฌํ๊ธฐ ์ํด ์ด๋ป๊ฒ? ๊ตฌ์กฐ์ฒด๋ฅผ ์ง์ํ์ง๋ง class ๋ฅผ ์ฐ๋ ๊ฒ ์ผ๋ฐ์ ์ transaction = ๋ฐ์ดํฐ ๋ฌถ์ (stimulus ๋จ์) โ ๋ณดํต class๋ก ์ ์ C์ธ์ด์์ ๊ตฌ์กฐ์ฒด(struct)๋ ๋จ์ ๋ฐ์ดํฐ ๋ฌถ์์ ์ ํฉ SystemVerilog class๋ ๋ณ์ + ๋ฉ์๋๋ฅผ ํจ๊ป ๋ฃ์ ์ ์์ด ๊ฐ์ฒด์งํฅ(OOP) ์คํ์ผ์ ์ฌ์ฌ์ฉยทํ์ฅ์ด ๊ฐ๋ฅ โ UVM ๊ฒ์ฆ ํ๊ฒฝ์ ๊ธฐ๋ณธ ๋จ์ module tb_adder (); environment env; // Class adder_intf adder_if (); // HW(๋ฉ๋ชจ๋ฆฌ๊ฐ ์๋) adder dut ( // HW .a(adder_if.a), .b(adder_if.b), .result(adder_if.result) ); initial begin env = new(adder_if); // new(virtual adder_intf adder_if(์ค์ HW์ ๋ณด ์ ๋ ฅ) = adder_if) ๊ฐ๋ช ์ ์ฐ๊ฒฐํ ๋๋ env.run(); end endmodule class environment; generator gen; driver drv; mailbox #(transaction) gen2drv_mbox; function new(virtual adder_intf adder_if); // ์์ new๋ฅผ ์ฝํจ. virtual(HW๋ฅผ SW์ ์ผ๋ก ์ฐ๊ฒฐ)๋ ๊ฐ์์ธํฐํ์ด์ค(HW๋ฅผ ๊ทธ๋ฅ ์ ๋ฌํ๋ฉด ์๋จ, SW์ฒ๋ผ ์๊ฐํ์) gen2drv_mbox = new(); // ์ ๋ณด๋ฅผ ์ฃผ๊ณ gen = new(gen2drv_mbox); // ์ ๋ณด๋ฅผ ์ฃผ๊ณ drv = new(gen2drv_mbox, adder_if); // ์ ๋ณด๋ฅผ ์ฃผ๊ณ endfunction task run(); fork gen.run(20); drv.run(); join_any #(10 * 10) $finish; endtask endclass class driver; transaction tr; virtual adder_intf adder_if; mailbox #(transaction) gen2drv_mbox; function new(mailbox#(transaction) gen2drv_mbox, // ์ฃผ์ virtual adder_intf adder_if); // HW์ ๋ณด this.gen2drv_mbox = gen2drv_mbox; this.adder_if = adder_if; endfunction task run(); forever begin gen2drv_mbox.get(tr); adder_if.a = tr.a; adder_if.b = tr.b; end endtask endclass class generator; transaction tr; // handler mailbox #(transaction) gen2drv_mbox; function new(mailbox#(transaction) gen2drv_mbox); this.gen2drv_mbox = gen2drv_mbox; endfunction task run(int run_count); repeat (run_count) begin tr = new(); // make instance. ์ค์ฒดํ ์ํจ๋ค. heap memory์ class ์๋ฃํ์ ๋ง๋ ๋ค. tr.randomize(); gen2drv_mbox.put(tr); // ํด๋น ์ธํฐํ์ด์ค์ ์ฃผ์๊ฐ(tr)์ ๋ฃ์ด์ค #10; end endtask endclass class environment; generator gen; driver drv; mailbox #(transaction) gen2drv_mbox; function new(virtual adder_intf adder_if); gen2drv_mbox = new(); gen = new(gen2drv_mbox); drv = new(gen2drv_mbox, adder_if); endfunction task run(); fork // ๋ฉํฐ ํ๋ก์ธ์ ์คํ gen.run(20); // ๋ ์ง์ ์ผ๋ก ๋์๊ฐ drv.run(); // ๋ ์ง์ ์ผ๋ก ๋์๊ฐ join_any #(10 * 10) $finish; endtask endclass fork-join : SW์ ์ผ๋ก ๋ณ๋ ฌ ์คํ์ ์ง์, gen.run(20) ๊ณผ drv.run() ์ด ๋์์ ์คํ (HW always ๋ธ๋ก 2๊ฐ๊ฐ ๋ณ๋ ฌ๋ก ๋๋ ๊ฒ๊ณผ ์ ์ฌํ ๊ฐ๋ ) ์ธ์คํด์ค๋ค์.๋ฉ์๋ ๊ตฌ์กฐ : ๋ฉ์๋์ ๊ธฐ๋ฅ์ ํธ์ถ fork-join : ์ ๋ถ ๋๋์ผ ๋ค์์ผ๋ก fork-join_any : ํ๋๋ผ๋ ๋๋๋ฉด ๋ค์์ผ๋ก (๋๋จธ์ง๋ ๊ณ์ ์คํ๋จ) fork-join_none : ์์๋ง ์ํค๊ณ ๋ฐ๋ก ๋ค์์ผ๋ก forever : ์กฐ๊ฑด ์๋ ๋ฌดํ ๋ฃจํ ๋น๋๊ธฐ์ adder < adder.sv > `timescale 1ns / 1ps module adder ( input logic [7:0] a, input logic [7:0] b, output logic [8:0] result ); assign result = a + b; endmodule < tb_adder.sv > `timescale 1ns / 1ps interface adder_intf; logic [7:0] a; logic [7:0] b; logic [8:0] result; endinterface class transaction; rand bit [7:0] a; rand bit [7:0] b; bit [8:0] result; endclass class generator; transaction tr; // handler mailbox #(transaction) gen2drv_mbox; // mailbox ์ฌ์ฉ โ generator์ driver ๊ฐ์ ํ/ํต์ ์ฑ๋ function new(mailbox#(transaction) gen2drv_mbox); this.gen2drv_mbox = gen2drv_mbox; endfunction task run(int run_count); repeat (run_count) begin tr = new(); // Heap์ transaction ๊ฐ์ฒด ์์ฑ // make instance. ์ค์ฒดํ ์ํจ๋ค. heap memory์ class ์๋ฃํ์ ๋ง๋ ๋ค. tr.randomize(); // ๋๋ค ์ ๋ ฅ ์์ฑ gen2drv_mbox.put(tr); // driver ์ชฝ์ผ๋ก ์ ๋ฌ #10; end endtask endclass class driver; transaction tr; virtual adder_intf adder_if; mailbox #(transaction) gen2drv_mbox; function new(mailbox#(transaction) gen2drv_mbox, virtual adder_intf adder_if); this.gen2drv_mbox = gen2drv_mbox; this.adder_if = adder_if; endfunction task run(); forever begin gen2drv_mbox.get(tr); // generator์์ transaction ๋ฐ์ adder_if.a = tr.a; // DUT ์ ๋ ฅ์ ํ ๋น adder_if.b = tr.b; // DUT ์ ๋ ฅ์ ํ ๋น end endtask endclass class monitor; transaction tr; virtual adder_intf adder_if; mailbox #(transaction) mon2scb_mbox; function new(mailbox#(transaction) mon2scb_mbox, virtual adder_intf adder_if); this.mon2scb_mbox = mon2scb_mbox; this.adder_if = adder_if; endfunction task run(); forever begin #1; tr = new(); tr.a = adder_if.a; tr.b = adder_if.b; tr.result = adder_if.result; mon2scb_mbox.put(tr); #10; end endtask endclass class scoreboard; transaction tr; mailbox #(transaction) mon2scb_mbox; bit [7:0] a, b; function new(mailbox#(transaction) mon2scb_mbox); this.mon2scb_mbox = mon2scb_mbox; endfunction task run(); tr = new(); forever begin mon2scb_mbox.get(tr); a = tr.a; b = tr.b; if (tr.result == (a + b)) begin $display("PASS! : %d + %d = %d", a, b, tr.result); end else begin $display("FAIL! : %d + %d = %d", a, b, tr.result); end end endtask endclass class environment; // generator, driver ๋ฑ testbench ๊ตฌ์ฑ ์์๋ฅผ ๋ฌถ๋ top-level class generator gen; driver drv; monitor mon; scoreboard scb; mailbox #(transaction) gen2drv_mbox; mailbox #(transaction) mon2scb_mbox; function new(virtual adder_intf adder_if); gen2drv_mbox = new(); // mailbox ์์ฑ mon2scb_mbox = new(); // mailbox ์์ฑ gen = new(gen2drv_mbox); // generator ์์ฑ drv = new(gen2drv_mbox, adder_if); // driver ์์ฑ mon = new(mon2scb_mbox, adder_if); // monitor ์์ฑ scb = new(mon2scb_mbox); // scoreboard ์์ฑ endfunction task run(); fork gen.run(1000); // 20๊ฐ stimulus ์์ฑ drv.run(); // DUT์ ๊ณ์ ์ ์ฉ mon.run(); // DUT์ ๊ณ์ ์ ์ฉ scb.run(); // DUT์ ๊ณ์ ์ ์ฉ join_any #(10 * 10) $finish; endtask endclass module tb_adder (); // DUT์ interface ์์ฑ โ environment ์คํ environment env; adder_intf adder_if (); // adder_if๋ผ๋ interface๋ฅผ ์์ฑํ์ฌ DUT์ TB๋ฅผ ์ฐ๊ฒฐ adder dut ( .a(adder_if.a), .b(adder_if.b), .result(adder_if.result) ); initial begin env = new(adder_if); // environment ์์ฑ env.run(); // ์๋ฎฌ๋ ์ด์ (generator/driver) ์คํ end endmodule ๋๊ธฐ์ adder < adder.sv > `timescale 1ns / 1ps module adder ( input logic clk, input logic [7:0] a, input logic [7:0] b, output logic [8:0] result ); always_ff @(posedge clk) begin result <= a + b; end endmodule < tb_adder.sv > `timescale 1ns / 1ps interface adder_intf; logic clk; logic [7:0] a; logic [7:0] b; logic [8:0] result; endinterface class transaction; rand bit [7:0] a; rand bit [7:0] b; bit [8:0] result; endclass class generator; transaction tr; // handler mailbox #(transaction) gen2drv_mbox; // mailbox ์ฌ์ฉ โ generator์ driver ๊ฐ์ ํ/ํต์ ์ฑ๋ function new(mailbox#(transaction) gen2drv_mbox); this.gen2drv_mbox = gen2drv_mbox; endfunction task run(int run_count); repeat (run_count) begin tr = new(); // Heap์ transaction ๊ฐ์ฒด ์์ฑ // make instance. ์ค์ฒดํ ์ํจ๋ค. heap memory์ class ์๋ฃํ์ ๋ง๋ ๋ค. tr.randomize(); // ๋๋ค ์ ๋ ฅ ์์ฑ gen2drv_mbox.put(tr); // driver ์ชฝ์ผ๋ก ์ ๋ฌ #10; end endtask endclass class driver; transaction tr; virtual adder_intf adder_if; mailbox #(transaction) gen2drv_mbox; function new(mailbox#(transaction) gen2drv_mbox, virtual adder_intf adder_if); this.gen2drv_mbox = gen2drv_mbox; this.adder_if = adder_if; endfunction task run(); forever begin gen2drv_mbox.get(tr); // generator์์ transaction ๋ฐ์ adder_if.a = tr.a; // DUT ์ ๋ ฅ์ ํ ๋น adder_if.b = tr.b; // DUT ์ ๋ ฅ์ ํ ๋น @(posedge adder_if.clk); end endtask endclass class monitor; transaction tr; virtual adder_intf adder_if; mailbox #(transaction) mon2scb_mbox; function new(mailbox#(transaction) mon2scb_mbox, virtual adder_intf adder_if); this.mon2scb_mbox = mon2scb_mbox; this.adder_if = adder_if; endfunction task run(); forever begin tr = new(); @(posedge adder_if.clk); #1; tr.a = adder_if.a; tr.b = adder_if.b; tr.result = adder_if.result; mon2scb_mbox.put(tr); end endtask endclass class scoreboard; transaction tr; mailbox #(transaction) mon2scb_mbox; bit [7:0] a, b; function new(mailbox#(transaction) mon2scb_mbox); this.mon2scb_mbox = mon2scb_mbox; endfunction task run(); // tr = new(); forever begin mon2scb_mbox.get(tr); a = tr.a; b = tr.b; if (tr.result == (a + b)) begin $display("PASS! : %d + %d = %d", a, b, tr.result); end else begin $display("FAIL! : %d + %d = %d", a, b, tr.result); end end endtask endclass class environment; // generator, driver ๋ฑ testbench ๊ตฌ์ฑ ์์๋ฅผ ๋ฌถ๋ top-level class generator gen; driver drv; monitor mon; scoreboard scb; mailbox #(transaction) gen2drv_mbox; mailbox #(transaction) mon2scb_mbox; function new(virtual adder_intf adder_if); gen2drv_mbox = new(); // mailbox ์์ฑ mon2scb_mbox = new(); // mailbox ์์ฑ gen = new(gen2drv_mbox); // generator ์์ฑ drv = new(gen2drv_mbox, adder_if); // driver ์์ฑ mon = new(mon2scb_mbox, adder_if); // monitor ์์ฑ scb = new(mon2scb_mbox); // scoreboard ์์ฑ endfunction task run(); fork gen.run(10); // 20๊ฐ stimulus ์์ฑ drv.run(); // DUT์ ๊ณ์ ์ ์ฉ mon.run(); // DUT์ ๊ณ์ ์ ์ฉ scb.run(); // DUT์ ๊ณ์ ์ ์ฉ join_any #(10 * 10) $finish; endtask endclass module tb_adder (); // DUT์ interface ์์ฑ โ environment ์คํ environment env; adder_intf adder_if (); // adder_if๋ผ๋ interface๋ฅผ ์์ฑํ์ฌ DUT์ TB๋ฅผ ์ฐ๊ฒฐ adder dut ( .clk (adder_if.clk), .a (adder_if.a), .b (adder_if.b), .result(adder_if.result) ); always #5 adder_if.clk = ~adder_if.clk; initial begin adder_if.clk = 1; end initial begin env = new(adder_if); // environment ์์ฑ env.run(); // ์๋ฎฌ๋ ์ด์ (generator/driver) ์คํ end endmodule < ํ์ผ : ๋๊ธฐ์ adder > sources (Class) text simulation (Class) text
Final
ยท 2025-09-02
2025-09-01
๐ ์ทจ์ ์ญ๋ ๊ฐํ (๋ฉด์ ) ๐ค PT ๋ฉด์ PT ๋ฉด์ ์ด ์๋ค๋ฉด ๋ณ๋ ์ค๋น ํ์ ๐ป ๋น๋๋ฉด ๋ฉด์ ํฉ๊ฒฉ ์๊ทธ๋, ์ํธ ํผ๋๋ฐฑ์ ๋ฐ๊ธฐ ์ด๋ ค์ ํผ๋๋ฐฑ์ ๋ฐ์ผ๋ ค๋ฉด ์ ๊ทน์ ์ผ๋ก ์ง๋ฌธ์ ํด์ผ ํจ ๐โโ๏ธ ์ง๋ฌธ ๋์ ๋ชจ๋ ์ง๋ฌธ์๋ ์ง์ ์ฑ์ด ๋๊ปด์ง๋๋ก ๋๋ต ๋ชจ๋ฅด๋ ๋ด์ฉ์ด ๋์ค๋ฉด? ์์งํ๊ฒ โ๋ชจ๋ฅธ๋คโ๋ผ๊ณ ๋ต๋ณ ์ต๋ํ ์๋ ์ ์์ ๋ณด์ ์ค๋ช ๐ฅ ๊ทธ๋ฃน ๋ฉด์ ์ ๊ฐ์ ์ง๋ฌธ์ ์ ์ฌ๋์ด ๋จผ์ ๋ต๋ณํ๋ค๋ฉด โ ์ฐจ๋ณํ๋ ๊ด์ ์ผ๋ก ๋ต๋ณ ์ค๋น ์๊ธฐ์๊ฐ ์คํฌ๋ฆฝํธ ๊ฐ์ธ์ํค๋ ์ฒซ ๋ฌธ์ฅ ์๋ ํ์ญ๋๊น, ์ค๊ณ๋ถํฐ ๊ฒ์ฆ, ๊ทธ๋ฆฌ๊ณ ์๋ฒ ๋๋์ AI๊น์ง ๊ฒฝํ์ ํ์ฅํด์จ ๋์ ์ ์์ด์ฝ์ด์ ๋์์์ด ๋ฐฐ์ฐ๋ฉฐ ์ฑ์ฅํ๋ ์ง์์ ์์ฌํ์ ๋๋ค. ๋๋ฅผ ์ค๋ช ํ๋ ๋ฌธ์ฅ ์ ์ ์ฒ ํ์ โ์์ ์ฑ์ทจ๋ฅผ ์์ ํฐ ์ฑ์ฅ์ ๋ง๋ ๋คโ์ ๋๋ค. ์์ธ๊ธฐ์ ๊ต์ก์ผํฐ์์ Verilog์ SystemVerilog๋ฅผ ํ์ฉํด RISC-V CPU์ FFT ์ค๊ณ๋ฅผ ์ํํ๋ฉฐ RTL ์ค๊ณ์ ๊ฒ์ฆ์ ๊ธฐ๋ณธ๊ธฐ๋ฅผ ๋ค์ก์ต๋๋ค. ๋ํ STM32 ๊ธฐ๋ฐ์ ์ ํฌ๊ธฐ ๊ฒ์์ ๊ฐ๋ฐํ๊ณ , FPGA๋ก ์๊ณยท์คํฑ์์นยท์ผ์ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๋ฉฐ ํ๋์จ์ด์ ํ์จ์ด์ ์ฐ๊ฒฐ์ ์ง์ ๊ฒฝํํ์ต๋๋ค. ๋์๊ฐ Python๊ณผ ONNX ๊ธฐ๋ฐ์ผ๋ก ํผ๋ถ ์งํ ์ง๋จ AI ์์คํ ์ ์ ์ํ์ฌ ์ํํธ์จ์ด์ AI ๊ธฐ์ ๊น์ง ์์ฐ๋ฅด๋ ์๊ฐ์ ๊ธธ๋ ์ต๋๋ค. ์ ๋ ์ด๋ฌํ ๊ณผ์ ์์์ ๋ฌธ์ ์ ์ง๋ฉดํ๋ฉด ํ์๊ณผ ํ์ ํ๋ฉฐ ํจ๊ป ๋ถ์ํด๊ณ ํด๊ฒฐํด๋๊ฐ๋ฉฐ ์ฑ๊ณผ๋ฅผ ๋ง๋ค์ด๋ด๋ ๊ณผ์ ์์ ํฐ ๋ณด๋์ ๋๊ผ์ต๋๋ค. ๋ง๋ฌด๋ฆฌ ๋ฌธ์ฅ ์ ๊ฐ ๊ท์ฌ์ ์ ์ฌํ๊ฒ ๋๋ค๋ฉด ์์ผ๋ก๋ ๋ฐฐ์ฐ๋ ์์ธ์ ๋์ ์ ์ ์ ๋ฐํ์ผ๋ก, ๋์ฒด๋ถ๊ฐ๋ฅํ ๋ฐ๋์ฒด ์ค๊ณ ์ธ์ฌ๋ก ์ฑ์ฅํ๊ฒ ์ต๋๋ค. ๊ฐ์ฌํฉ๋๋ค. ํผ๋๋ฐฑ ์ ๋ถ ์ธ์ฐ๊ธฐ ํ๋ค ์๋ ์์ผ๋ ๋ด์ฉ ์ค์ผ ๊ฒ ํผ์ ์ฐ์ตํ ๋ 40์ด ์ด๋ด๋ก ๋๋ ๋ถ๋์ผ๋ก ์คํฌ๋ฆฝํธ ์์ฑ
Final
ยท 2025-09-01
2025-08-29
๐ ์ทจ์ ์ญ๋ ๊ฐํ (์์์) ๐ Google ์๋ฆฌ๋ฏธ ํน์ ํค์๋(์: โ๋ฐ๋์ฒด ์ฑ์ฉโ, โAI ๋ฐ๋์ฒดโ)๋ฅผ ๋ฑ๋กํ๋ฉด ์๋ก์ด ๋ด์ค/์น๋ฌธ์๊ฐ ๋์ค๋ฉด Gmail๋ก ์๋ฆผ ๋์ฐฉ ์ฐ์ ๊ตฐ ๋๋ ๊ด์ฌ ๊ธฐ์ ๊ด๋ จ ์๋ฆผ๋ ์ค์ ๊ฐ๋ฅ ๐ ์๊ธฐ์๊ฐ์ ์์ฑ ๊ด๋ จ GPT๊ฐ ์ด ์์์๋ ์ธ์ฌ๋ด๋น์์๊ฒ ์ง์ ์ฑ์ ์ฃผ์ง ๋ชปํจ ๊ฐ์น๊ด ์ํผ์๋ ํ์ฉ ์ ๋ต: ๊ฐ์น๊ด + ๋ณธ์ธ ๊ฐ์ ์ญ์ง์ฌ์ง๋ก ๊ฐ์น๊ด์ ํ์ด๋ด๋ฉด ์ข์ (์ง๋ฌด๊ฒฝํ ์ฐ๊ฒฐ) ๋จ์ํ ๋ด์ฉ๋ง ์ฑ์ฐ์ง ๋ง๊ณ , ์ ๋ชฉ๊น์ง ๊ณ ๋ คํด์ผ ํจ ๋ค์ด๋ก๋๋ฅผ ์ํด PPT, PDF ํ์ ํ์ํ ๊ฒฝ์ฐ ์์ ๐ ์ฑ์ฉ ๋ํฅ ๋ฐ ์ธ์ฌ์ ์ฑ์ฉ ๋ํฅ: ๋ฌ๋ ์ด๋น๋ฆฌํฐ ์๋ ์ธ์ฌ์ ๋ณํ โ ๊ณต๊ธฐ์ ์์์ ํ์ฉ ์ฌ๋ก ์ฆ๊ฐ ์ค๋ฌด ๊ฒฝํ์ ํ์์ฑ ๊ฐ์กฐ ๊ธฐ์ ๋ถ์: ๊ฒฝ์์ด๋ โ ํต์ฌ๊ฐ์น โ ์ธ์ฌ์ โ ํ๋์์ ๐ ์ ๋ณด ์์ง ์ฑ๋ ์ค์๊ธฐ์ ํํฉ์ ๋ณด์์คํ ์ทจ์ ํ๋ซํผ : ์ฌ๋์ธ, ์ก์ฝ๋ฆฌ์, ์ฝ๋ฉํ , ๋ธ๋ผ์ธ๋ โ ์๋ฆผ ์ค์ ๋ฆฌ๋ฉค๋ฒ : ๋ฐฉ๋ช ๋ก ๊ธฐ๋ฅ ํ์ฉ ๐ก ๊ธฐ์ ๋ถ์ & ์ ์ฌ ๋๊ธฐ Right People ํ์ฌ ๊ฐ์น๊ด์ ๋ณด๊ณ โ ์ ํธ ์ด์, ๋ด์ค ํ์ธ โ ๋ด ๊ฒฝํยท๊ฐ์น์ ์ฐ๊ฒฐ ์ ์ฌ๋๊ธฐยทํฌ๋ถ๋ฅผ ์ง๋ฌด ์ค์ฌ์ผ๋ก ์ฐ๋ฉด, ํ์ฌ๊ฐ ๋ฐ๋์ด๋ ์์ ํ ๋ด์ฉ์ด ์ต์ํ๋จ ์ง์ยท์ญ๋ยทํ๋ ๊ธฐ์ค์ผ๋ก ์ง๋ฌด ๋ถ์ โ๋๋ ์ด๋ฐ ์ธ์ฌ์ด๋คโ ์ ์์ ์ ์ง์ ๐ ๋ฉด์ ๋ฐ ์๊ธฐ์๊ฐ ์ ๋ต ๊ด๋ฆฌ์ยทCEO ์ธ์ฌ๋ง ์ฐธ๊ณ ๋ฉด์ ์์๋ ๊ธฐ๋ณธ๊ธฐ ์ค์ ์ฑ์ฅ ๋๋ ฅ = ํธ๊ธฐ์ฌ ํค์๋ ์ธ์ฌ๋ด๋น์ ์ ์ฅ์์ ์ฐ๊ธฐ ๊ฐ๊ดํ / ์์นํ STAR ๊ธฐ๋ฒ: ๊ฒฐ๋ก โ ๋ณธ๋ก (STAR) โ ๊ฒฐ๋ก ๐งฐ ์์ฑ ๊ฐ์ด๋ ์ฅ์ 7๊ฐ, ๋จ์ 3๊ฐ (๋จ์ ์ ๊ฐ์ ์ค์์ ๊ฐ์กฐ, ์์ ๋ถํ์) ๋ฌธ์ ํด๊ฒฐ ๋ฅ๋ ฅ (STAR ๊ธฐ๋ฒ) S: ์ํฉ์ ๋ฌด์์ด์๋? T: ์ญํ ์ ๋ฌด์์ด์๋? A: ์ด๋ค ํ๋์ ํ๋? R: ๊ฒฐ๊ณผ๋ ์ด๋ ๋? (์ฑ๊ณต ์ฌ๋ก ์์ฃผ) ๐โโ๏ธ ์๊ธฐ ์ดํด ์ง๋จ ๋ด๊ฐ ์์ฃผ ๋ฃ๋ ์นญ์ฐฌ์? ๋ด๊ฐ ๊ฐ์ฅ ์ด์ ์ ๋๋ผ๋ ํ๋์? ์น๊ตฌ๋ค์ด ์ฃผ๋ก ๋งก๊ธฐ๋ ์ญํ ์? ๋ด๊ฐ ์ข์ํ๋ ์์ /๊ณผ๋ชฉ์? ์๊ฐ์ด ํ๋ฅด๋ ์ค ๋ชจ๋ฅด๊ณ ๋ชฐ์ ํ ๊ฒฝํ์? ๋ฐ๋๋ ์๊ฐ(ํฐ๋ํฌ์ธํธ)์ด ์๋ค๋ฉด? ๐ท๏ธ ๋์ ๊ฐ์ ํค์๋ ์ญ๋์ ์ฃผ๋ก ํค์๋ํ โ #์๋์ง๋ฟ๋ฟ #์ฐฝ์กฐ์ ์ฌ๊ณ #๋์ ์์์ด์ฝ #์ด์ ์์ ์ #์นํ๋ ฅ์์ ๋์ ๊ฐ์ ํค์๋ ๋์ถ ๋์ ๊ฐ์ 2๊ฐ ์น๊ตฌ๊ฐ ๋ณธ ๊ฐ์ 2๊ฐ ์ต์ข ์ ์ ๊ฐ์ 2๊ฐ ์๊ธฐ์๊ฐ์ PPT ์ง์ ๋๊ธฐ ๋ฐ ์ ์ฌ ํ ํฌ๋ถ ํ๋ ์ผ, ์ญ๋, ํด๋น ๊ฒฝํ ๋ฐฐ์นํ๊ธฐ ์ฐ์ ํน์ฑ ๋ฐ ์ด์, ์ฐ์ ๋ด ํ์ฌ ๋ฐฉํฅ ์ง์ ์ง๋ฌด ๋ฐ ๋ถ์์ ์ญํ /ํ์์ฑ๊ณผ ์์ ์ ์ ํฉ์ฑ ๊ฐ๋จํ๊ฒ ๊ฐ์กฐ ํฅํ ์ ๋ฌด, ์ญํ ์ํ ๊ณํ ๊ฐ๊ฒฐํ๊ฒ ์ง์ํ ํ์ฌ์ ์ง์ค โโ๋ถ์ผ์์ ~ํ ~์ปค๋ฆฌ์ด ๋ชฉํ, ์ ๋ฌด์ํ ๋ชฉํ ์ธ๋ถ๊ณํ ์ธ๊ฐ์ง ๊ฒฝ๋ ฅ์์ ์๊ฐ์ ์ฐธ๊ณ ํ๊ธฐ NCS์ ๋ฌด ๋ถ์ ์ฐธ๊ณ ํ๊ธฐ ํ์ง์ ์์๋ณด๊ธฐ ~ํ ์ธ์ฌ๊ฐ ๋๊ฒ ์ต๋๋ค.(O) / ~ํ ์ธ์ฌ์ ๋๋ค.(X) ์ฑ์ฅ ๊ณผ์ ์ฑ์ฅ์์ผ์จ ๋์ ์ ๋ , ๊ธฐ์ค ์ฅ์๊ฐ ์ค์ฒํด์จ ์ฌ๋ก ํฌ๋ง ์ง๋ฌด, ํ์ ์ฑํฅ/์กฐ์ง ์ตํ ๊ด๋ จ ์ฅ์ ์ ํค์์จ ์ฌ๋ก ๊ฐ์กฑ ์๊ฐX, ๋ฉํ ์๊ฐX, ๋ถ์ ์ ์๊ฐX 25์ธ ์ด์์ด๋ฉด ์ฑ์ธ ๋ ์ด์ผ๊ธฐ๋ง ์ด๋ค(๋ณธ์ธ์ ์์ง, ์ฑํฅ๋ง ์ด๋ค) ์ฑ๊ฒฉ์ ์ฅ๋จ์ ์ง๋ฌด์ ์ง์ ์ ์ผ๋ก ์ฐ๊ด๋๋ ์ฅ์ (์ฅ์ ์ฌ๋ก, ์ฅ์ ์ ๊ฐ์ง๊ณ ์ง๋ฌด์ ๊ธฐ์ฌํ ์ ์๋ ๋ถ๋ถ) ๋จ์ ์ ๋ณด์ํ๋ ๋ ธ๋ ฅ ํจ๊ป ์์ฑ ์ฅ๋จ์ ์ ๋น์จ 7:3 โ ํ์ง ๋ง์์ผ ํ ๊ฒ: ์ฅ์ ์ด์ ๋จ์ ์ด ๋๋ ๊ฒ, ๋ถ๋ฆฌ(ํฌ์ ์ํค์ง ๋ง์/๋จ์ ์ธ ๋ฏ, ์ฅ์ ์ธ ๊ฒ), ๋จ์ ์ ๋ ธ๋ ฅ์ ํ์ฌ์งํํ์ด์ด์ผ ํจ ํน๊ธฐ ์ฌํญ ์ง๋ฌด ๊ฒฝํ ์์ฑ ์ ์ง๋ฌด์ ๊ด๋ จ๋ ์ง์ ์ ์ธ ๊ฒฝํ(์ค๋ฌด) โ ์ง๋ฌด์ญ๋(์ฑ๊ฒฉX) ์์ ์ ์ญํ , ํฅ์์ํจ ์ค๋ฌด์ญ๋, ๊ทธ ๊ฒฝํ์ ํตํด ๋ฐฐ์ด ์ ๋ฑ ๊ฐ์ฅ ์ง์ ์ ์ผ๋ก ๊ฒช์ด๋ณธ ์ง๋ฌด ๊ฒฝํ ์ํ๋ ์ญ๋ 1๊ฐ์ง ์ฉ! ๊ฐ์ ๊ฒฝํ์ ์ค๋ณตํ์ฌ ๊ธฐ์ ํ์ง ์๋๋ก ์ฃผ์ ์์ ์๊ฒ ๋งก๊ฒจ์ง ์ผ์ด๋ ๊ณผ์ ๋ฅผ ๋ฐค์ ์์ธ ์ ๋๋ก ์ด์คํ์ฌ ์ฑ๊ณต์ ์ผ๋ก ์์ํ ๊ฒฝํ ์ด์ ์ ๋ง์ธ๋์ ํ๋์ ํตํด ์์ ์ ์ถ์ด ๋ณํ๋๊ณ , ๊ธ์ ์ ์ธ ์ํฅ์ ๋ผ์น ๊ฒฝํ
Final
ยท 2025-08-29
2025-08-28
APB Slave Interface RAM Design < Design Specification > Address ๊ธฐ์ค์ผ๋ก broadcast ํ๋ ๊ตฌ์กฐ : BUS ๊ตฌ์กฐ /* APB_Slave ๊ตฌ์กฐ ์ฐธ๊ณ */ if (PWRITE) begin // ์ฐ๊ธฐ ๋์ case (PADDR[3:2]) // ์ฃผ์์ ๋ฐ๋ฅธ 2'd0: slv_reg0 <= PWDATA; 2'd1: slv_reg1 <= PWDATA; 2'd2: slv_reg2 <= PWDATA; 2'd3: slv_reg3 <= PWDATA; endcase end else begin // ์ฝ๊ธฐ ๋์ case (PADDR[3:2]) // ์ฃผ์์ ๋ฐ๋ฅธ 2'd0: PRDATA <= slv_reg0; 2'd1: PRDATA <= slv_reg1; 2'd2: PRDATA <= slv_reg2; 2'd3: PRDATA <= slv_reg3; endcase end < Simulation > APB๋ CPU ๋ ready ์ ํธ๊ฐ ๋ค์ด์ฌ ๋๊น์ง ๋ช ํด๋ญ์ด๋ ๋๊ธฐ AHB๋ ํ์ดํ๋ผ์ธ๊ตฌ์กฐ๋ผ์ ๋๊ธฐํ๋ ์๊ฐ์ด ์งง์ RAM ์คํํฌ์ธํฐ ์์น 0x1000_0000 ~ 0x1000_0FFF ๋ง์ถฐ์ SP๋ฅผ RAM ์ต์๋จ์ผ๋ก ์ด๊ธฐํํด์ผ ํจ < SW ๊ฒ์ฆ : Store, Load Test> int main() { int a, b, c; a = 1; b = 2; c = a + b; return 0; } < Simulation > GPO Design < Design Specification > GPO ๋ฅผ ๋ง๋ค์ด์ ์ฐ๊ฒฐ์ ์ํ๋ฉฐ, LED๋ ์ฐ๊ฒฐํ๋ค. < APB_Peripheral ๋ด๋ถ ๊ตฌ์กฐ > < SW ๊ฒ์ฆ : GPO ๋์ > #include <stdint.h> #define APB_BASE 0x10000000 #define GPO_BASE (APB_BASE + 0x1000) #define GPO_CR *(uint32_t *)(GPO_BASE + 0x00) #define GPO_ODR *(uint32_t *)(GPO_BASE + 0x04) int main() { uint32_t data = 0; GPO_CR = 0xff; while(1) { GPO_ODR = data; data = GPO_ODR; data = data ^ 1; } return 0; } < Simulation > < SW ๊ฒ์ฆ : LED Shift Test > #include <stdint.h> #define APB_BASE 0x10000000 #define GPO_BASE (APB_BASE + 0x1000) #define GPO_CR *(uint32_t *)(GPO_BASE + 0x00) #define GPO_ODR *(uint32_t *)(GPO_BASE + 0x04) void delay(uint32_t t); int main() { uint32_t data = 1; GPO_CR = 0xff; while(1) { GPO_ODR = data; delay(1000); data = (data >> 7) | (data << 1); } return 0; } void delay(uint32_t t) { for (uint32_t i=0; i<t; i++) { for (uint32_t j=0; j<1000; j++); } } GPI Design < SW ๊ฒ์ฆ : LED Switching Test > #include <stdint.h> #define APB_BASE 0x10000000 #define GPO_BASE (APB_BASE + 0x1000) #define GPO_CR *(uint32_t *)(GPO_BASE + 0x00) #define GPO_ODR *(uint32_t *)(GPO_BASE + 0x04) #define GPI_BASE (APB_BASE + 0x2000) #define GPI_CR *(uint32_t *)(GPI_BASE + 0x00) #define GPI_IDR *(uint32_t *)(GPI_BASE + 0x04) //void delay(uint32_t t); int main() { uint32_t data = 0; GPO_CR = 0xff; GPI_CR = 0xff; while(1) { data = GPI_IDR; GPO_ODR = data; //delay(1000); //data = (data >> 7) | (data << 1); } return 0; } /* void delay(uint32_t t) { for (uint32_t i=0; i<t; i++) { for (uint32_t j=0; j<1000; j++); } } */ GPIO Design < ํ์ผ > sources (Class) APB_Master.sv APB_Slave.sv code.mem ControlUnit.sv CPU_RV32I.sv DataPath.sv defines.sv GPI.sv GPIO.sv GPO.sv MCU.sv RAM.sv ROM.sv simulation (Class) apb_tb.sv RV32I_tb.sv constrs (Class) Basys-3-Master.xdc HW : FND_Peripheral Design < SW ๊ฒ์ฆ : FND 0~9999 Counter ๋์ > #include<stdint.h> #define APB_BASE 0x10000000 #define GPO_BASE (APB_BASE + 0x1000) #define GPO_CR *(uint32_t *)(GPO_BASE + 0x00) #define GPO_ODR *(uint32_t *)(GPO_BASE + 0x04) #define GPI_BASE (APB_BASE + 0x2000) #define GPI_CR *(uint32_t *)(GPI_BASE + 0x00) #define GPI_IDR *(uint32_t *)(GPI_BASE + 0x04) #define GPIO_BASE (APB_BASE + 0x3000) #define GPIO_CR *(uint32_t *)(GPIO_BASE + 0x00) #define GPIO_IDR *(uint32_t *)(GPIO_BASE + 0x04) #define GPIO_ODR *(uint32_t *)(GPIO_BASE + 0x08) #define FND_BASE (APB_BASE + 0x4000) #define FND_CR *(uint32_t *)(FND_BASE + 0x00) #define FND_ODR *(uint32_t *)(FND_BASE + 0x04) void delay(uint32_t t); int main() { enum {LEFT, RIGHT}; uint32_t data = 1; uint32_t fnd_count = 0; // FND ์นด์ดํฐ ์ถ๊ฐ GPO_CR = 0xff; GPI_CR = 0xff; GPIO_CR |= 0x0f; GPIO_CR &= ~(0x0f<<4); // FND ์ด๊ธฐํ FND_CR = 0x3FFF; // 14๋นํธ ๋ชจ๋ ํ์ฑํ FND_ODR = fnd_count; // ์ด๊ธฐ๊ฐ 1 ์ค์ uint32_t state = LEFT; while (1) { switch(state) { case LEFT: data = (data >> 7) | (data << 1); if(GPIO_IDR & (1<<5)) state = RIGHT; break; case RIGHT: data = (data << 7) | (data >> 1); if(GPIO_IDR & (1<<6)) state = LEFT; break; } GPO_ODR = data; //data = GPI_IDR; GPIO_ODR = GPIO_IDR >>4; // FND ์นด์ดํฐ ์ ๋ฐ์ดํธ fnd_count++; if(fnd_count > 9999) fnd_count = 1; // 9999 ์ด๊ณผ์ 1๋ก ๋ฆฌ์ FND_ODR = fnd_count; delay(100); } return 0; } void delay(uint32_t t) { for(uint32_t i=0;i<t;i++){ for(uint32_t j=0;j<1000;j++); } } < ํ์ผ > sources (HW) APB_Master.sv APB_Slave.sv code.mem ControlUnit.sv CPU_RV32I.sv DataPath.sv defines.sv FND.sv fndController.sv GPI.sv GPIO.sv GPO.sv MCU.sv RAM.sv ROM.sv constrs (HW) Basys-3-Master.xdc
Final
ยท 2025-08-28
2025-08-27
AMBA APB ์ด๋ก Decoder ๋ฅผ ํตํด SELECT ์ฃผ์๊ฐ L H L ๊ฐ ๋๋ฉด ํ์ ๋นํธ๋ก ์ด๋ค ์๊ฐ ๋ค์ด๊ฐ๋ 8255๊ฐ ์ ํ๋๊ณ ๋๋จธ์ง๋ ์ ํ๋์ง ์์ ์์ 4bit = ์ฃผ์ address 8255 I/O ์ ํ๋ ์ํ์์ ๊ฐ์ฅ ์์ ์ : 0100_0000_0000_0000 = 0x4000 8255 I/O ์ ํ๋ ์ํ์์ ๊ฐ์ฅ ์์ ์ : 0101_1111_1111_1111 = 0x5FFF => 0x4000 ~ 0x5FFF : 8255 I/O ์์ญ => 0x2000 ~ 0x3FFF : RAM ์์ญ => 0x0000 ~ 0x1FFF : ROM ์์ญ => ํ ๋น ๋์ง ์์ ๋ถ๋ถ : reserved ์์ญ, ์ฌ์ฉ๋์ง ์์ 0x5FFF - 0x4000 + 1 = 0x2000 = 8192 8192 / 8 = 1024Byte = ์์ญ๋ณ 1KB ๊ณต๊ฐ์ด ์์ (int *)(0x2500) = 10 => X, ์ข๋ณ์ ์ฃผ์๋ฅผ ์๋ฏธํจ *(int *)(0x2500) = 10 => O, ์ข๋ณ์ ์ฃผ์์ ๊ฐ์ ์๋ฏธํจ => RAM ๋ง ๋์ => ์ดํ ๊ฐ์ด ๋ค๋ฐ๋ผ ๋ค์ด๊ฐ์ 10์ write *(char *)(0x4001) = 0xFF; ๊ฒฐ๊ณผ๋ 0x4001 ์ฃผ์์ ์ ๊ทผ => 8255 ๋ด๋ถ ๋ ์ง์คํฐ ์ค ํ๋์ write (Port B์ ํด๋น) =>Port B์ 0xFF๋ฅผ ์ถ๋ ฅ CPU ์ค์ฌ์ผ๋ก ๋ณด๋ฉด ์ฃผ๋ณ Device๋ Memory๋ก ๋ฐ๋ผ๋ณธ๋ค. (Memory Mapped I/O) APB ๋ฒ์ค๋ ์ฃผ์ยท๋ฐ์ดํฐ๋ฅผ ๋ชจ๋ Slave์๊ฒ broadcast ํ์ง๋ง, Decoder๊ฐ ์ฃผ์๋ฅผ ํด์ํด ํน์ Slave๋ง ์ ํํ๋ค Memory Mapping Chip Select < About the APB protocol > ๋ณต์กํ interface๋ฅผ ์ค์ด๋๋ฐ optimized ๋์ด์์ low-cost : logic ๊ฐฏ์๊ฐ ์ ๊ธฐ ๋๋ฌธ not pipeline (AHB๋ pipeline) synchronous protocol : ๋๊ธฐ protocol every transfer takes at least two cycle to complete : ์ต์ 2 cycle ์ด์ ๊ฑธ๋ฆผ โthe programmable control registers of peripheral devicesโ : CPU๊ฐ ๋ ์ง์คํฐ์ ์ ๊ทผํด์ write/read ํ๋ค = ํด๋น peripheral device๋ฅผ ์ ์ดํ๋ค < Write transfer with no wait states > PADDR : 16bit Addr1 ์ ์ง PWRITE : High ์ ์ง PSEL : High ์ ์ง PENABLE : Low(์ค๋น๋จ๊ณ) -> High PWDATA : 32bit Data1 ์ ์ง PREADY : Low -> High(Prei์์ ์ฒ๋ฆฌํ๋ค๋ ๋ป) => ์ดํ IDLE cpu ์์๋ sel, enable, ready ์ ํธ๋ค์ด ์์ ๊ธฐ์กด cpu : Addr, we, WData, RData + ready, transfer ์ถ๊ฐ Memory Map : 32bit = 4Gbyte AMBA APB Design < Block Diagram > < Simulation > < ํ์ผ > sources (Class) APB_Master.sv APB_Slave.sv code.mem ControlUnit.sv CPU_RV32I.sv DataPath.sv defines.sv MCU.sv RAM.sv ROM.sv simulation (Class) apb_tb.sv HW < Design Specification > APB Slave Interface ๊ตฌ์กฐ์ RAM์ ๋ง๋์์ค Test Bench์์ APB ์ ํธ๋ฅผ ์ ๋ ฅํ์ฌ ์์์ ์ฃผ์์ Read/Write ์๋ฎฌ๋ ์ด์ ํ์์ค < Simulation > < ํ์ผ > sources (HW) APB_Master.sv APB_Slave.sv code.mem ControlUnit.sv CPU_RV32I.sv DataPath.sv defines.sv MCU.sv RAM_Slave.sv RAM.sv ROM.sv simulation (HW) apb_tb.sv
Final
ยท 2025-08-27
2025-08-21
Multi Cycle single cycle ํ๋ฆ PC -(์ฃผ์)-> ROM -(๋ช ๋ น์ด)-> RegFile, ControlUnit(Decoding->SignalOut) -> ALU -> RAM -> Regfile ๊ฐ์ฅ ๊ธด Path์ ๊ฒฝ์ฐ, 1 ํด๋ญ๋์ ALU ์ ๋ ฅ์ ํธ์ ControlUnit ์์ ๋ด๋ณด๋ด๋ ์ ํธ๋ฅผ ๊ฐ์ด ๋ฐ์์ RAM ์ผ๋ก ๊ฐ์ ๋ฉ๋ชจ๋ฆฌ access ํ RAM ์์ ๋์จ ๊ฒฐ๊ณผ๊ฐ RegFile ์ ๋ค์ด๊ฐ. -> ํด๋ญ ๊ธธ์ด๊ฐ ๋๋ฌด ๊ธธ๋ค ์กฐํฉํ๋ก๊ฐ 5๊ฐ ์๋ค๊ณ ๊ฐ์ ํ๊ณ ๊ฐ ํ๋ก๋ง๋ค 10ns ์๊ฐ์ด ๊ฑธ๋ฆฐ๋ค๋ฉด ํด๋ญ์ ์๋ฌด๋ฆฌ ์ค์ฌ๋ ์ต๋ํ 50ns ์ด์ ๋์ด์ผํ๋ค. ์ค๊ฐ์ FF ์ ๋๋ค๊ณ ๊ฐ์ ํ๊ณ ์ด๋ 1ns ์๊ฐ์ด ๊ฑธ๋ฆฐ๋ค๋ฉด ์ ์ฒด๋ฅผ ํต๊ณผํ๋๋ฐ ๊ฑธ๋ฆฌ๋ ์๊ฐ์ด 56ns + a ํ์ Fetch : ๋ช ๋ น์ด๋ฅผ ๋นผ๋ด๋ ๋์ (ROM ์ ์ถ๋ ฅ + PC ์ถ๋ ฅ) Decode : opcode ๋ถ์ (ImmExtend ์ถ๋ ฅ + ControlUnit ์ ์ถ๋ ฅ) Excute : ์คํ, ์ฐ์ฐ (ALU ์ ์ถ๋ ฅ + PC ์ ๋ ฅ๋ถ gate ๋ค๊ณผ mux, Jump ํ๋จ) MemAccess : RAM ์ ๋ ฅ (ALU ์ถ๋ ฅ + RAM ์ ๋ ฅ) WriteBack : RAM ์ถ๋ ฅ (RAM ์ถ๋ ฅ + RegFile ์ ๋ ฅ) R-Type : 34 + a ns S-Type : 45 + a ns L-Type : 56 + a ns => Single Cycle ๋ณด๋ค ํจ์จ์ด ์ฝ๊ฐ ๋ ์ฌ๋ผ๊ฐ ์ฃผ์์ : Fetch ๊ตฌ๊ฐ์์ ๋์๊น์ง ๋ค์ ๋ช ๋ น์ด๊ฐ ๋์ค๋ฉด ์ด๊ฑด Pipeline ๊ตฌ์กฐ, Fetch ๊ตฌ๊ฐ์์ ๋์๊น์ง ๋ค์ ๋ช ๋ น์ด๊ฐ ๋์ค์ง ์์ผ๋ฉด Multi Cycle ๊ตฌ์กฐ ControlUnit ์ ๊ตฌ๊ฐ๋ณ๋ก FSM ํ์ RV32I-V ํด์ฒด ์์ ํ์ Fetch ๊ตฌ๊ฐ : PC๋ฅผ ์ข ๋นผ์ PCEn ์ ํธ ํ์ Decode ๊ตฌ๊ฐ : RegFile ์ถ๋ ฅ, ImmExtend ์ถ๋ ฅ Reg ์ถ๊ฐ Excute ๊ตฌ๊ฐ : ๋ฉ๋ชจ๋ฆฌ Access ํ๊ธฐ ์ , PC๋ก ๊ฐ๊ธฐ ์ Reg ์ถ๊ฐ MemAccess ๊ตฌ๊ฐ : RAM ์ถ๋ ฅ๋ถ๋ถ Reg ์ถ๊ฐ WriteBack ๊ตฌ๊ฐ DataPath ์ฝ๋ฉ RAM ์ถ๋ ฅ ๋ถ๋ถ์ ํ๋ชจ๋(MCU)์์ CPU์ ์ ๋ ฅ์ ํตํด DataPath๋ก ๋ค์ด๊ฐ ControlUnit ์ฝ๋ฉ opcode๋ฅผ ๋ณด๊ณ Type ๊ตฌ๋ณ FSM R-Type : Excute โ Fetch (ALU ๋ช ๋ น ํ RegFile ์ ๋ ฅ ๋๊ธฐ ํ ํด๋ญ์ด ๋ค์ด์ค๋ฉด ๋์ด๊ฐ) I-Type : Excute โ Fetch B-Type : Excute โ Fetch S-Type : Excute โ MemAccess โ Fetch L-Type : Excute โ MemAccess โ WriteBack โ Fetch ํด๋ญ์ ํตํด ์ํ๊ฒ ์ ๋ฐ์ดํธ๋๊ฒ ํด์ผํจ (global signal ์ ์ธ) PPT ๊ฐ ๋ช ๋ น์ด๋ง๋ค ํ ํ์ด์ง๋ก ์ ๋ฆฌ C์ธ์ด๋ฅผ ํตํ ํ ์คํธ์ฝ๋๋ฅผ ๋ง๋ค์ด์ (sort๋ง?) ๋ด CPU ์ ๋๋ค๋ ๊ฒ ์ฆ๋ช ํธ๋ฌ๋ธ์ํ , ๋๋์ (์์ ์) FSM ํ์ ๋ณ๋ก ๋ค ๊ทธ๋ ค์ค์ผ๋จ Multi ์ง๋ฉด์ FSM ์ ํตํด ํ๋ฒ๋ ์ ํธ์ ๋ํ ์ดํดํจ 1.ํ์ง, ์ ๋ชฉ, ๋ฐํ์ ์ด๋ฆ 2.RISC-V ๊ฐ์ 3.๊ฐ๋ฐํ๊ฒฝ, ์ธ์ด, Simulationํ๊ฒฝ 4.๋ช ๋ น Type๋ณ ์ค๋ช -๊ฒ์ฆ๋ด์ฉ(Timing Diagram) 5.Test Program ์ค๋ช (ex:sorting) 6.ํธ๋ฌ๋ธ์ํ 7.๋๋์ -๋ฐฐ์ด์ , ๋ณํ๋์ ์ฒ์์๋ ์คํ ์ด ๊ฒฝ๋ก๋ฅผ ๋ถํธํ์ฅ ํ์ผ๋ ํ์ค์ ์ฐพ์๋ณด๊ณ wdata๋ฅผ ์ํํธํด์ ์ฒ๋ฆฌํจ - ๋๋ค ๋ ๊ฒฝ์ฐ ์ฒ์์๋ ์คํ ์ด ๊ฒฝ๋ก๋ฅผ ๋ถํธํ์ฅ์ ํ ๋ฒ์ ํ์ผ๋ ํ์ค์ ์ฐพ์๋ณด๊ณ wdata๋ฅผ ์ํํธํด์ ์ฒ๋ฆฌํจ ์ด๋ก์ธํด ํด๋ญ๋ฌธ์ ๋ฅผ ํด๊ฒฐ - ์๋ ๊ฒฝ์ฐ
Final
ยท 2025-08-21
2025-08-20
RV32I_All_Type Single_Cycle ์์ฑ RV32I_All_Type Multi_Cycle I-Type path ๊ฐ์ฅ ์ค๋ ๊ฑธ๋ฆผ, ์ฌ๋ฌ ํด๋ญ์ ๋๋ ์ ์ฒ๋ฆฌ ์จ๋ผ์ธ C-Compiler : https://godbolt.org/ ์จ๋ผ์ธ Assembler : https://riscvasm.lucasteske.dev/ RISC-V ๋ช ๋ น์ด ๋ถ์๊ธฐ (Decoder/Encoder) : https://luplab.gitlab.io/rvcodecjs/ ๋์ ๋ฉ๋ชจ๋ฆฌ ํ ๋นํ๋ ์์ญ์ด heap ์์ญ ๋ณ์๋ ํจ์๋ stack ์์ญ์ ํ ๋น ๋ฉ๋ชจ๋ฆฌ์ ๊ฐ์ฅ ๊ผญ๋๊ธฐ๋ stack ์์ญ stack ์์ญ์ ์์์ ์ RAM์ ๊ฐ์ฅ ๊ผญ๋๊ธฐ. RAM ๋ง์ง๋ง์ฃผ์ + 1 C์ธ์ด์ ๋ํ ๋ฉ๋ชจ๋ฆฌ๊ตฌ์กฐ ํ์ ํ์ ra : return address (ํจ์๊ฐ ๋๋๋ฉด ๊ทธ ์์น๋ก ๋์๊ฐ์ผํจ, ๊ทธ ์์น ์ ์ต) s0 ๋ฅผ RAM์ ์ ์ฅ s0์ sp ์์์์น ์ ์ฅ a5 = 10 s0(๊ผญ๋๊ธฐ)๋ฅผ 20 ๋จ์ดํธ๋ ค์ 10(a5 ๊ฐ)์ ์ ์ฅํจ a5 = 20 s0(๊ผญ๋๊ธฐ)๋ฅผ 24 ๋จ์ดํธ๋ ค์ 20(a5 ๊ฐ)์ ์ ์ฅํจ lw : a4์ 10์ ๋ฃ์ด์ค lw : a5์ 20์ ๋ฃ์ด์ค add : a5 = a4 + 15 = 30 30 ๋ฃ์ด์ค li : a5 = 0 a0 = 0 ra = RAM์ ์ ์ฅ๋ ra๊ฐ s0 = RAM์ ์ ์ฅ๋ s0๊ฐ sp ์ด๊ธฐ์์น ra ์์น๋ก ์ ํ HW Memory ๊ณต๊ฐ์ Stack ์์ญ์ ๋ณํ๊ณผ์ ๊ณผ ๋ณ์์ Memory ํ ๋น ๋ฐฉ์ ์ดํด ๋ฐฐ์ด, ํฌ์ธํฐ ๋์ ๋ฐฉ์์ Memory ๊ด์ ์์ ๋ถ์ํ์์ค Memory ๊ทธ๋ฆผ์ ๊ทธ๋ฆฌ๋ฉด์ ๋ถ์ RegisterFile์ Register ํ ๋น ABI name์ ๋ณด๋ฉด์ ํ ๋น ๋ฐฉ์ ์ดํด. ๋ถ์ ์ด์ ๋ธ๋ฆฌ์ด ๋ช ๋ น ํ๋ํ๋ Memory์ RegFile ์ํธ์์ฉ ๋ด์ฉ์ ๊ธ๋ก ์ ์ผ๋ฉด์ ๋ถ์ํ์์ค 
Final
ยท 2025-08-20
2025-08-19
RISC-V I-TYPE Review funct3 ๋ฅผ ํตํด SLTI, SLTIU ๊ตฌ๋ถ ํด์ผํจ SLTI ๊ฒฝ์ฐ ๋ถํธ๋นํธ๋ฅผ ์๊ฐํด์ ๋๋ ค์ค์ผ ํจ shift ๋ ์ ๋ถ unsigned, ๊ทธ๋์ SLTIU ๋ immExtend ์์ ๊ฐ์ด ์ฒ๋ฆฌ /*** immExtend ***/ `OP_TYPE_I: begin case (func3) 3'b001: immExt = {27'b0, instrCode[24:20]}; // SLLI 3'b011: immExt = {20'b0, instrCode[31:20]}; // SRLI, SRAI 3'b101: immExt = {27'b0, instrCode[24:20]}; // SLTIU default:immExt = {{20{instrCode[31]}}, instrCode[31:20]}; endcase end /*** ROM ***/ //rom[x]=32'b imm12 _ rs1 _f3 _ rd _ op // I-Type rom[6] = 32'b000000000001_00001_000_01001_0010011;// addi x9, x1, 1 rom[7] = 32'b000000000100_00010_111_01010_0010011;// andi x10, x2, 4 rom[8] = 32'b000000000001_00010_110_01011_0010011;// ori x11, x2, 1 rom[9] = 32'b000000000011_00001_001_01100_0010011;// slli x12, x1, 1 โ 2b00001000 << 3 = 11 * 2^3 = 88 ์ผ์ชฝ ์ฌํํธ: x ยซย n = x ร 2โฟ ์ค๋ฅธ์ชฝ ์ฌํํธ: xย ยป n = floor(x รท 2โฟ) RISC-V B-TYPE ๋น๊ตํด์ ์ ํํ๊ฒ ๋ค. ๊ฒฐ๊ตญ ๋ช ๋ น์ด์ ์ฃผ์๋ฅผ ๋ฐ๊พธ๊ฒ ๋ค๋ ๋ป. PC์ ๊ฐ์ ๋ฐ๊พธ๋ฉด ๋์ค๋ ๋ช ๋ น์ด๊ฐ ๋ฐ๋ = Branch (C์ธ์ด: if, for, while, switch ๋ฑ) (rs1, rs2๋ก ์ฐ์ฐํ๊ธฐ ์ํด) ALU ์์ ๋น๊ต๊ธฐ ์ฒ๋ฆฌ /*** ControlUnit ***/ `OP_TYPE_B: aluControl = operator; /*** alu ***/ always_comb begin : branch btaken = 1'b0; case (aluControl[2:0]) `BEQ: btaken = (a == b); `BNE: btaken = (a != b); `BLT: btaken = ($signed(a) < $signed(b)); `BGE: btaken = ($signed(a) >= $signed(b)); `BLTU: btaken = (a < b); `BGEU: btaken = (a >= b); endcase end /*** DataPath ***/ logic [3:0] PC_4_AdderResult, PC_Imm_AdderResult, PCSrcMuxOut; logic PCSrcMuxSel; logic btaken; adder U_PC_Imm_Adder ( .a(immExt), .b(PCOutData), .y(PC_Imm_AdderResult) ); adder U_PC_4_Adder ( .a(32'd4), .b(PCOutData), .y(PC_4_AdderResult) ); assign PCSrcMuxSel = btaken & branch; mux_2x1 U_PCSrcMux ( .sel(PCSrcMuxSel), .x0 (PC_4_AdderResult), .x1 (PC_Imm_AdderResult), .y (PCSrcMuxOut) ); ROM[n] : n*4 ์ฉ ์ด๋ ROM[5] ์ฐธ -> rom[8] ์ ํ (20->32) /*** ROM ***/ //rom[x]=32'b imm7 _ rs2 _ rs1 _f3 _ imm5_ op // B-Type rom[5] = 32'b0000000_00010_00010_000_01100_1100011; // beq x2, x2, 12 //rom[x]=32'b imm12 _ rs1 _f3 _ rd _ op // L-Type rom[6] = 32'b000000001000_00000_010_01000_0000011; // lw x8, 8(x0) //rom[x]=32'b imm12 _ rs1 _f3 _ rd _ op // I-Type rom[7] = 32'b000000000001_00001_000_01001_0010011; // addi x9, x1, 1 rom[8] = 32'b000000000100_00010_111_01010_0010011; // andi x10, x2, 4 ROM[5] ๊ฑฐ์ง -> rom[8] (20->24) /*** ROM ***/ //rom[x]=32'b imm7 _ rs2 _ rs1 _f3 _ imm5_ op // B-Type rom[5] = 32'b0000000_00010_00000_000_01100_1100011; // beq x2, x0, 12 //rom[x]=32'b imm12 _ rs1 _f3 _ rd _ op // L-Type rom[6] = 32'b000000001000_00000_010_01000_0000011; // lw x8, 8(x0) ๊ท์น์ฑ Imm์ ๊ณตํต bit๋ฅผ ์ต๋ํ ๋๊ฐ์ ์์น์ ๋ง์ถ๋ค. L, I, S, B, J, JL Type ์์ ์ต๋ํ ๊ฐ์ ์์น์ Imm bit ์์น๋ฅผ ๊ฐ๊ฒ ํ๋ค. H/W ์ต์ ํ์ ๋์์ด ๋๋ค. B, J Type์ ๊ฒฝ์ฐ Imm๊ฐ์ด ROM(PC)์ฃผ์์ offset๊ฐ์ด ๋๋ค. ROM์ ์ฃผ์๋ ํญ์ ์ง์๊ฐ ๋๋ฏ๋ก imm[0]์ ํญ์ โ0โ๊ฐ์ด ๋๋ค. ๊ทธ๋ฌ๋ฏ๋ก B, J Type์์ imm[0]์ด ์์ด ๊ฐ์ ๋ก โ0โ์ ๋ฃ์ด์ค๋ ๋๋ค. ๊ทธ ํจ๊ณผ๋ offset ๋ฒ์๊ฐ์ ๋ํ ์ ์๋ค. ๋ช ๋ น์ด๊ฐ ์ ๋ ฅ๋ ROM์ ์ฃผ์ ํน์ง์ 4์ ๋ฐฐ์์ด๋ค. imm 12bit ๊ณ ์ . ์ต๋๊ฐ ์ฃผ์๋ฒ์๋ฅผ ๋ํ๊ณ ์ถ๋ค. RISC-V LU, AU, J, JL-TYPE C์ธ์ด๋ก if๋ฌธ ํด์ ์ ํ, ์ปดํ์ผ๋ฌ์์ ๋ง๋ค์ด์ค
Final
ยท 2025-08-19
2025-08-18
RISC-V (RV32I Instruction Set) โR-Typeโ RA1 : โRead Address 1โ โ ์ฝ์ ๋ ์ง์คํฐ์ ์ฃผ์(๋ฒํธ). rs1(๋ช ๋ น์ด [19:15])๊ฐ ๋ค์ด๊ฐ. 5๋นํธ. RA2 : โRead Address 2โ โ ์ฝ์ ๋ ์ง์คํฐ์ ์ฃผ์(๋ฒํธ). rs2(๋ช ๋ น์ด [24:20])๊ฐ ๋ค์ด๊ฐ. 5๋นํธ. WA : โWrite Addressโ โ ์ธ ๋ ์ง์คํฐ์ ์ฃผ์(๋ฒํธ). rd(๋ช ๋ น์ด [11:7]). 5๋นํธ. RD1 : โRead Data 1โ โ x[rs1]์์ ์ฝํ ๋์จ ๋ฐ์ดํฐ. ALU ํผ์ฐ์ฐ์ a๋ก ์ฐ๊ฒฐ. RD2 : โRead Data 2โ โ x[rs2]์์ ์ฝํ ๋์จ ๋ฐ์ดํฐ. ALU ํผ์ฐ์ฐ์ b๋ก ์ฐ๊ฒฐ. WD : โWrite Dataโ โ ์ธ ๋ฐ์ดํฐ. R-type์ด๋ฉด ๋ณดํต ALU ๊ฒฐ๊ณผ(aluResult). we : โWrite Enableโ โ ํด๋ก ์์น์ฃ์ง์ we=1์ด๋ฉด x[WA] โ WD๋ก ๊ธฐ๋ก. Instruction Memory(ROM/Flash) : ๋ช ๋ น์ด๋ฅผ ์ ์ฅํ๊ณ PC๊ฐ ์ง์ ํ ์ฃผ์์ ๋ช ๋ น์ด๋ฅผ ์ฝ์ด์ค๋ค. PC(Program Counter) : ํ์ฌ ๋ช ๋ น์ด์ ์ฃผ์๋ฅผ ๋ณด๊ดํ๊ณ ๋ค์ ์ฃผ์(๋ณดํต PC+4 ๋๋ ๋ถ๊ธฐ/์ ํ)๋ฅผ ์ ์ํ๋ค. Control Unit : opcode(+funct3/7)๋ฅผ ํด๋ ํด ALUยท๋ ์ง์คํฐยท๋ฉ๋ชจ๋ฆฌยทPC ์ ์ด ์ ํธ(aluControl ๋ฑ)๋ฅผ ์์ฑํ๋ค. ํจ์จ์ ์ด๊ณ ๋ฒ์ฉ์ ์ธ ๋ช ๋ น์ด๋ฅผ ๋ง๋ค๊ธฐ ์ํด ๊ต์๋๊ณผ ๊ฐ์ด R-Type ์ค๊ณ I_Type๊ณผ ๋์ผํ funtion ๋ถ๋ถ์ด ๋ช ๊ตฐ๋ฐ ๋ณด์ ControlUnit ์์ operator ๊ฐ๊ณผ aluControl ์ ํธ๊ฐ ๋์ผํ๋ฏ๋ก R-Type ์ด๋ฉด aluControl = operator โ 7โb0110011: aluControl = operator; ๊ฐ๋ ์ฑ์ ๋์ด๊ธฐ ์ํด defines.sv ์์ฑ โ `include โdefines.svโ S-Type (Store) ์ค๊ณ, RAM ํ์ R-Type(์ฐ์ /๋ ผ๋ฆฌ): ๋ ์ง์คํฐ๋ผ๋ฆฌ๋ง ์ฐ์ฐํด ๊ฒฐ๊ณผ๋ฅผ ๋ค์ ๋ ์ง์คํฐ์ ์. ์คํ ์ค โ๋ฐ์ดํฐ ๋ฉ๋ชจ๋ฆฌโ๋ฅผ ์ฝ๊ฑฐ๋ ์ฐ์ง ์์. ํ์ํ ๋ฉ๋ชจ๋ฆฌ๋ ๋ช ๋ น์ ์ฝ์ด์ค๋ Instruction Memory(๋ณดํต ROM/Flash)๋ฟ. S-Type(Store): ๋ ์ง์คํฐ ๊ฐ์ ๋ฐ์ดํฐ ๋ฉ๋ชจ๋ฆฌ๋ก ์ ์ฅ(์ฐ๊ธฐ) ํด์ผ ํจ. ์คํ ์ค ๋ด์ฉ์ด ๋ฐ๋์ด์ผ ํ๋ฏ๋ก ์ฐ๊ธฐ ๊ฐ๋ฅํ ๋ฉ๋ชจ๋ฆฌ(RAM)๊ฐ ํ์. S-Type Descript : Memory[์ฃผ์] = Data โ M[rs1+imm] = rs2 (Memory[์ฃผ์]=RAM, imm=์์) imm exted : ๋ถํธ๋นํธ๋ฅผ ์๊ฐํด์ ์ฒ๋ฆฌ, imm=opset ๊ฐ, ํด๋น ์ฃผ์๋ก๋ถํฐ ์ฌ๋ผ๊ฐ(+) ์๋ ์๊ณ ๋ด๋ ค๊ฐ(-) ์๋ ์์, ๋นํธ๋ถํธ ํ์ฅ ํ์, ์ต์์ ๋นํธ๋ฅผ 20๋ฒ copy signals ๋์ด๋จ์ ๋ฐ๋ผ ๋ฌถ์ด์ค. โ {regFileWe, aluSrcMuxSel, busWe} = signals; // [2:0]signals L-Type I-Type
Final
ยท 2025-08-18
2025-08-14
RISC-V Design RISC-V (๋ฆฌ์คํฌ ํ์ด๋ธ) 2010๋ ๋ถํฐ ๋ฏธ๊ตญ UC ๋ฒํด๋ฆฌ์์ ๊ฐ๋ฐ ์ค์ธ ๋ฌด๋ฃ ์คํ ์์ค RISC ๋ช ๋ น์ด์ ์ํคํ ์ฒ Base: RV32I Version: 2.0 1. Single-Cycle Architecture ๋ชจ๋ ๋ช ๋ น์ด๊ฐ 1 clock์ ๋์ ๊ฐ์ฅ ์๊ฐ์ด ์ค๋ ๊ฑธ๋ฆฌ๋ ๋ช ๋ น์ด๋ฅผ ๊ธฐ์ค์ผ๋ก ํด๋ญ ์ฃผ๊ธฐ๋ฅผ ์ค๊ณํด์ผ ํจ ์ฅ์ : ๊ตฌ์กฐ๊ฐ ๋งค์ฐ ๋จ์ํจ ๋จ์ : ์ ์ฒด ์คํ ์๋๊ฐ ๋๋ฆผ 2. Multi-Cycle Architecture ๋ช ๋ น์ด ์ ํ(type)์ ๋ฐ๋ผ ํ์ํ clock ์๊ฐ ๋ค๋ฆ ๋ช ๋ น์ด์ ๋ฐ๋ผ ์คํ ์๊ฐ์ ๋จ์ถํ ์ ์์ ์ฅ์ : Single-Cycle๋ณด๋ค ๋น ๋ฆ ๋จ์ : ๊ตฌ์กฐ๊ฐ ๋ค์ ๋ณต์กํจ ๊ตฌํ ๋ชฉํ โ Single-Cycle๋ก ๋จผ์ ๊ตฌํ ๋ฐ ์ดํด โก Multi-Cycle๋ก ์ ํ + ARMA BUS + ์ฃผ๋ณ์ฅ์น(Peripherals) ์ฐ๋ 3. Pipeline Architecture (ํ์ฌ ๊ตฌํ X) ์ฅ์ : Single-Cycle๋ณด๋ค ํจ์ฌ ๋น ๋ฆ ๋จ์ : ๊ตฌ์กฐ๊ฐ ๋งค์ฐ ๋ณต์กํจ x0 โ zero : ํญ์ 0 ๊ฐ์ ๊ฐ์ง๋ ๋ ์ง์คํฐ x1 โ ra (Return Address) : ํจ์ ํธ์ถ ํ ๋ณต๊ท ์ฃผ์ ์ ์ฅ x2 โ sp (Stack Pointer) : ์คํ์ ์ต์๋จ ์ฃผ์ ์ ์ฅ x3 โ gp (Global Pointer) : ์ ์ญ ๋ณ์ ์ ๊ทผ์ฉ ํฌ์ธํฐ โฆ (์ดํ x31๊น์ง ๊ฐ์ ์ฉ๋ ์ง์ ) โ ์ด์ ๋ธ๋ฆฌ์ด์์๋ x0, x1 ๋์ zero, ra, sp, gp ๋ฑ์ ๋ณ์นญ(alias)์ผ๋ก ํ๊ธฐ๋จ CPU ๊ธฐ๋ณธ ๋ชจ๋ (ํ๋ฒ๋ ๊ตฌ์กฐ) Register File โ CPU ๋ด๋ถ ๋ ์ง์คํฐ ์งํฉ, ์ฐ์ฐ ๋ฐ ๋ฐ์ดํฐ ์์ ์ ์ฅ ALU (Arithmetic Logic Unit) โ ์ฐ์ ๋ฐ ๋ ผ๋ฆฌ ์ฐ์ฐ ์ํ ROM / Flash (Instruction Memory) โ ํ๋ก๊ทธ๋จ ๋ช ๋ น์ด ์ ์ฅ โป ROM์ ํ ๋ฒ ์ฐ๋ฉด ์ง์ธ ์ ์์ผ๋ฏ๋ก, ๋๋ถ๋ถ Flash ๋ฉ๋ชจ๋ฆฌ(๋นํ๋ฐ์ฑ) ์ฌ์ฉ RAM (Data Memory) โ ํ๋ก๊ทธ๋จ ์คํ ์ค ๋ฐ์ดํฐ ์์ ์ ์ฅ (ํ๋ฐ์ฑ) PC (Program Counter) โ ํ์ฌ ์คํ ์ค์ธ ๋ช ๋ น์ด์ ์ฃผ์๋ฅผ ๊ฐ๋ฆฌํค๋ ๋ ์ง์คํฐ Instruction, CPU, RAM ๊น์ง Single-Cycle ๊ตฌํ Peri๋ Multi-Cycle ์ดํ ๊ตฌํ Block Diagram Signal ์ดํด Register Source 1 (5) : 5bit RS1 Register Source 2 (5) : 5bit RS2 Register Destination (5) : 5bit RD Opcode (7) : 7bit type ๊ตฌ๋ถ Funct7 (7) : 7bit ์ฐ์ฐ ๊ตฌ๋ถ Funct3 (3) : 3bit ์ฐ์ฐ ๊ตฌ๋ถ ADD : rd(WAddr) = rs1(RA1) + rs2(RA2) / add : x7(rd), x5(rs1), x6(rs2) = x7 = x5(Data) + x6(Data) < Data Path > < Code : Data Path > `timescale 1ns / 1ps module DataPath ( input logic clk, input logic reset, input logic [31:0] instrCode, input logic regFileWe, input logic [ 1:0] aluControl, output logic [31:0] instrMemAddr ); logic [31:0] aluResult, RFData1, RFData2; logic [31:0] PCSrcData, PCOutData; assign instrMemAddr = PCOutData; RegisterFile U_RegFile ( .clk(clk), .we (regFileWe), .RA1(instrCode[19:15]), .RA2(instrCode[24:20]), .WA (instrCode[11:7]), .WD (aluResult), .RD1(RFData1), .RD2(RFData2) ); alu U_ALU ( .aluControl(aluControl), .a (RFData1), .b (RFData2), .result (aluResult) ); register U_PC ( .clk (clk), .reset(reset), .en (1'b1), .d (PCSrcData), .q (PCOutData) ); adder U_PC_Adder ( .a(32'd4), .b(PCOutData), .y(PCSrcData) ); endmodule module alu ( input logic [ 1:0] aluControl, input logic [31:0] a, input logic [31:0] b, output logic [31:0] result ); always_comb begin result = a + b; case (aluControl) 2'b00: result = a + b; 2'b01: result = a - b; 2'b10: result = a & b; 2'b11: result = a | b; endcase end endmodule module RegisterFile ( input logic clk, input logic we, input logic [ 4:0] RA1, input logic [ 4:0] RA2, input logic [ 4:0] WA, input logic [31:0] WD, output logic [31:0] RD1, output logic [31:0] RD2 ); logic [31:0] mem[0:2**5-1]; always_ff @(posedge clk) begin if (we) mem[WA] <= WD; end assign RD1 = (RA1 != 0) ? mem[RA1] : 32'b0; assign RD2 = (RA2 != 0) ? mem[RA2] : 32'b0; endmodule module register ( input logic clk, input logic reset, input logic en, input logic [31:0] d, output logic [31:0] q ); always_ff @(posedge clk, posedge reset) begin if (reset) begin q <= 0; end else begin if (en) q <= d; end end endmodule module adder ( input logic [31:0] a, input logic [31:0] b, output logic [31:0] y ); assign y = a + b; endmodule < Schematic : DataPath > < Code : Control Unit > `timescale 1ns / 1ps module ControlUnit ( input logic [31:0] instrCode, output logic regFileWe, output logic [ 1:0] aluControl ); // logic ์ ์ ์ธํ๋ฉด์ ์ฐ๊ฒฐ์ด ์๋๊ธฐ ๋๋ฌธ์ wire ์ฌ์ฉ (logic ์ฌ์ฉ์ assign ํ์) wire [6:0] opcode = instrCode[6:0]; wire [3:0] operator = {instrCode[30], instrCode[14:12]}; always_comb begin regFileWe = 1'b0; case (opcode) 7'b0110011: regFileWe = 1'b1; endcase end always_comb begin aluControl = 2'bx; case (opcode) 7'b0110011: begin // R-Type aluControl = 2'bx; case (operator) 4'b0000: aluControl = 2'b00; // add 4'b1000: aluControl = 2'b01; // sub 4'b0111: aluControl = 2'b10; // and 4'b0110: aluControl = 2'b11; // or endcase end endcase end endmodule < Code : CPU_RV32I > `timescale 1ns / 1ps module CPU_RV32I ( input logic clk, input logic reset, input logic [31:0] instrCode, output logic [31:0] instrMemAddr ); logic regFileWe; logic [1:0] aluControl; ControlUnit U_ControlUnit (.*); DataPath U_DataPath (.*); endmodule < Schematic : CPU_RV32I > < Code : ROM > `timescale 1ns / 1ps module ROM ( input logic [31:0] addr, output logic [31:0] data ); logic [31:0] rom[0:61]; initial begin //rom[x]=32'b func7 _ rs2 _ rs1 _f3 _ rd _ op rom[0] = 32'b0000000_00001_00010_000_00100_0110011; // add x4, x2, x1 rom[1] = 32'b0100000_00001_00010_000_00101_0110011; // sub x5, x2, x1 rom[2] = 32'b0000000_00000_00011_111_00110_0110011; // and x6, x3, x0 rom[3] = 32'b0000000_00000_00011_110_00111_0110011; // or x7, x3, x0 end // ํ์ 2bit ๋ฅผ ์์ ๋ฉด 4(2^2)์ ๋ฐฐ์๋ก ํํ์ด ๋จ, 4byte ๋จ์๋ก ์ด๋ ๊ฐ๋ฅ assign data = rom[addr[31:2]]; endmodule < Code : MCU > `timescale 1ns / 1ps module MCU ( input logic clk, input logic reset ); logic [31:0] instrCode; logic [31:0] instrMemAddr; ROM U_ROM ( .addr(instrMemAddr), .data(instrCode) ); CPU_RV32I U_CPU_RV32I (.*); endmodule < Schematic : MCU > < Simulation > < ํ์ผ > sources (Class) MCU.sv ROM.sv CPU_RV32I.sv ControlUnit.sv DataPath.sv sim (Class) RV32I_tb.sv HW < Design Specification > RISC-V RV32I R-Type ๋ช ๋ น์ด ์ค๊ณ < Code : DataPath (alu) > //... module alu ( input logic [ 3:0] aluControl, input logic [31:0] a, input logic [31:0] b, output logic [31:0] result ); always_comb begin result = 32'b0; case (aluControl) 4'b0000: result = a + b; 4'b0001: result = a - b; 4'b0010: result = a << b; 4'b0011: result = a >> b; 4'b0100: result = a >>> b; 4'b0101: result = ($signed(a) < $signed(b)) ? 1 : 0; 4'b0110: result = (a < b) ? 1 : 0; 4'b0111: result = a ^ b; 4'b1000: result = a | b; 4'b1001: result = a & b; endcase end endmodule //... < Code : ControlUnit > `timescale 1ns / 1ps module ControlUnit ( input logic [31:0] instrCode, output logic regFileWe, output logic [ 3:0] aluControl ); // logic ์ ์ ์ธํ๋ฉด์ ์ฐ๊ฒฐ์ด ์๋๊ธฐ ๋๋ฌธ์ wire ์ฌ์ฉ (logic ์ฌ์ฉ์ assign ํ์) wire [6:0] opcode = instrCode[6:0]; wire [3:0] operator = {instrCode[30], instrCode[14:12]}; always_comb begin regFileWe = 1'b0; case (opcode) 7'b0110011: regFileWe = 1'b1; endcase end always_comb begin aluControl = 4'bx; case (opcode) 7'b0110011: begin // R-Type aluControl = 4'bx; case (operator) 4'b0000: aluControl = 4'b0000; // ADD 4'b1000: aluControl = 4'b0001; // SUB 4'b0001: aluControl = 4'b0010; // SLL 4'b0101: aluControl = 4'b0011; // SRL 4'b1101: aluControl = 4'b0100; // SRA 4'b0010: aluControl = 4'b0101; // SLT 4'b0011: aluControl = 4'b0110; // SLTU 4'b0100: aluControl = 4'b0111; // XOR 4'b0110: aluControl = 4'b1000; // OR 4'b0111: aluControl = 4'b1001; // AND endcase end endcase end endmodule < Code : ROM > `timescale 1ns / 1ps module ROM ( input logic [31:0] addr, output logic [31:0] data ); logic [31:0] rom[0:61]; initial begin //rom[x]=32'b func7 _ rs2 _ rs1 _f3 _ rd _ op rom[0] = 32'b0000000_00010_00001_000_00011_0110011; // add x3, x1, x2 rom[1] = 32'b0100000_00010_00001_000_00011_0110011; // sub x3, x1, x2 rom[2] = 32'b0000000_00010_00001_001_00011_0110011; // sll x3, x1, x2 rom[3] = 32'b0000000_00010_00001_101_00011_0110011; // srl x3, x1, x2 rom[4] = 32'b0100000_00010_00001_101_00011_0110011; // sra x3, x1, x2 rom[5] = 32'b0000000_00010_00001_010_00011_0110011; // slt x3, x1, x2 rom[6] = 32'b0000000_00010_00001_011_00011_0110011; // sltu x3, x1, x2 rom[7] = 32'b0000000_00010_00001_100_00011_0110011; // xor x3, x1, x2 rom[8] = 32'b0000000_00010_00001_110_00011_0110011; // or x3, x1, x2 rom[9] = 32'b0000000_00010_00001_111_00011_0110011; // and x3, x1, x2 end // ํ์ 2bit ๋ฅผ ์์ ๋ฉด 4(2^2)์ ๋ฐฐ์๋ก ํํ์ด ๋จ, 4byte ๋จ์๋ก ์ด๋ ๊ฐ๋ฅ assign data = rom[addr[31:2]]; endmodule < Simulation > < ํ์ผ > sources (HW) MCU ROM CPU_RV32I ControlUnit DataPath sim (HW) RV32I_tb
Final
ยท 2025-08-14
2025-08-13
๐ ์ง๋ฌด๋ถ์ ๋ฐฉ๋ฒ ๋ณธ์ธ์ ์ง๋ฌด์ ํ ๊ธฐ์ค๊ณผ ์ ํ ์ง๋ฌด์ ๊ตฌ์ฒด์ ์ญํ ๋ฐ ํ์ ์ญ๋ ํ์ธ ์ง์ ์ง๋ฌด ์ํ์ ํ์ํ ๋ณธ์ธ์ด ์ค๋นํ ์ญ๋ ํ์ ์ง๋ฌด ์ํ์ ์์ด ๊ฐ์ฅ ๋ถ์กฑํ ์ญ๋ ํ์ธ ๋ถ์กฑํ ์ญ๋ ๋ณด์์ ์ํ ๋ ธ๋ ฅ ๊ณํ ๋ฐ ์ ์ฌ ํ ํฌ๋ถ ์์ฑ KSA ๋ถ์ ํด๋น ์ง๋ฌด์ ํ์ํ ์ง์(K), ๊ธฐ์ (S), ํ๋(A) ๊ธฐ์ ์์ฃผ์ ํํ ๊ฒฝํ ๊ธฐ์ฌ ๊ตฌ์กฐ ์์ : ํ๋ ์ผ โ ํ์ํ KSA โ ์์ ์ด ๋ณด์ ํ KSA โ ๊ทผ๊ฑฐ ์ฌ๋ก โ ๋ฏธ๋ณด์ KSA โ ๋ณด์ ๊ณํ ์์ฑ ์ ์์ฌํญ ๊ฒธ์ X / ๊ฐ์ ์ญ๋ O ์ฌ๋ก๋ฅผ ํตํ ์ ์ฆ ํ ๋จ์์ ์ง๋ฌด ๊ด๋ จ ๊ฒฝํ ๊ฐ์กฐ (ํ์๊ณผ์ ๋ถํ ์์์ ๊ฐ์ ์ ์ผ๋ก ์ ๋ฌ) ๐ ๊ตฌ์ฒด์ ์ธ ์ง๋ฌด๋ถ์ ๋ฐฉ๋ฒ 1.๊ณ ์ฉ24 + NCS ์ง์ ์ ๋ณด, ํ๊ฐ๊ธฐ์ค, ์ง๋ฌด๊ธฐ์ ์ ํ์ธ 2.๊ธฐ์ ํํ์ด์ง ์ง๋ฌด์๊ฐ ํ์ด์ง, ํ์ฌ ๊ณต์ ์ ๋ณด 3.๋์์ ์ฑ๋ ํ์ง์ ์ธํฐ๋ทฐ, ์ ๊ณ ๊ทผํฉ 4.์ทจ์ ํฌํธ ์ฌ์ดํธ ์์์ค, ์ฌ๋์ธ(ํ์ง์ ์ธํฐ๋ทฐ, 7~10๋ ์ฐจ ๊ฒฝ๋ ฅ์ ์ญ๋ ์ฐธ๊ณ ), ์ก์ฝ๋ฆฌ์, ์กํ๋๋ 5.์ง๋ฌด ๊ด๋ จ ์ปค๋ฎค๋ํฐ ๋ธ๋ผ์ธ๋, ์ฝ๋ฉํ , ์๋ค 6.๊ธฐํ ์ฐ์ ๊ธฐ์ฌ ์๊ฒฉ์ฆ์ด ์๋ค๋ฉด ์ค์ ๊ธฐ์ฌ์ ๋งค์นญ ํ ๊ฒฌํด ๋ฐ์ ํฌํธํด๋ฆฌ์คยท๋ฉด์ ์ค์์ฑ ์์น ๐ ์ง๋ฌด๋ถ์ ๊ตฌ์กฐ ์์ ๊ธฐ์ ๊ธฐ๋ณธ์ ๋ณด ๋น์ , ๋ฏธ์ , ์ ๋ต ๋น์ ์๋ฆฝ ์ด์ , ์ค์ฒ ์ฌ๋ก ํ์ฌ๊ฐ์, ์ฐฝ์ ์ด๋ , ๊ฒฝ์ํ๋, CEO ์ธ์ฌ๋ง, ์ ๋ ์ฌ, ๊ธฐ์ SNS, ์ฌ๋ณด โ โ๊ทธ ๋ฏธ์ ์ ํจ๊ป ์ํํ๊ธฐ ์ํด ์ง์ํจโ ์ธ์ฌ์ยทํต์ฌ๊ฐ์น ๊ธฐ์ ์ ์ธ์ฌ์ ์ ์ ๋ฐ ์ฌํด์ ํด๋น ์ธ์ฌ์์ด ํ์ํ ์ด์ ์ดํด ์ฌ์ ํํฉ ์์ต ๊ตฌ์กฐ, ์์ดํ , ๋งค์ถยท์์ ์ด์ต ์ถ์ง๊ณผ์ ์ฐ์ ๊ฒฝ์์์ ๊ธฐ์ค ๊ฐ์ ยท์ฝ์ ๋ถ์ ์ฅ๊ธฐ ๋ฐ์ ๊ฐ๋ฅ์ฑ, ์ต์ ์ด์, ์ง์ ์ ๋ณด ์ ๋ ์ฌ์์ ํค์๋ ํ์ฉ Note: ์์์๋ 1ยท2๋ฒ๊น์ง๋ง, ๋ฉด์ ์ 4๊ฐ ์ ๋ถ ์ค๋น ๐ ๊ธฐ์ ๋ถ์ ํ์ ์๋ฃ ๊ธฐ์ ํํ์ด์ง ํ์ฌ์๊ฐ, ์ฐํ, ๊ฒฝ์์ด๋ , ์ธ์ฌ์, ๋น์ ยท๋ฏธ์ , ์ ํยท์๋น์ค, ๋ธ๋๋, ์ฌ๋ด์์ ์ต๊ทผ ๋ณด๋์๋ฃ ์ ๊ท์ฌ์ , ์ค์ ์ฌ์ , ์ ๊ณ ์ด์, ์ ๋ ์ฌ ์ฌ์ ๋ชฉํ DART(์ฌ์ ๋ณด๊ณ ์) ์ฌ์ ๊ท๋ชจ, ์ ๋ต, ์ฌ๋ฌดํํฉ ์ฌ์ ์๊ฐ, ๋ถ๊ธฐ๋ณด๊ณ ์, ์ฌ๋ฌด์ ํ, ๋งค์ถยท์์ด์ตยท์ฆ๊ฐ์จ ํ์ ์ถ๊ฐ ์ฐธ๊ณ ๊ตฌ๊ธ ๊ธฐ์ ์ฌ์ ๋ณด๊ณ ์, IRํ๋ณด์๋ฃ ์ค์๊ธฐ์ : ๊ธฐ์ ๋ก๋๋งต, ํํฉ ์ ๋ณด์์คํ , ๋์ด์ค ๊ธฐ์ ์ ๋ณด, ํ๊ตญ๊ธฐ์ ํ๊ฐ ๐ ์ฐ์ ๋ถ์ ์ฃผ์ ์ฐ์ ๊ณผ ์ด์์ ๋งฅ๋ฝ ํ์ ๊ณต๊ธฐ์ ์ฐธ๊ณ ์ฌ์ดํธ: ALIO, ๋๋ฒ ์ดํ ๋ฐ์ด, ์กํ๋๋ (์๊ธฐ ๊ธฐ์ค ์ค์ ), DBR ๐ ์ ์ฌ์ง์์ ์์ฑ ํฌ์ธํธ ์ง๋ฌด ๊ฒฝํ๊ณผ KSA ๋ถ์ ๋ฐ์ ํ์ฌ ๋ง์ถคํ ์คํ ๋ฆฌ ์ ๋งคํ ์ด๋ ฅ์ โ ์๋ฅ ํ๋ฝ ์ํ ํฌํธํด๋ฆฌ์ค: ๊ทธ๋ฆผ ์์ฃผ, ๊ฐ๊ฒฐํ๊ฒ ์์ฑ ์ ์ ๊ฒ์ฌํญ ํ์๋ถ์ ์ฌ๋ถ ๊ฐ์ /๊ฒฝํ ์ ๋ฆฌ ์ง๋ฌด์ ํฉ์ฑ(์ 3์ ๊ด์ ๊ฒํ ) ์ง๋์น ๊ฒธ์ X / ์ ์ ํ ์ดํ O ๋จ์ ๋ถํ์ ๋ ธ์ถ ๐ ์ด๋ ฅ์ ํ(KDT) ์ฃผ์: ๋๋ก๋ช ๊น์ง๋ง ํ๋ ฅ: ์ต๊ทผ ์กธ์ 2๊ฐ๋ง ์๊ฒฉ์ฌํญ: ์ค์๋ ์ ๊ธฐ์ฌ ๐ ์์์ ์์ฑ ํ๋ฆ ์ง๋ฌด ํ์ ํ์ํ ์ญ๋ ๋ถ์ ํด๋น ์ญ๋ ์ ๋ฆฌ ๊ฒฝํ ์ฌ๋ก ์ ๋ฆฌ ํญ๋ชฉ๋ณ ๋ฐฐ์น KSA ์ฐ์ ์์ ๊ณ ๋ ค ์์ฑ ์๋ น ์ธ์ฌ๋ด๋น์ ๊ด์ ๊ฐ๊ดํยท์์นํ ๋๊ด์ โ ๊ฒฐ๋ก (๊ฐ์ ) โ ๋ณธ๋ก (STAR) โ ๊ฒฐ๋ก ๐ ์์์ ๊ธฐ๋ณธ ๊ตฌ์ฑ ์ฑ์ฅ๊ณผ์ : ์ง๋ฌด์ ๋ง๋ ์ฑํฅ ์ฑ๊ฒฉ์๊ฐ: ๊ฐ์ + ๋ณด์ ๋ ธ๋ ฅ ์ง๋ฌด๊ฒฝํ: ์ญํ , ์ญ๋ ํฅ์, ๋ฐฐ์ด ์ ์ง์๋๊ธฐยทํฌ๋ถ: ์ฐ์ ํน์ฑยท์ด์, ํ์ฌ ๋ฐฉํฅ, ์ง๋ฌด ํ์์ฑ, ์ ํฉ์ฑ, ํฅํ ๊ณํ
Final
ยท 2025-08-13
2025-08-12
Dedicated Processor Sum Counter Design < C์ธ์ด > i = 0; sum = 0; while (i <= 10) { sum = sum + i i = i + 1; outport = sum; } halt; < Design Specification > i ์ ์ฅ โ Register 1๊ฐ sum ์ ์ฅํ โ Register 1๊ฐ ์ถ๋ ฅ์ ์ ์ฅํ โ Register 1๊ฒ while ๋ฌธ โ Comparator ๋ง์ ์ฐ์ฐ โ Adder < Data Path > < ASM > < Code : DataPath > `timescale 1ns / 1ps module DataPath ( input logic clk, input logic reset, input logic SumSrcMuxSel, input logic ISrcMuxSel, input logic SumEn, input logic IEn, input logic AdderSrcMuxSel, input logic OutPortEn, output logic ILe10, output logic [7:0] OutPort ); logic [7:0] SumSrcMuxOut, ISrcMuxOut; logic [7:0] SumRegOut, IRegOut; logic [7:0] AdderResult, AdderSrcMuxOut; Mux_2x1 U_SumSrcMux ( .sel(SumSrcMuxSel), .x0 (0), .x1 (AdderResult), .y (SumSrcMuxOut) ); Mux_2x1 U_ISrcMux ( .sel(ISrcMuxSel), .x0 (0), .x1 (AdderResult), .y (ISrcMuxOut) ); Register U_SumReg ( .clk (clk), .reset(reset), .en (SumEn), .d (SumSrcMuxOut), .q (SumRegOut) ); Register U_IReg ( .clk (clk), .reset(reset), .en (IEn), .d (ISrcMuxOut), .q (IRegOut) ); Comparator U_ILe10 ( .a (IRegOut), .b (10), .lt(ILe10) ); Mux_2x1 U_AdderSrcMux ( .sel(AdderSrcMuxSel), .x0 (SumRegOut), .x1 (1), .y (AdderSrcMuxOut) ); Adder U_Adder ( .a (AdderSrcMuxOut), .b (IRegOut), .sum(AdderResult) ); Register U_OutPort ( .clk (clk), .reset(reset), .en (OutPortEn), .d (SumRegOut), .q (OutPort) ); endmodule module Register ( input logic clk, input logic reset, input logic en, input logic [7:0] d, output logic [7:0] q ); always_ff @(posedge clk, posedge reset) begin if (reset) begin q <= 0; end else begin if (en) begin q <= d; end end end endmodule module Mux_2x1 ( input logic sel, input logic [7:0] x0, input logic [7:0] x1, output logic [7:0] y ); always_comb begin y = 8'b0; case (sel) 1'b0: y = x0; 1'b1: y = x1; endcase end endmodule module Adder ( input logic [7:0] a, input logic [7:0] b, output logic [7:0] sum ); assign sum = a + b; endmodule module Comparator ( input logic [7:0] a, input logic [7:0] b, output logic lt ); assign lt = a < b; endmodule module OutBuf ( input logic en, input logic [7:0] x, output logic [7:0] y ); assign y = en ? x : 8'bx; endmodule < Schematic > < Code : ControlUnit > `timescale 1ns / 1ps module ControlUnit ( input logic clk, input logic reset, input logic ILe10, output logic SumSrcMuxSel, output logic ISrcMuxSel, output logic SumEn, output logic IEn, output logic AdderSrcMuxSel, output logic OutPortEn ); typedef enum { S0, S1, S2, S3, S4, S5 } state_e; state_e state, next_state; always_ff @(posedge clk, posedge reset) begin if (reset) begin state <= S0; end else begin state <= next_state; end end always_comb begin next_state = state; SumSrcMuxSel = 0; ISrcMuxSel = 0; SumEn = 0; IEn = 0; AdderSrcMuxSel = 0; OutPortEn = 0; case (state) S0: begin // i = 0, sum = 0 SumSrcMuxSel = 0; ISrcMuxSel = 0; SumEn = 1; IEn = 1; AdderSrcMuxSel = 0; // X OutPortEn = 0; next_state = S1; end S1: begin // iLe10 SumSrcMuxSel = 0; ISrcMuxSel = 0; SumEn = 0; IEn = 0; AdderSrcMuxSel = 0; OutPortEn = 0; if (ILe10) next_state = S2; else next_state = S5; end S2: begin // sum = sum + i SumSrcMuxSel = 1; ISrcMuxSel = 1; SumEn = 1; IEn = 0; AdderSrcMuxSel = 0; OutPortEn = 0; next_state = S3; end S3: begin // i = i + 1 SumSrcMuxSel = 1; ISrcMuxSel = 1; SumEn = 0; IEn = 1; AdderSrcMuxSel = 1; OutPortEn = 0; next_state = S4; end S4: begin // OutPort = sum SumSrcMuxSel = 1; ISrcMuxSel = 1; SumEn = 0; IEn = 0; AdderSrcMuxSel = 0; OutPortEn = 1; next_state = S1; end S5: begin // halt SumSrcMuxSel = 1; ISrcMuxSel = 1; SumEn = 0; IEn = 0; AdderSrcMuxSel = 0; OutPortEn = 0; next_state = S5; end endcase end endmodule < Code : DedicatedProcessor > `timescale 1ns / 1ps module DedicatedProcessor ( input logic clk, input logic reset, output logic [7:0] OutPort ); logic SumSrcMuxSel; logic ISrcMuxSel; logic SumEn; logic IEn; logic AdderSrcMuxSel; logic OutPortEn; logic ILe10; DataPath U_DataPath (.*); ControlUnit U_ControlUnit (.*); endmodule < Comment > IReg์ SumReg ๋ ๊ฐ์ ๋ ์ง์คํฐ๋ก ๊ฐ๊ฐ i ๊ฐ๊ณผ ๋์ ํฉ(sum)์ ์ ์ฅํ๋ค. OutPort ๋ ์ง์คํฐ๋ ์ต์ข ์ถ๋ ฅ๊ฐ์ ํด๋ญ ๊ฒฝ๊ณ์์ ์์ ์ ์ผ๋ก ๋ด๋ณด๋ธ๋ค. ๊ฐ ์ฐ์ฐ์ ํ์ํ ํผ์ฐ์ฐ์ ์ ํ์ MUX๋ฅผ ํตํด ์ด๋ฃจ์ด์ง๋ฉฐ, ํ๋์ Adder๋ฅผ ๊ณต์ ํ๋ค. Comparator(ILe10)๋ i โค 10 ์กฐ๊ฑด์ ํ๋์จ์ด ์ ํธ๋ก ๋ณํํด Control Unit์ด ๋ฃจํ ์ข ๋ฃ๋ฅผ ํ๋จํ๋๋ก ํ๋ค. < ๊ณ ์ฐฐ > ํ๋์ Adder๋ก ๋ ์ฐ์ฐ์ ๋ฒ๊ฐ์ ์ฒ๋ฆฌํ๋ฏ๋ก ํ๋์จ์ด ์์ ์ ์ฝ MUX์ Enable ์ ํธ๋ก ๋์ ํ์ด๋ฐ๊ณผ ๋ฐ์ดํฐ ๊ฒฝ๋ก๋ฅผ ์์ ํ ์ ์ด ๊ฐ๋ฅ < Simulation > < Code : top > `timescale 1ns / 1ps module top ( input logic clk, input logic reset, output logic [3:0] fndCom, output logic [7:0] fndFont ); logic clk_10hz; logic [7:0] OutPort; clk_div_10hz U_ClkDiv ( .clk (clk), .reset (reset), .clk_10hz(clk_10hz) ); DedicatedProcessor U_DedicatedProcessor ( .clk (clk_10hz), .reset (reset), .OutPort(OutPort) ); fndController U_FndController ( .clk (clk), .reset (reset), .number ({6'b0, OutPort}), .fndCom (fndCom), .fndFont(fndFont) ); endmodule module clk_div_10hz ( input logic clk, input logic reset, output logic clk_10hz ); //logic [23:0] div_counter; logic [$clog2(10_000_000)-1:0] div_counter; always_ff @(posedge clk, posedge reset) begin if (reset) begin div_counter <= 0; clk_10hz <= 1'b0; end else begin if (div_counter == 10_000_000 - 1) begin div_counter <= 0; clk_10hz <= 1'b1; end else begin div_counter <= div_counter + 1; clk_10hz <= 1'b0; end end end endmodule < Schematic > < ํ์ผ > sources (Class) top.sv DedicatedProcessor.sv DataPath.sv ControlUnit.sv fndController.sv simulation (Class) DedicatedProcessor_tb.sv constrs (Class) Basys-3-Master.xdc Register File Design < Design Specification > ๋ฐ์ดํฐ ์ถ๋ ฅ: 2๊ฐ์ Read Port(RD1, RD2)๋ฅผ ํตํด ALU๋ก ๋ฐ์ดํฐ ์ ๋ฌ ์ฃผ์ ์ง์ : ๊ฐ Read Port๋ ๋ณ๋์ Read Address ์ ๋ ฅ์ ๊ฐ์ง ์: RD1 ์ฃผ์ ์ ๋ ฅ์ 0์ ์ฃผ๋ฉด, ๋ ์ง์คํฐ 0๋ฒ ๋ฐ์ดํฐ ์ถ๋ ฅ RD2 ์ฃผ์ ์ ๋ ฅ์ 2๋ฅผ ์ฃผ๋ฉด, ๋ ์ง์คํฐ 2๋ฒ ๋ฐ์ดํฐ ์ถ๋ ฅ ๋ฐ์ดํฐ ์ฐ๊ธฐ: Write Address ์ ๋ ฅ์ ์ ์ฅํ ๋ ์ง์คํฐ ๋ฒํธ ์ง์ write_en ์ ํธ๋ฅผ 1๋ก ํ๊ณ ํด๋ญ ์ฃ์ง์ ๋ง์ถฐ ๋ฐ์ดํฐ ์ ์ฅ ์: Write Address = 3, write_en = 1 โ ๋ ์ง์คํฐ 3๋ฒ์ ๋ฐ์ดํฐ ์ ์ฅ ์ถ๋ ฅ ํน์ฑ: ๋ณ๋์ read_enable ์์ด, ์ฃผ์๊ฐ ์ ํจํ๋ฉด ํญ์ ํด๋น ๋ฐ์ดํฐ ์ถ๋ ฅ ์ฃผ์ ๋ณ๊ฒฝ ์ ์ฆ์ ํด๋น ๋ ์ง์คํฐ ๊ฐ ์ถ๋ ฅ < C์ธ์ด > R1 = 0; // i R2 = 0; // sum R3 = 1; while (R1 <= 10) { R2 = R2 + R1 R1 = R1 + R3; outport = R2; } halt; < Data Path > < Code : DataPath > `timescale 1ns / 1ps module DataPath ( input logic clk, input logic reset, input logic RFSrcMuxSel, input logic [2:0] RAddr1, input logic [2:0] RAddr2, input logic [2:0] WAddr, input logic we, input logic OutPortEn, output logic R1Le10, output logic [7:0] OutPort ); logic [7:0] AddrResult, RFSrcMuxOut; logic [7:0] RData1, RData2; Mux_2x1 U_RFSrcMux ( .sel(RFSrcMuxSel), .x0 (AddrResult), .x1 (8'b1), .y (RFSrcMuxOut) ); RegFile U_RegFile ( .clk (clk), .RAddr1(RAddr1), .RAddr2(RAddr2), .WAddr (WAddr), .we (we), .Wdata (RFSrcMuxOut), .RData1(RData1), .RData2(RData2) ); Comparator U_R1Le10 ( .a (RData1), .b (8'd10), .lte(R1Le10) ); Adder U_Adder ( .a (RData1), .b (RData2), .sum(AddrResult) ); Register U_Register ( .clk (clk), .reset(reset), .en (OutPortEn), .d (RData1), .q (OutPort) ); endmodule module RegFile ( input logic clk, input logic [2:0] RAddr1, input logic [2:0] RAddr2, input logic [2:0] WAddr, input logic we, input logic [7:0] Wdata, output logic [7:0] RData1, output logic [7:0] RData2 ); logic [7:0] mem[0:2**3-1]; // [0:2**(Number of addresses)-1] always_ff @(posedge clk) begin if (we) begin mem[WAddr] <= Wdata; end end assign RData1 = (RAddr1 == 0) ? 8'b0 : mem[RAddr1]; assign RData2 = (RAddr2 == 0) ? 8'b0 : mem[RAddr2]; endmodule module Register ( input logic clk, input logic reset, input logic en, input logic [7:0] d, output logic [7:0] q ); always_ff @(posedge clk, posedge reset) begin if (reset) begin q <= 0; end else begin if (en) begin q <= d; end end end endmodule module Mux_2x1 ( input logic sel, input logic [7:0] x0, input logic [7:0] x1, output logic [7:0] y ); always_comb begin y = 8'b0; case (sel) 1'b0: y = x0; 1'b1: y = x1; endcase end endmodule module Adder ( input logic [7:0] a, input logic [7:0] b, output logic [7:0] sum ); assign sum = a + b; endmodule module Comparator ( input logic [7:0] a, input logic [7:0] b, output logic lte ); assign lte = a <= b; endmodule < Schematic > Homework_1 < Design Specification > Register File ์ Data Path ์ด์ด์ ControlUnit, DedicatedProcessor ์ค๊ณ ๋์: RegisterFile ์ ์ด์ฉํ์ฌ 0 ~ 10 ๋์ ํฉ์ fnd์ ์ถ๋ ฅ < ASM > < Code : ControlUnit > `timescale 1ns / 1ps module ControlUnit ( input logic clk, input logic reset, input logic R1Le10, output logic RFSrcMuxSel, output logic [2:0] RAddr1, output logic [2:0] RAddr2, output logic [2:0] WAddr, output logic we, output logic OutPortEn ); typedef enum { S0, S1, S2, S3, S4, S5, S6, S7 } state_e; state_e state, next_state; always_ff @(posedge clk, posedge reset) begin if (reset) begin state <= S0; end else begin state <= next_state; end end always_comb begin next_state = state; RFSrcMuxSel = 0; RAddr1 = 0; RAddr2 = 0; WAddr = 0; we = 0; OutPortEn = 0; case (state) S0: begin RFSrcMuxSel = 0; RAddr1 = 4'd0; RAddr2 = 4'd0; WAddr = 4'd1; we = 1; OutPortEn = 0; next_state = S1; end S1: begin RFSrcMuxSel = 0; RAddr1 = 4'd0; RAddr2 = 4'd0; WAddr = 4'd2; we = 1; OutPortEn = 0; next_state = S2; end S2: begin RFSrcMuxSel = 1; RAddr1 = 4'd0; RAddr2 = 4'd0; WAddr = 4'd3; we = 1; OutPortEn = 0; next_state = S3; end S3: begin RFSrcMuxSel = 0; RAddr1 = 4'd1; RAddr2 = 4'd0; WAddr = 4'd0; we = 0; OutPortEn = 0; if (R1Le10) next_state = S4; else next_state = S7; end S4: begin RFSrcMuxSel = 0; RAddr1 = 4'd1; RAddr2 = 4'd2; WAddr = 4'd2; we = 1; OutPortEn = 0; next_state = S5; end S5: begin RFSrcMuxSel = 0; RAddr1 = 4'd1; RAddr2 = 4'd3; WAddr = 4'd1; we = 1; OutPortEn = 0; next_state = S6; end S6: begin RFSrcMuxSel = 0; RAddr1 = 4'd2; RAddr2 = 4'd0; WAddr = 4'd0; we = 0; OutPortEn = 1; next_state = S3; end S7: begin RFSrcMuxSel = 0; RAddr1 = 4'd0; RAddr2 = 4'd0; WAddr = 4'd0; we = 0; OutPortEn = 0; next_state = S7; end endcase end endmodule < Code : DedicatedProcessor > `timescale 1ns / 1ps module DedicatedProcessor ( input logic clk, input logic reset, output logic [7:0] OutPort ); logic RFSrcMuxSel; logic [2:0] RAddr1; logic [2:0] RAddr2; logic [2:0] WAddr; logic we; logic OutPortEn; logic R1Le10; DataPath U_DataPath (.*); ControlUnit U_ControlUnit (.*); endmodule < Commnet > RegFile์ i, sum, (ํ์ ์) ์์ ๋ ์ง์คํฐ๋ฅผ ๋ฐฐ์นํ๊ณ , RAddr1/2๋ก ๋ ํผ์ฐ์ฐ์๋ฅผ ์ ํ, WAddr๋ก ์ฐ์ฐ ๊ฒฐ๊ณผ์ ๋ชฉ์ ์ง๋ฅผ ์ง์ ํ๋ค. RFSrcMux๋ ์ฐ์ฐ ๊ฒฐ๊ณผ(AddrResult) ๋๋ ์ฆ์น๊ฐ 1 ์ค ํ๋๋ฅผ Wdata๋ก ์ ํํด ์ด๊ธฐํ/์ฆ๊ฐ๋ฅผ ๋ชจ๋ ํ๋์ Adder๋ก ์ฒ๋ฆฌํ ์ ์๊ฒ ํ๋ค. OutPort๋ RData1์ ์ํ/ํ๋ํ์ฌ ์ธ๋ถ๋ก ์์ ์ ์ผ๋ก ์ถ๋ ฅํ๋ค(Enable๋ก ์ถ๋ ฅ ํ์ด๋ฐ ์ ์ด). < ๊ณ ์ฐฐ > ์ ์ฐ์ฑ: ์ฃผ์๋ง ๋ฐ๊ฟ i, sum, ์์ ๋ฑ ๋ค์ํ ์กฐํฉ์ ๊ฐ์ ํ๋์จ์ด๋ก ์ฒ๋ฆฌ ์์ ๊ณต์ : Adder 1๊ฐ๋ก ์ฆ๊ฐ์ ๋์ ์ ๋ชจ๋ ์ํ โ ๋ฉด์ ์ ์ฝ ๊ฐ๋ ์ฑ/ํ์ฅ์ฑ: ์์ 0์ ์ฃผ์ 0๋ก, ์์ 1์ ํ ๋ฒ ๊ธฐ๋ก ํ ์ฌ์ฌ์ฉํ๋ ํจํด์ผ๋ก ์ปจํธ๋กค์ด ๋จ์ < Video > < ํ์ผ > sources (Homework) top.sv ControlUnit.sv DataPath.sv DedicatedProcessor.sv fndController.sv constrs (Homework) Basys-3-Master.xdc Homework_2 < Design Specification > ALU๋ฅผ ๋ง๋ค์ด DedicatedProcessor ์ค๊ณ R1 = 1, R2 = 0, R3 = 0, R4 = 0 R2 = R1 + R1 R3 = R2 + R1 R4 = R3 - R1 R1 = R1 | R2 R4 < R2; // Yes: R4 = R3 - R1; // No: R4 = R4 & R3; R4 = R4 & R3 R4 = R2 + R3 R2 < R4 // Yes: R2 = R1 + R1; // No: hlat hlat < Data Path > < ASM > < Code : ControlUnit > `timescale 1ns / 1ps module ControlUnit ( input logic clk, input logic reset, input logic lte, output logic RFSrcMuxSel, output logic [2:0] RAddr1, output logic [2:0] RAddr2, output logic [2:0] WAddr, output logic we, output logic OutPortEn, output logic [1:0] ALUop ); typedef enum { S0, S1, S2, S3, S4, S5, S6, S7, S8, S9, S10, S11, S12, S13 } state_e; state_e state, next_state; always_ff @(posedge clk, posedge reset) begin if (reset) begin state <= S0; end else begin state <= next_state; end end always_comb begin next_state = state; RFSrcMuxSel = 0; RAddr1 = 4'd0; RAddr2 = 4'd0; WAddr = 4'd0; we = 0; OutPortEn = 0; ALUop = 4'd0; case (state) S0: begin // R1 = 1 RFSrcMuxSel = 1; RAddr1 = 4'd0; RAddr2 = 4'd0; WAddr = 4'd1; we = 1; OutPortEn = 0; ALUop = 4'd0; next_state = S1; end S1: begin // R2 = 0 RFSrcMuxSel = 0; RAddr1 = 4'd0; RAddr2 = 4'd0; WAddr = 4'd2; we = 1; OutPortEn = 0; ALUop = 4'd0; next_state = S2; end S2: begin // R3 = 0 RFSrcMuxSel = 0; RAddr1 = 4'd0; RAddr2 = 4'd0; WAddr = 4'd3; we = 1; OutPortEn = 0; ALUop = 4'd0; next_state = S3; end S3: begin // R4 = 0 RFSrcMuxSel = 0; RAddr1 = 4'd0; RAddr2 = 4'd0; WAddr = 4'd4; we = 1; OutPortEn = 0; ALUop = 4'd0; next_state = S4; end S4: begin // R2 = R1 + R1 RFSrcMuxSel = 0; RAddr1 = 4'd1; RAddr2 = 4'd1; WAddr = 4'd2; we = 1; OutPortEn = 0; ALUop = 4'd0; next_state = S5; end S5: begin // R3 = R2 + R1 RFSrcMuxSel = 0; RAddr1 = 4'd2; RAddr2 = 4'd1; WAddr = 4'd3; we = 1; OutPortEn = 0; ALUop = 4'd0; next_state = S6; end S6: begin // R4 = R3 = R1 RFSrcMuxSel = 0; RAddr1 = 4'd3; RAddr2 = 4'd1; WAddr = 4'd4; we = 1; OutPortEn = 0; ALUop = 4'd1; next_state = S7; end S7: begin // R1 = R1 | R2 RFSrcMuxSel = 0; RAddr1 = 4'd1; RAddr2 = 4'd2; WAddr = 4'd1; we = 1; OutPortEn = 0; ALUop = 4'd3; next_state = S8; end S8: begin // R4 < R2 RFSrcMuxSel = 0; RAddr1 = 4'd4; RAddr2 = 4'd2; WAddr = 4'd0; we = 0; OutPortEn = 0; ALUop = 4'd0; if (lte) next_state = S5; else next_state = S9; end S9: begin // R4 = R4 & R3 RFSrcMuxSel = 0; RAddr1 = 4'd4; RAddr2 = 4'd3; WAddr = 4'd4; we = 1; OutPortEn = 0; ALUop = 4'd2; next_state = S10; end S10: begin // R4 = R2 + R3 RFSrcMuxSel = 0; RAddr1 = 4'd2; RAddr2 = 4'd3; WAddr = 4'd4; we = 1; OutPortEn = 0; ALUop = 4'd0; next_state = S11; end S11: begin // OutProt = R4 RFSrcMuxSel = 0; RAddr1 = 4'd4; RAddr2 = 4'd0; WAddr = 4'd0; we = 0; OutPortEn = 1; ALUop = 4'd0; next_state = S12; end S12: begin // R2 < R4 RFSrcMuxSel = 0; RAddr1 = 4'd2; RAddr2 = 4'd4; WAddr = 4'd0; we = 0; OutPortEn = 0; ALUop = 4'd0; if (lte) next_state = S4; else next_state = S13; end S13: begin // half RFSrcMuxSel = 0; RAddr1 = 4'd0; RAddr2 = 4'd0; WAddr = 4'd0; we = 0; OutPortEn = 0; ALUop = 4'd0; next_state = S13; end endcase end endmodule < Code : Data Path > //... module ALU ( input logic [1:0] sel, input logic [7:0] a, input logic [7:0] b, output logic [7:0] alu_result ); always_comb begin alu_result = a + b; case (sel) 2'd0: alu_result = a + b; 2'd1: alu_result = a - b; 2'd2: alu_result = a & b; 2'd3: alu_result = a | b; endcase end endmodule //... < Schematic > < Comment > ๋ฐ๋ณต๋ณ ๋ ์ง์คํฐ ๊ฐ 1ํ: R1=3, R2=2, R3=3, R4=5 โ Yes 2ํ: R1=7, R2=6, R3=9, R4=15 โ Yes 3ํ: R1=15, R2=14, R3=21, R4=35 โ Yes 4ํ: R1=31, R2=30, R3=45, R4=75 โ Yes 5ํ: R1=63, R2=62, R3=93, R4=155 โ Yes 6ํ: R1=127, R2=126, R3=189, R4=59 โ No โ halt ์ฒซ ๋ฒ์งธ ๋ฐ๋ณต ์์ ๊ฐ: (R1, R2, R3, R4) = (1, 0, 0, 0) ๊ณ์ฐ ์์: R2 = R1 + R1 (1 + 1 = 2) โ (1, 2, 0, 0) R3 = R2 + R1 (2 + 1 = 3) โ (1, 2, 3, 0) R4 = R3 - R1 (3 - 1 = 2) โ (1, 2, 3, 2) R1 = R1 | R2 (1 | 2 = 3) โ (3, 2, 3, 2) R4 = R4 & R3 (2 & 3 = 2) โ (3, 2, 3, 2) R4 = R2 + R3 (2 + 3 = 5) โ (3, 2, 3, 5) ์กฐ๊ฑด ํ์ธ: R4 > R2 (5 > 2) โ Yes, ๊ณ์ ์งํ ๋ ๋ฒ์งธ ๋ฐ๋ณต ์์ ๊ฐ: (R1, R2, R3, R4) = (3, 2, 3, 5) ๊ณ์ฐ ์์: R2 = R1 + R1 (3 + 3 = 6) โ (3, 6, 3, 5) R3 = R2 + R1 (6 + 3 = 9) โ (3, 6, 9, 5) R4 = R3 - R1 (9 - 3 = 6) โ (3, 6, 9, 6) R1 = R1 | R2 (3 | 6 = 7) โ (7, 6, 9, 6) R4 = R4 & R3 (6 & 9 = 0) โ (7, 6, 9, 0) R4 = R2 + R3 (6 + 9 = 15) โ (7, 6, 9, 15) ์กฐ๊ฑด ํ์ธ: R4 > R2 (15 > 6) โ Yes, ๊ณ์ ์งํ ์ธ ๋ฒ์งธ ๋ฐ๋ณต ์์ ๊ฐ: (R1, R2, R3, R4) = (7, 6, 9, 15) ๊ณ์ฐ ์์: R2 = R1 + R1 (7 + 7 = 14) โ (7, 14, 9, 15) R3 = R2 + R1 (14 + 7 = 21) โ (7, 14, 21, 15) R4 = R3 - R1 (21 - 7 = 14) โ (7, 14, 21, 14) R1 = R1 | R2 (7 | 14 = 15) โ (15, 14, 21, 14) R4 = R4 & R3 (14 & 21 = 4) โ (15, 14, 21, 4) R4 = R2 + R3 (14 + 21 = 35) โ (15, 14, 21, 35) ์กฐ๊ฑด ํ์ธ: R4 > R2 (35 > 14) โ Yes, ๊ณ์ ์งํ ๋ค ๋ฒ์งธ ๋ฐ๋ณต ์์ ๊ฐ: (R1, R2, R3, R4) = (15, 14, 21, 35) ๊ณ์ฐ ์์: R2 = R1 + R1 (15 + 15 = 30) โ (15, 30, 21, 35) R3 = R2 + R1 (30 + 15 = 45) โ (15, 30, 45, 35) R4 = R3 - R1 (45 - 15 = 30) โ (15, 30, 45, 30) R1 = R1 | R2 (15 | 30 = 31) โ (31, 30, 45, 30) R4 = R4 & R3 (30 & 45 = 12) โ (31, 30, 45, 12) R4 = R2 + R3 (30 + 45 = 75) โ (31, 30, 45, 75) ์กฐ๊ฑด ํ์ธ: R4 > R2 (75 > 30) โ Yes, ๊ณ์ ์งํ ๋ค์ฏ ๋ฒ์งธ ๋ฐ๋ณต ์์ ๊ฐ: (R1, R2, R3, R4) = (31, 30, 45, 75) ๊ณ์ฐ ์์: R2 = R1 + R1 (31 + 31 = 62) โ (31, 62, 45, 75) R3 = R2 + R1 (62 + 31 = 93) โ (31, 62, 93, 75) R4 = R3 - R1 (93 - 31 = 62) โ (31, 62, 93, 62) R1 = R1 | R2 (31 | 62 = 63) โ (63, 62, 93, 62) R4 = R4 & R3 (62 & 93 = 28) โ (63, 62, 93, 28) R4 = R2 + R3 (62 + 93 = 155) โ (63, 62, 93, 155) ์กฐ๊ฑด ํ์ธ: R4 > R2 (155 > 62) โ Yes, ๊ณ์ ์งํ ์ฌ์ฏ ๋ฒ์งธ ๋ฐ๋ณต (๋ง์ง๋ง) ์์ ๊ฐ: (R1, R2, R3, R4) = (63, 62, 93, 155) ๊ณ์ฐ ์์ R2 = R1 + R1 (63 + 63 = 126) โ (63, 126, 93, 155) R3 = R2 + R1 (126 + 63 = 189) โ (63, 126, 189, 155) R4 = R3 - R1 (189 - 63 = 126) โ (63, 126, 189, 126) R1 = R1 | R2 (63 | 126 = 127) โ (127, 126, 189, 126) R4 = R4 & R3 (126 & 189 = 120) โ (127, 126, 189, 120) R4 = R2 + R3 (126 + 189 = 315) โ (127, 126, 189, 59) ์กฐ๊ฑด ํ์ธ: R4 > R2 (59 > 126) โ No, ์ค๋จ (Halt) 8bit Wrapping (์ค๋ฒํ๋ก์ฐ): 8๋นํธ ๋ ์ง์คํฐ๋ 255๊น์ง๋ง ํํ ๊ฐ๋ฅํ๋ฏ๋ก, 315๋ 256์ ๋บ ๋๋จธ์ง ๊ฐ์ธ 59๊ฐ ๋๋ค. < ํ์ผ > sources (Homework) ControlUnit.sv DataPath.sv DedicatedProcessor.sv simulation (Homework) DedicatedProcessor_tb.sv
Final
ยท 2025-08-12
2025-08-11
Uart + UpDownCounter Design < Block Design > < Code : uart > `timescale 1ns / 1ps module uart ( // global signal input logic clk, input logic reset, // transmitter signal input logic start, input logic [7:0] tx_data, output logic tx_busy, output logic tx_done, output logic tx, // receiver signal output logic [7:0] rx_data, output logic rx_done, input logic rx ); logic br_tick; baudrate_gen U_BRAUD_GEN ( .clk (clk), .reset (reset), .br_tick(br_tick) ); transmitter U_Transmitter ( .clk (clk), .reset (reset), .br_tick(br_tick), .start (start), .tx_data(tx_data), .tx_busy(tx_busy), .tx_done(tx_done), .tx (tx) ); receiver U_Receiver ( .clk (clk), .reset (reset), .br_tick(br_tick), .rx_data(rx_data), .rx_done(rx_done), .rx (rx) ); endmodule module baudrate_gen ( input logic clk, input logic reset, output logic br_tick ); logic [$clog2(100_000_000 / 9600 / 16)-1:0] br_counter; //logic [3:0] br_counter; always_ff @(posedge clk, posedge reset) begin if (reset) begin br_counter <= 0; br_tick <= 1'b0; end else begin if (br_counter == 100_000_000 / 9600 / 16 - 1) begin //if (br_counter == 10 - 1) begin br_counter <= 0; br_tick <= 1'b1; end else begin br_counter <= br_counter + 1; br_tick <= 1'b0; end end end endmodule module transmitter ( input logic clk, input logic reset, input logic br_tick, input logic start, input logic [7:0] tx_data, output logic tx_busy, output logic tx_done, output logic tx ); typedef enum { IDLE, START, DATA, STOP } tx_state_e; tx_state_e tx_state, tx_next_state; logic [7:0] temp_data_reg, temp_data_next; logic tx_reg, tx_next; logic [3:0] tick_cnt_reg, tick_cnt_next; logic [2:0] bit_cnt_reg, bit_cnt_next; logic tx_done_reg, tx_done_next; logic tx_busy_reg, tx_busy_next; assign tx = tx_reg; assign tx_busy = tx_busy_reg; assign tx_done = tx_done_reg; always_ff @(posedge clk, posedge reset) begin if (reset) begin tx_state <= IDLE; temp_data_reg <= 0; tx_reg <= 1'b1; tick_cnt_reg <= 0; bit_cnt_reg <= 0; tx_done_reg <= 0; tx_busy_reg <= 0; end else begin tx_state <= tx_next_state; temp_data_reg <= temp_data_next; tx_reg <= tx_next; tick_cnt_reg <= tick_cnt_next; bit_cnt_reg <= bit_cnt_next; tx_done_reg <= tx_done_next; tx_busy_reg <= tx_busy_next; end end always_comb begin tx_next_state = tx_state; temp_data_next = temp_data_reg; tx_next = tx_reg; tick_cnt_next = tick_cnt_reg; bit_cnt_next = bit_cnt_reg; tx_done_next = tx_done_reg; tx_busy_next = tx_busy_reg; case (tx_state) IDLE: begin tx_next = 1'b1; tx_done_next = 0; tx_busy_next = 0; if (start) begin tx_next_state = START; temp_data_next = tx_data; tick_cnt_next = 0; bit_cnt_next = 0; tx_busy_next = 1; end end START: begin tx_next = 1'b0; if (br_tick) begin if (tick_cnt_reg == 15) begin tx_next_state = DATA; tick_cnt_next = 0; end else begin tick_cnt_next = tick_cnt_reg + 1; end end end DATA: begin tx_next = temp_data_reg[0]; if (br_tick) begin if (tick_cnt_reg == 15) begin tick_cnt_next = 0; if (bit_cnt_reg == 7) begin tx_next_state = STOP; bit_cnt_next = 0; end else begin temp_data_next = {1'b0, temp_data_reg[7:1]}; bit_cnt_next = bit_cnt_reg + 1; end end else begin tick_cnt_next = tick_cnt_reg + 1; end end end STOP: begin tx_next = 1'b1; if (br_tick) begin if (tick_cnt_reg == 15) begin tx_next_state = IDLE; tx_done_next = 1; tx_busy_next = 0; tick_cnt_next = 0; end else begin tick_cnt_next = tick_cnt_reg + 1; end end end endcase end endmodule module receiver ( input logic clk, input logic reset, input logic br_tick, output logic [7:0] rx_data, output logic rx_done, input logic rx ); typedef enum { IDLE, START, DATA, STOP } rx_state_e; rx_state_e rx_state, rx_next_state; logic [4:0] tick_cnt_reg, tick_cnt_next; logic [2:0] bit_cnt_reg, bit_cnt_next; logic [7:0] rx_data_reg, rx_data_next; logic rx_done_next, rx_done_reg; assign rx_data = rx_data_reg; assign rx_done = rx_done_reg; always_ff @(posedge clk, posedge reset) begin if (reset) begin rx_state <= IDLE; tick_cnt_reg <= 0; bit_cnt_reg <= 0; rx_data_reg <= 0; rx_done_reg <= 0; end else begin rx_state <= rx_next_state; tick_cnt_reg <= tick_cnt_next; bit_cnt_reg <= bit_cnt_next; rx_data_reg <= rx_data_next; rx_done_reg <= rx_done_next; end end always_comb begin rx_next_state = rx_state; rx_done_next = rx_done; tick_cnt_next = tick_cnt_reg; bit_cnt_next = bit_cnt_reg; rx_data_next = rx_data_reg; case (rx_state) IDLE: begin rx_done_next = 0; if (rx == 1'b0) begin rx_next_state = START; tick_cnt_next = 0; bit_cnt_next = 0; rx_data_next = 0; end end START: begin if (br_tick) begin if (tick_cnt_reg == 7) begin tick_cnt_next = 0; rx_next_state = DATA; end else begin tick_cnt_next = tick_cnt_reg + 1; end end end DATA: begin if (br_tick) begin if (tick_cnt_reg == 15) begin tick_cnt_next = 0; rx_data_next = {rx, rx_data_reg[7:1]}; if (bit_cnt_reg == 7) begin bit_cnt_next = 0; rx_next_state = STOP; end else begin bit_cnt_next = bit_cnt_reg + 1; end end else begin tick_cnt_next = tick_cnt_reg + 1; end end end STOP: begin if (br_tick) begin if (tick_cnt_reg == 23) begin tick_cnt_next = 0; rx_done_next = 1; rx_next_state = IDLE; end else begin tick_cnt_next = tick_cnt_reg + 1; end end end endcase end endmodule < Simulation : uart > < Code : UpDownCounter > `timescale 1ns / 1ps module UpDownCounter ( input logic clk, input logic reset, input logic btn_mode, input logic btn_run_stop, input logic btn_clear, input logic [ 7:0] rx_data, input logic rx_done, output logic [ 1:0] led_mode, output logic [ 1:0] led_run_stop, output logic [13:0] count ); logic tick_10hz; logic mode, run_stop, clear; clk_div_10hz U_CLK_DIV_10hz ( .clk (clk), .reset (reset), .run_stop (run_stop), .clear (clear), .tick_10hz(tick_10hz) ); up_down_counter U_UP_DOWN_COUNTER ( .clk (clk), .reset(reset), .tick (tick_10hz), .mode (mode), .clear(clear), .count(count) ); control_unit U_CU ( .clk (clk), .reset (reset), .btn_mode (btn_mode), .btn_run_stop(btn_run_stop), .btn_clear (btn_clear), .rx_data (rx_data), .rx_done (rx_done), .mode (mode), .run_stop (run_stop), .clear (clear), .led_mode (led_mode), .led_run_stop(led_run_stop) ); endmodule // ... module control_unit ( input logic clk, input logic reset, input logic btn_mode, input logic btn_run_stop, input logic btn_clear, input logic [7:0] rx_data, input logic rx_done, output logic mode, output logic run_stop, output logic clear, output logic [1:0] led_mode, output logic [1:0] led_run_stop ); /************************** MODE FSM **************************/ typedef enum { UP, DOWN } state_mode_e; state_mode_e state_mode, next_state_mode; // transition logic always_ff @(posedge clk, posedge reset) begin if (reset) begin state_mode <= UP; end else begin state_mode <= next_state_mode; end end // output logic always_comb begin next_state_mode = state_mode; mode = 0; led_mode = 2'b00; case (state_mode) UP: begin led_mode = 2'b01; mode = 0; if (btn_mode) begin next_state_mode = DOWN; end if (rx_done) begin if (rx_data == 8'h4d || rx_data == 8'h6d) begin // M, m next_state_mode = DOWN; end end end DOWN: begin led_mode = 2'b10; mode = 1; if (btn_mode) begin next_state_mode = UP; end if (rx_done) begin if (rx_data == 8'h4d || rx_data == 8'h6d) begin // M, m next_state_mode = UP; end end end endcase end /********************* RUN STOP CLEAR FSM *********************/ typedef enum { STOP, RUN, CLEAR } state_counter_e; state_counter_e state_counter, next_state_counter; always_ff @(posedge clk, posedge reset) begin if (reset) begin state_counter <= STOP; end else begin state_counter <= next_state_counter; end end always_comb begin next_state_counter = state_counter; run_stop = 0; clear = 0; led_run_stop = 2'b00; case (state_counter) STOP: begin led_run_stop = 2'b01; if (btn_run_stop) next_state_counter = RUN; else if (btn_clear) next_state_counter = CLEAR; if (rx_done) begin if (rx_data == 8'h52 || rx_data == 8'h72) begin // R, r next_state_counter = RUN; end end if (rx_done) begin if (rx_data == 8'h43 || rx_data == 8'h63) begin // C, c next_state_counter = CLEAR; end end end RUN: begin run_stop = 1; led_run_stop = 2'b10; if (btn_run_stop) next_state_counter = STOP; if (rx_done) begin if (rx_data == 8'h53 || rx_data == 8'h73) begin // S, s next_state_counter = STOP; end end end CLEAR: begin clear = 1; next_state_counter = STOP; end endcase end endmodule < Schematic > < ํ์ผ > sources (Class) top_UpDownCounter.sv uart.sv button_detector.sv UpDownCounter.sv tfndController.svext simulation (Class) uart_tb.sv constrs (Class) Basys-3-Master.xdc CPU CISC(Complex Instruction Set Computer) micro processor์๊ฒ ๋ช ๋ น์ ๋ด๋ฆฌ๋๋ฐ ํ์ํ ๋ชจ๋ ๋ช ๋ น์ด ์ ์ ๊ฐ์ถ๊ณ ์๋ processor์ด๋ค. ๋ฐ๋ผ์ ๋ณต์กํ๊ณ ๊ธฐ๋ฅ์ด ๋ง์ ๋ช ๋ น์ด๋ก ๊ตฌ์ฑ๋์ด์๋ค. ๊ณผ๊ฑฐ์๋ ์ปดํจํฐ ๋ฉ๋ชจ๋ฆฌ ์ฉ๋์ด ํฌ์ง ์์์ sw ํ๋ก๊ทธ๋จ์ ์ฉ๋์ ์ค์ด๊ธฐ ์ํด ํ๋์ ๋ช ๋ น์ด๋ก ์ฌ๋ฌ ์์ ์ ์ํํ๋๋ก ํ๊ธฐ ๋๋ฌธ์ CISC๋ฅผ ๋ง์ด ์ฌ์ฉํ์๋ค. ์ฅ์ : ๋ณตํฉ์ ์ด๊ณ ๊ธฐ๋ฅ์ด ๋ง๊ธฐ ๋๋ฌธ์ ํ์ ํธํ์ฑ?์ด ์ข๋ค. ๋ฐ๋ผ์ ํธํ์ฑ์ด ์ ๋์ ์ผ๋ก ํ์ํ PC ํ๊ฒฝ์์๋ CISC๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข๋ค. ๋จ์ : ํ์ง๋ง ํธ๋์ง์คํฐ ์ง์ ์ ์์ด์ ํจ์จ์ฑ์ด ๋จ์ด์ง๊ธฐ ๋๋ฌธ์ ์ฑ๋ฅ ํฅ์์ ๋ฐฉํดํ๋ ์์ธ์ด ๋ ์ ์์ผ๋ฉฐ, ์ ๋ ฅ ์๋ชจ๊ฐ ํฌ๊ณ , ๊ฐ๊ฒฉ์ด ๋น์ธ๋ค๋ ๋ฑ์ ๋จ์ ์ด ์๋ค. ์ฉ๋: ๋ค์ํ ๋ช ๋ น์ด๋ฅผ ํฌํจํ๊ณ ์์ด ์ผ๋ฐ์ ์ผ๋ก ์ฐ๋ฆฌ๊ฐ ์ฌ์ฉํ๋ ๋ฒ์ฉ ์ปดํจํฐ(general purpose computer)์ CPU๋ก ๋ง์ด ์ฌ์ฉ๋๋ค. RISC(Reduced Instruction Set Computer) CISC ๋ด๋ถ์ ๊ฐ์ถ์ด์ง ๋ชจ๋ ๋ช ๋ น์ด๋ค ์ค ๋ถ๊ณผ 20%์ ํด๋นํ๋ ๋ช ๋ น์ด๋ค๋ง์ด ์ ์ฒด 80% ์ด์์ ์ผ์ ์ฒ๋ฆฌํ๋ค. ๋ฐ๋ผ์ CISC์ ๊ฐ์ด ํ์ํ ๋ชจ๋ ๋ช ๋ น์ด ์ ์ ๊ฐ๊ณ ์๋ ๊ฒ์ ๋นํจ์จ์ ์ผ ์ ์๋ค. ์ด๋ฅผ ๊ทน๋ณตํ๊ธฐ ์ํด ๋ฑ์ฅํ ๊ฒ์ด RISC์ด๋ค. ์ฅ์ : RISC๋ ์ ์ ์์ ๋ช ๋ น์ด๋ค(์ฌ์ฉ ๋น๋๊ฐ ๋์ 20%์ ๋ช ๋ น์ด๋ค)๋ก ๊ตฌ์ฑ๋ processor์ด๋ค. ๋ฐ๋ผ์ CISC๋ณด๋ค ๋ ๋น ๋ฅธ ์๋?๋ก ๋์ํ ์ ์์ผ๋ฉฐ, ๋จ์ํ๊ณ , ์ ๋ ฅ์๋ชจ๊ฐ ์ ๊ณ , ๊ฐ๊ฒฉ๋ ์ ๋ ดํ๋ค. (Tr ๊ฐฏ์ โ) ๋จ์ : ํ์ง๋ง ํ๋์จ์ด๊ฐ ๊ฐ๋จํ ๋์ ์ํํธ์จ์ด(Compiler)๊ฐ ํฌ๊ณ ๋ณต์กํด์ก์ผ๋ฉฐ, ํ์ ํธํ์ฑ์ด ๋ถ์กฑํ๋ค๋ ๋จ์ ์ด ์๋ค. ์ฉ๋: RISC ๊ตฌ์กฐ๋ ํ์ดํ๋ผ์ธ ์ค์ฒฉ์ด ๊ฐ๋ฅํด์ ๊ฐ์ ์์ ๋ช ๋ น์ด์ ๋ํด ์ ์ clock์ผ๋ก ์ฒ๋ฆฌ๊ฐ ๊ฐ๋ฅํ๋ฉฐ ๋ฐ์ด๊ณผ ์ ๋ ฅ ์๋ชจ๋ ์ค์ผ ์ ์๋ค. ๋ฐ๋ผ์ ์๋ฒ ๋๋ ํ๋ก์ธ์์์๋ RISC ๊ตฌ์กฐ๋ฅผ ๋ง์ด ์ฌ์ฉํ๋ค. (MIPS, ARM) ์์ผ๋ก์ ํ์ต ๋ฐ ๊ตฌํ ๊ณํ RISC-V Instruction Set ์ดํด RV32I (Base Integer ISA) ๊ตฌํ 1.Single-Cycle Processor (๋ชจ๋ ๋ช ๋ น์ด๋ฅผ 1 ํด๋ญ ๋ด์ ์คํ) 2.Multi-Cycle Processor (๋ช ๋ น์ด ์ข ๋ฅ์ ๋ฐ๋ผ ์คํ ํด๋ญ ์๊ฐ ๋ค๋ฆ) 3.Pipeline ๊ตฌ์กฐ CPU (์ ํ ์ฌํญ / ๋ฏธ๊ตฌํ ์์ ) DedicatedProcessor_Counter Design < Design Specification > 0~9 ๊น์ง ์นด์ดํธํ๋ Processor๋ฅผ ์ค๊ณ A = 0 (Data) < C ์ธ์ด > A = 0; while (A < 10) { output = A; A = A + 1; } halt; < Data Path > < ASM > < Code : DedicatedProcessor_Counter > `timescale 1ns / 1ps module DedicatedProcessor_Counter ( input logic clk, input logic reset, output logic [7:0] OutBuffer ); logic ASrcMuxSel; logic AEn; logic ALt10; logic OutBufEn; logic [$clog2(10_000_000)-1:0] div_counter; logic clk_10hz; always_ff @(posedge clk, posedge reset) begin if (reset) begin div_counter <= 0; end else begin if (div_counter == 10_000_000 - 1) begin div_counter <= 0; clk_10hz <= 1'b1; end else begin div_counter <= div_counter + 1; clk_10hz <= 1'b0; end end end ControlUnit U_ControlUnit ( .clk(clk_10hz), // bitstream .* ); DataPath U_DataPath ( .clk(clk_10hz), // bitstream .* ); endmodule module Register ( input logic clk, input logic reset, input logic en, input logic [7:0] d, output logic [7:0] q ); always_ff @(posedge clk, posedge reset) begin if (reset) begin q <= 0; end else begin if (en) begin q <= d; end end end endmodule module Mux_2x1 ( input logic sel, input logic [7:0] x0, input logic [7:0] x1, output logic [7:0] y ); always_comb begin y = 8'b0; case (sel) 1'b0: y = x0; 1'b1: y = x1; endcase end endmodule module Adder ( input logic [7:0] a, input logic [7:0] b, output logic [7:0] sum ); assign sum = a + b; endmodule module Comparator ( input logic [7:0] a, input logic [7:0] b, output logic lt ); assign lt = a < b; endmodule module OutBuf ( input logic en, input logic [7:0] x, output logic [7:0] y ); assign y = en ? x : 8'bx; endmodule module ControlUnit ( input logic clk, input logic reset, input logic ALt10, output logic ASrcMuxSel, output logic AEn, output logic OutBufEn ); typedef enum { S0, S1, S2, S3, S4 } state_e; state_e state, next_state; always_ff @(posedge clk, posedge reset) begin if (reset) begin state <= S0; end else begin state <= next_state; end end always_comb begin ASrcMuxSel = 0; AEn = 0; OutBufEn = 0; next_state = state; case (state) S0: begin ASrcMuxSel = 0; AEn = 1; OutBufEn = 0; next_state = S1; end S1: begin ASrcMuxSel = 1; AEn = 0; OutBufEn = 0; if (ALt10) next_state = S2; else next_state = S4; end S2: begin ASrcMuxSel = 1; AEn = 0; OutBufEn = 1; next_state = S3; end S3: begin ASrcMuxSel = 1; AEn = 1; OutBufEn = 0; next_state = S1; end S4: begin ASrcMuxSel = 1; AEn = 0; OutBufEn = 0; next_state = S4; end endcase end endmodule module DataPath ( input logic clk, input logic reset, input logic ASrcMuxSel, input logic AEn, input logic OutBufEn, output logic ALt10, output logic [7:0] OutBuffer ); logic [7:0] AdderResult, ASrcMuxOut, ARegOut; Mux_2x1 U_ASrcMux ( .sel(ASrcMuxSel), .x0 (8'b0), .x1 (AdderResult), .y (ASrcMuxOut) ); Register U_A_Reg ( .clk (clk), .reset(reset), .en (AEn), .d (ASrcMuxOut), .q (ARegOut) ); Comparator U_ALt10 ( .a (ARegOut), .b (8'd10), .lt(ALt10) ); Adder U_Adder ( .a (ARegOut), .b (8'd1), .sum(AdderResult) ); // OutBuf U_OutBuf ( // .en(OutBufEn), // .x (ARegOut), // .y (OutBuffer) // ); Register U_OutReg ( .clk (clk), .reset(reset), .en (OutBufEn), .d (ARegOut), .q (OutBuffer) ); endmodule < Comment > DataPath Comparator ์ถ๋ ฅ(ALt10)์ C์ while (A < 10)์ ํ๋์จ์ด๋ก ์นํํ ์ ์ด ๋ถ๊ธฐ ์ ๋ ฅ์ผ๋ก ํ์๋ค. ๋ ์ง์คํฐ๋ณ Enable์ A ์ ๋ฐ์ดํธ์ ์ถ๋ ฅ ์ํ๋ง์ ํ์ด๋ฐ์ ๋ ๋ฆฝ ์ ์ดํด ์ ํํ ์์ยท์ ์งยท์ด๊ธฐํ๋ฅผ ๋ณด์ฅํ๋ค. ๋์ผ ์ฃ์ง์์ OutReg์ AReg๋ฅผ ํจ๊ป ์ํ๋งํจ์ผ๋ก์จ C์ โoutput=A; A=A+1;โ๋ฅผ ํด๋ญ ํ๋๋ก ์ ํํ ๊ตฌํํ๋ค. < Schematic > < Simulation > < ํ์ผ > sources (Class) DedicatedProcessor_Counter.sv simulation (Class) DedicatedProcessor_Counter_tb.sv constrs (Class) Basys-3-Master.xdc Homework < Design Specification > 0+1+2+3+โฆ+9+10 = 55 ์ ๊ฐ์ด ๋์ ์ผ๋ก ๋ง์ ๊ฒฐ๊ณผ ์ถ๋ ฅ์ด ๋๋๋ก ๊ตฌํ FND์ ๋์ ๊ฐ์ ์ถ๋ ฅ < C ์ธ์ด > a = 0; b = 0; while (a <= 10) { b = b + a; // ๋์ a = a + 1; // ์ฆ๊ฐ } output = b; // 55 < Data Path > < ASM > < Code : top > `timescale 1ns / 1ps module top ( input logic clk, input logic reset, output logic [3:0] fndCom, output logic [7:0] fndFont ); logic [7:0] data; DedicatedProcessor U_DedicatedProcessor ( .clk(clk), .reset(reset), .OutBuffer(data) ); fndController U_fndController ( .clk(clk), .reset(reset), .number(data), .fndCom(fndCom), .fndFont(fndFont) ); endmodule < Code : DedicatedProcessor (DataPath) > //... module DataPath ( input logic clk, input logic reset, input logic ASrcMuxSel, input logic AEn, input logic OutBufEn, output logic ALt10, output logic [7:0] OutBuffer ); logic [7:0] AdderResult, ASrcMuxOut, ARegOut; logic [7:0] SumResult, BSrcMuxOut, BRegOut; Mux_2x1 U_ASrcMux ( .sel(ASrcMuxSel), .x0 (8'b0), .x1 (AdderResult), .y (ASrcMuxOut) ); Register U_A_Reg ( .clk (clk), .reset(reset), .en (AEn), .d (ASrcMuxOut), .q (ARegOut) ); Comparator U_ALt10 ( .a (ARegOut), .b (8'd11), // 8'd11 .lt(ALt10) ); Adder U_Adder ( .a (ARegOut), .b (8'd1), .sum(AdderResult) ); // OutBuf U_OutBuf ( // .en(OutBufEn), // .x (ARegOut), // .y (OutBuffer) // ); // Register U_OutReg ( // .clk (clk), // .reset(reset), // .en (OutBufEn), // .d (ARegOut), // .q (OutBuffer) // ); /*************** B ***************/ Mux_2x1 U_BSrcMux ( .sel(ASrcMuxSel), .x0 (8'b0), .x1 (SumResult), .y (BSrcMuxOut) ); Register U_B_Reg ( .clk (clk), .reset(reset), .en (AEn), .d (BSrcMuxOut), .q (BRegOut) ); Adder U_Sum ( .a (AdderResult), .b (BRegOut), .sum(SumResult) ); Register U_OutReg ( .clk (clk), .reset(reset), .en (OutBufEn), .d (BRegOut), .q (OutBuffer) ); endmodule //... < Comment > DataPath ๋์ ๊ฐ(B)์ ํ์ฌ ํญ(A ๋๋ A+1)์ ๋ํ๋ ๋ง์ ๊ธฐ์ ๋์ ๊ฐ์ ์ ์ฅํ๋ ๋ ์ง์คํฐ(B Reg)๋ฅผ ์ถ๊ฐ A์ B๋ ๋์ผํ Enable(AEn)๊ณผ ์ด๊ธฐํ ๊ฒฝ๋ก(ASrcMuxSel=0)๋ฅผ ๊ณต์ ํ์ฌ ๋ฃจํ ๊ฐฑ์ ์ ๋์ ์ ๋ฐ์ดํธ๊ฐ ๊ฐ๋ฅ ์ถ๋ ฅ ๋ ์ง์คํฐ๋ฅผ ๋์ด ๊ธ๋ฆฌ์น ๋ฐฉ์ง์ ํ์ด๋ฐ ์ฌ์ ๋ฅผ ํ๋ณด < simulation > < Video > < ๊ณ ์ฐฐ > DataPath์ ๋์ ๊ธฐ ๊ฒฝ๋ก๋ฅผ ์ถ๊ฐํจ์ผ๋ก์จ, ๋จ์ ์นด์ดํธ๊ฐ ์๋ ๋์ ์ฐ์ฐ๊น์ง ์ง์ํ๋ ๊ตฌ์กฐ๋ฅผ ๊ตฌํํ ์ ์์๋ค. ๊ฐ ๋ ์ง์คํฐ์ Enable๊ณผ ์กฐ๊ฑด ์ ์ด๋ฅผ ํตํด ์ถ๋ ฅ ์์ ์ฑ๊ณผ ์ฐ์ฐ ์ ํ์ฑ์ ํ๋ณดํ์๋ค. < ํ์ผ > sources (Homework) top.sv DedicatedProcessor.sv fndController.sv simulation (Homework) DedicatedProcessor_tb.sv constrs (Homework) Basys-3-Master.xdc
Final
ยท 2025-08-11
2025-08-08
Run_Stop_Clear_Counter Design < Code : UpDownCounter > `timescale 1ns / 1ps module UpDownCounter ( input logic clk, input logic reset, input logic btn_mode, input logic btn_run_stop, input logic btn_clear, output logic [ 1:0] led_mode, output logic [ 1:0] led_run_stop, output logic [13:0] count ); logic tick_10hz; logic mode, run_stop, clear; clk_div_10hz U_Clk_Div_10hz ( .clk (clk), .reset (reset), .run_stop (run_stop), .clear (clear), .tick_10hz(tick_10hz) ); up_down_counter U_Up_Down_Counter ( .clk (clk), .reset(reset), .tick (tick_10hz), .mode (mode), .clear(clear), .count(count) ); control_unit U_Control_Unit ( .clk (clk), .reset (reset), .btn_mode (btn_mode), .btn_run_stop(btn_run_stop), .btn_clear (btn_clear), .mode (mode), .run_stop (run_stop), .clear (clear), .led_mode (led_mode), .led_run_stop(led_run_stop) ); endmodule module clk_div_10hz ( input logic clk, input logic reset, input logic run_stop, input logic clear, output logic tick_10hz ); //logic [23:0] div_counter; logic [$clog2(10_000_000)-1:0] div_counter; always_ff @(posedge clk, posedge reset) begin if (reset) begin div_counter <= 0; tick_10hz <= 1'b0; end else begin if (run_stop) begin if (div_counter == 10_000_000 - 1) begin div_counter <= 0; tick_10hz <= 1'b1; end else begin div_counter <= div_counter + 1; tick_10hz <= 1'b0; end end if (clear) begin div_counter <= 0; tick_10hz <= 1'b0; end end end endmodule module up_down_counter ( input logic clk, input logic reset, input logic tick, input logic mode, input logic clear, output logic [13:0] count ); always_ff @(posedge clk, posedge reset) begin if (reset) begin count <= 0; end else begin if (clear) begin count <= 0; end if (mode == 1'b0) begin // up counter if (tick) begin if (count == 9999) begin count <= 0; end else begin count <= count + 1; end end end else begin // down counter if (tick) begin if (count == 0) begin count <= 9999; end else begin count <= count - 1; end end end end end endmodule module control_unit ( input logic clk, input logic reset, input logic btn_mode, input logic btn_run_stop, input logic btn_clear, output logic mode, output logic run_stop, output logic clear, output logic [1:0] led_mode, output logic [1:0] led_run_stop ); /******************** MODE FSM ********************/ typedef enum { UP, DOWN } state_mode_e; state_mode_e state_mode, next_state_mode; // state memory always_ff @(posedge clk, posedge reset) begin if (reset) begin state_mode <= UP; end else begin state_mode <= next_state_mode; end end // transition logic always_comb begin next_state_mode = state_mode; mode = 0; led_mode = 2'b00; case (state_mode) UP: begin led_mode = 2'b01; if (btn_mode) begin next_state_mode = DOWN; end end DOWN: begin mode = 1; led_mode = 2'b10; if (btn_mode) begin next_state_mode = UP; end end endcase end /******************** RUN STOP CLEAR FSM ********************/ typedef enum { STOP, RUN, CLEAR } state_counter_e; state_counter_e state_counter, next_state_counter; always_ff @(posedge clk, posedge reset) begin if (reset) begin state_counter <= STOP; end else begin state_counter <= next_state_counter; end end always_comb begin next_state_counter = state_counter; run_stop = 0; clear = 0; led_run_stop = 2'b00; case (state_counter) STOP: begin led_run_stop = 2'b01; if (btn_run_stop) next_state_counter = RUN; else if (btn_clear) next_state_counter = CLEAR; end RUN: begin run_stop = 1; led_run_stop = 2'b10; if (btn_run_stop) next_state_counter = STOP; end CLEAR: begin clear = 1; next_state_counter = STOP; end endcase end endmodule < Comment > clk_div_10hz run_stop๊ณผ clear ์ ํธ๋ฅผ ๋ฐ์ ์ํ์ ๋ฐ๋ผ ์นด์ดํฐ ๋์์ ์ ์ดํ๋ค. up_down_counter clear ์ ํธ๋ฅผ ๋ฐ์ ์นด์ดํฐ ๊ฐ์ ์ฆ์ ์ด๊ธฐํํ๋ค. โ ์๊ธฐ์น ์์ ์ํ์์๋ ์ํ๋ ์์ ์ ์นด์ดํฐ๋ฅผ ์์ ์ ์ผ๋ก ๋ฆฌ์ ํ ์ ์๋ค. control_unit ํ๋์ control_unit์์ ์ํ ๊ตฌ๋ถ์ฉ ์ ์ด ์ ํธ๋ฅผ ๋ฐ์ ์ฌ๋ฌ ๊ฐ์ FSM(mode, run/stop/clear)์ ๋์์ ์ฒ๋ฆฌํ๋ค. ๊ฐ FSM์์ led_mode์ led_run_stop ์ถ๋ ฅ์ ์ง์ ์์ฑํ๋๋ก ์ค๊ณํ์ฌ ๊ฐ๋ ์ฑ๊ณผ ์ง๊ด์ฑ์ด ํฅ์๋๋ค. < ํ์ผ > sources (Class) top_UpDownCounter.sv button_detector.sv UpDownCounter.sv fndController.sv constrs (Class) Basys-3-Master.xdc Serial ํต์ ํ๋กํ ์ฝ 1. UART ๋น๋๊ธฐ(Asynchronous) ํต์ ๋ฐฉ์ Baud rate(bps, bit per second) ์ค์ ๊ฐ์ ๋ฐ๋ผ ์ก์์ ์๋ ๊ฒฐ์ ์กยท์์ ์์ธก์ ์๋ ์ค์ ์ด ๋ค๋ฅด๋ฉด ํต์ ๋ถ๊ฐ ๋๊ธฐ ์ ํธ๊ฐ ์์ด ์๋ฌ์จ์ด ์๋์ ์ผ๋ก ๋์ ์ก์์ ์๋์ ์ ํ์ด ์์ 1:1 ํต์ ๋ง ๊ฐ๋ฅ (๋ฉํฐํฌ์ธํธ ๋ถ๊ฐ) ์กยท์์ ์ธก์์ ๋ด๋ถ ํด๋ญ์ ์์ฑํ์ฌ ํ์ด๋ฐ ์ ์ง 2. IยฒC ๋๊ธฐ(Synchronous) ํต์ ๋ฐฉ์ SCL(ํด๋ญ)๊ณผ SDA(๋ฐ์ดํฐ) 2์ ์ผ๋ก ๋์ ์ฌ๋ ์ด๋ธ ์ฃผ์(Address)๋ฅผ ์ง์ ํด ํต์ โ SPI๋ณด๋ค ์๋๊ฐ ๋๋ฆผ N:N ํต์ ๊ฐ๋ฅ (ํ๋์ ๋ฒ์ค์ ์ฌ๋ฌ ๋ง์คํฐยท์ฌ๋ ์ด๋ธ ์ฐ๊ฒฐ ๊ฐ๋ฅ) Chip Select ์ ํธ์ ๋ถํ์ (์ฃผ์๋ก ๊ตฌ๋ถ) ์ก์ ๋๋ ์์ ์ค ํ ๋ฐฉํฅ๋ง ๊ฐ๋ฅ (Half-duplex) 3. SPI ๋๊ธฐ(Synchronous) ํต์ ๋ฐฉ์ SCLK(ํด๋ญ), MOSI, MISO, CS(Chip Select) ์ ํธ ์ฌ์ฉ ํด๋ญ์ ๋ง์ถฐ ๋งค์ฐ ๋น ๋ฅธ ๋ฐ์ดํฐ ์ ์ก ๊ฐ๋ฅ โ ์ธ ๋ฐฉ์ ์ค ๊ฐ์ฅ ๋น ๋ฆ 1:N ํต์ (๋ง์คํฐ 1๊ฐ, ๋ค์ ์ฌ๋ ์ด๋ธ ๊ฐ๋ฅ) ์ฌ๋ ์ด๋ธ ์ ํ์ ์ํด Chip Select ์ ํธ์ ์ฌ์ฉ ์ก์์ ๋์ ๊ฐ๋ฅ (Full-duplex) UART / IยฒC / SPI ๋น๊ต ๊ตฌ๋ถ UART IยฒC SPI ํต์ ๋ฐฉ์ ๋น๋๊ธฐ ๋๊ธฐ ๋๊ธฐ ๋ฐ์ดํฐ์ Tx, Rx SDA, SCL MOSI, MISO, SCLK, CS ์๋ ๋ฎ์ ์ค๊ฐ ๋น ๋ฆ ํต์ ๊ตฌ์กฐ 1:1 N:N 1:N Chip Select X X O Duplex Full Half Full ์ฅ์ ๊ฐ๋จ, ๋ฐฐ์ ์ ์ ๋ฐฐ์ ์ ์, ๋ค์ค ์ง์ ๋น ๋ฆ, ๋์ ์ก์์ ๋จ์ ๋๋ฆผ, ๋ฉํฐ ๋ถ๊ฐ SPI๋ณด๋ค ๋๋ฆผ ๋ฐฐ์ ๋ง์, CS ๊ด๋ฆฌ ํ์ Uart (Transmitter) Design < Block Design > < FSM (Transmitter) > < ASM (Transmitter) > < Code : Uart (Transmitter) > `timescale 1ns / 1ps module uart ( input logic clk, input logic reset, input logic start, input logic [7:0] tx_data, output logic tx, output logic tx_busy, output logic tx_done ); logic br_tick; baudrate_gen U_Baudrate_Gen ( .clk (clk), .reset (reset), .br_tick(br_tick) ); transmitter U_Transmitter ( .clk (clk), .reset (reset), .br_tick(br_tick), .start (start), .tx_data(tx_data), .tx_busy(tx_busy), .tx_done(tx_done), .tx (tx) ); endmodule module baudrate_gen ( input logic clk, input logic reset, output logic br_tick ); //logic [$clog2(100_000_000/9600/16)-1:0] br_counter; logic [3:0] br_counter; always_ff @(posedge clk, posedge reset) begin if (reset) begin br_counter <= 0; br_tick <= 1'b0; end else begin //if (br_counter == 100_000_000 / 9600 / 16 - 1) begin // 9600hz 9600bps if (br_counter == 10 - 1) begin br_counter <= 0; br_tick <= 1'b1; end else begin br_counter <= br_counter + 1; br_tick <= 1'b0; end end end endmodule module transmitter ( input logic clk, input logic reset, input logic br_tick, input logic start, input logic [7:0] tx_data, output logic tx_busy, output logic tx_done, output logic tx ); typedef enum { IDLE, START, DATA, STOP } tx_state_e; tx_state_e tx_state, tx_next_state; logic [7:0] temp_data_next, temp_data_reg; logic tx_reg, tx_next; logic [3:0] tick_cnt_reg, tick_cnt_next; logic [2:0] bit_cnt_reg, bit_cnt_next; logic tx_done_reg, tx_done_next; logic tx_busy_reg, tx_busy_next; assign tx = tx_reg; assign tx_busy = tx_busy_reg; assign tx_done = tx_done_reg; always_ff @(posedge clk, posedge reset) begin if (reset) begin tx_state <= IDLE; temp_data_reg <= 0; tx_reg <= 1'b1; tick_cnt_reg <= 0; bit_cnt_reg <= 0; tx_done_reg <= 0; tx_busy_reg <= 0; end else begin tx_state <= tx_next_state; temp_data_reg <= temp_data_next; tx_reg <= tx_next; tick_cnt_reg <= tick_cnt_next; bit_cnt_reg <= bit_cnt_next; tx_done_reg <= tx_done_next; tx_busy_reg <= tx_busy_next; end end always_comb begin tx_next_state = tx_state; temp_data_next = temp_data_reg; tx_next = tx_reg; tick_cnt_next = tick_cnt_reg; bit_cnt_next = bit_cnt_reg; tx_done_next = tx_done_reg; tx_busy_next = tx_busy_reg; case (tx_state) IDLE: begin tx_next = 1'b1; tx_done_next = 0; tx_busy_next = 0; if (start) begin tx_next_state = START; temp_data_next = tx_data; tick_cnt_next = 0; bit_cnt_next = 0; tx_busy_next = 1; end end START: begin tx_next = 1'b0; if (br_tick) begin if (tick_cnt_reg == 15) begin tx_next_state = DATA; tick_cnt_next = 0; end else begin tick_cnt_next = tick_cnt_reg + 1; end end end DATA: begin tx_next = temp_data_reg[0]; if (br_tick) begin if (tick_cnt_reg == 15) begin tick_cnt_next = 0; if (bit_cnt_reg == 7) begin tx_next_state = STOP; bit_cnt_next = 0; end else begin temp_data_next = {1'b0, temp_data_reg[7:1]}; bit_cnt_next = bit_cnt_reg + 1; end end else begin tick_cnt_next = tick_cnt_reg + 1; end end end STOP: begin tx_next = 1'b1; if (br_tick) begin if (tick_cnt_reg == 15) begin tx_next_state = IDLE; tx_done_next = 1; tx_busy_next = 0; tick_cnt_next = 0; end else begin tick_cnt_next = tick_cnt_reg + 1; end end end endcase end endmodule < Comment > baudrate_gen ์์คํ ํด๋ญ(100 MHz)์์ UART ํต์ ์๋ 9600bps, 16๋ฐฐ ์ค๋ฒ์ํ๋ง(ํ์ค UART ์์ ๋ฐฉ์) ์กฐ๊ฑด์ ๋ง์ถฐ br_tick์ ์์ฑํ๋ ๋ชจ๋์ด๋ค. ์นด์ดํฐ ์ต๋๊ฐ์ 100_000_000 / 9600 / 16 - 1๋ก ์ค์ ํ์ฌ, ํด๋น ์ฃผ๊ธฐ๋ง๋ค br_tick์ 1ํด๋ญ ๋์ High๋ก ๋ง๋ค์ด transmitter์ receiver๊ฐ ๋์ผํ baudrate ํด๋ญ์ ๋๊ธฐํ๋๋๋ก ํ๋ค. transmitter UART ์ก์ ๊ธฐ๋ฅผ ๊ตฌํํ ๋ชจ๋๋ก, start ์ ํธ ์ ๋ ฅ ์ ๋ฐ์ดํฐ(tx_data)๋ฅผ UART ํ๋ ์ ๊ตฌ์กฐ(1 start bit + 8 data bits + 1 stop bit)๋ก ์ง๋ ฌ ์ ์กํ๋ค. FSM(IDLE โ START โ DATA โ STOP)์ผ๋ก ๋์ํ๋ฉฐ, ๊ฐ ๋นํธ ์ ์ก์ baudrate ์ค๋ฒ์ํ๋ง(16๋ฐฐ) ๊ธฐ์ค br_tick ์ ํธ์ ๋ง์ถฐ ์งํ๋๋ค. ๋ฐ์ดํฐ ๊ตฌ๋ ์ LSB๋ถํฐ ์์ฐจ์ ์ผ๋ก ์ ์กํ๋ฉฐ, ๋ชจ๋ ๋นํธ ์ ์ก์ด ์๋ฃ๋๋ฉด tx_done์ 1๋ก ์ค์ ํ๊ณ tx_busy๋ฅผ 0์ผ๋ก ๋ณต๊ท์์ผ ๋ค์ ์ ์ก์ ์ค๋นํ๋ค. < ํ์ผ > sources (Class) uart.sv sim (Class) uart_tb.sv Homework < Design Specification > receiver ์ค๊ณ โ uart ๊ตฌํ uart + up down counter โ PC ์ ์ด (ComPortMaster) โrโ : run ์ํ โsโ : stop ์ํ โcโ : clear ์ํ โmโ : mode๋ณ๊ฒฝ < Block Diagram > < FSM (receiver) > < ASM (receiver) > < Code : uart > `timescale 1ns / 1ps module uart ( input logic clk, input logic reset, input logic rx, output logic tx, output logic [7:0] uart_data ); logic br_tick; logic rx_done; logic [7:0] rx_data; assign uart_data = rx_done ? rx_data : 8'b0; baudrate_gen U_Baudrate_Gen ( .clk (clk), .reset (reset), .br_tick(br_tick) ); receiver U_Receiver ( .clk (clk), .reset (reset), .br_tick(br_tick), .rx (rx), .rx_data(rx_data), .rx_done(rx_done) ); transmitter U_Transmitter ( .clk (clk), .reset (reset), .br_tick(br_tick), .start (rx_done), .tx_data(rx_data), .tx_busy(), .tx_done(), .tx (tx) ); endmodule module baudrate_gen ( input logic clk, input logic reset, output logic br_tick ); logic [$clog2(100_000_000/9600/16)-1:0] br_counter; // logic [3:0] br_counter; always_ff @(posedge clk, posedge reset) begin if (reset) begin br_counter <= 0; br_tick <= 1'b0; end else begin if (br_counter == 100_000_000 / 9600 / 16 - 1) begin // 9600hz 9600bps // if (br_counter == 10 - 1) begin br_counter <= 0; br_tick <= 1'b1; end else begin br_counter <= br_counter + 1; br_tick <= 1'b0; end end end endmodule module receiver ( input logic clk, input logic reset, input logic br_tick, input logic rx, output logic [7:0] rx_data, output logic rx_done ); typedef enum { IDLE, START, DATA, STOP } rx_state_e; rx_state_e rx_state, rx_next_state; logic [7:0] rx_data_reg, rx_data_next; logic [4:0] tick_cnt_reg, tick_cnt_next; logic [2:0] bit_cnt_reg, bit_cnt_next; logic rx_done_reg, rx_done_next; assign rx_done = rx_done_reg; assign rx_data = rx_data_reg; always_ff @(posedge clk, posedge reset) begin if (reset) begin rx_state <= IDLE; rx_data_reg <= 0; tick_cnt_reg <= 0; bit_cnt_reg <= 0; rx_done_reg <= 0; end else begin rx_state <= rx_next_state; rx_data_reg <= rx_data_next; tick_cnt_reg <= tick_cnt_next; bit_cnt_reg <= bit_cnt_next; rx_done_reg <= rx_done_next; end end always_comb begin rx_next_state = rx_state; rx_data_next = rx_data_reg; tick_cnt_next = tick_cnt_reg; bit_cnt_next = bit_cnt_reg; rx_done_next = rx_done_reg; case (rx_state) IDLE: begin rx_done_next = 0; if (rx == 0) begin rx_next_state = START; rx_data_next = 0; tick_cnt_next = 0; bit_cnt_next = 0; end end START: begin if (br_tick) begin if (tick_cnt_reg == 7) begin rx_next_state = DATA; tick_cnt_next = 0; end else begin tick_cnt_next = tick_cnt_reg + 1; end end end DATA: begin if (br_tick) begin if (tick_cnt_reg == 15) begin tick_cnt_next = 0; rx_data_next = {rx, rx_data_reg[7:1]}; if (bit_cnt_reg == 7) begin rx_next_state = STOP; bit_cnt_next = 0; end else begin bit_cnt_next = bit_cnt_reg + 1; end end else begin tick_cnt_next = tick_cnt_reg + 1; end end end STOP: begin if (br_tick) begin if (tick_cnt_reg == 23) begin rx_next_state = IDLE; rx_done_next = 1; tick_cnt_next = 0; end else begin tick_cnt_next = tick_cnt_reg + 1; end end end endcase end endmodule module transmitter ( input logic clk, input logic reset, input logic br_tick, input logic start, input logic [7:0] tx_data, output logic tx_busy, output logic tx_done, output logic tx ); typedef enum { IDLE, START, DATA, STOP } tx_state_e; tx_state_e tx_state, tx_next_state; logic [7:0] temp_data_next, temp_data_reg; logic tx_reg, tx_next; logic [3:0] tick_cnt_reg, tick_cnt_next; logic [2:0] bit_cnt_reg, bit_cnt_next; logic tx_done_reg, tx_done_next; logic tx_busy_reg, tx_busy_next; assign tx = tx_reg; assign tx_busy = tx_busy_reg; assign tx_done = tx_done_reg; always_ff @(posedge clk, posedge reset) begin if (reset) begin tx_state <= IDLE; temp_data_reg <= 0; tx_reg <= 1'b1; tick_cnt_reg <= 0; bit_cnt_reg <= 0; tx_done_reg <= 0; tx_busy_reg <= 0; end else begin tx_state <= tx_next_state; temp_data_reg <= temp_data_next; tx_reg <= tx_next; tick_cnt_reg <= tick_cnt_next; bit_cnt_reg <= bit_cnt_next; tx_done_reg <= tx_done_next; tx_busy_reg <= tx_busy_next; end end always_comb begin tx_next_state = tx_state; temp_data_next = temp_data_reg; tx_next = tx_reg; tick_cnt_next = tick_cnt_reg; bit_cnt_next = bit_cnt_reg; tx_done_next = tx_done_reg; tx_busy_next = tx_busy_reg; case (tx_state) IDLE: begin tx_next = 1'b1; tx_done_next = 0; tx_busy_next = 0; if (start) begin tx_next_state = START; temp_data_next = tx_data; tick_cnt_next = 0; bit_cnt_next = 0; tx_busy_next = 1; end end START: begin tx_next = 1'b0; if (br_tick) begin if (tick_cnt_reg == 15) begin tx_next_state = DATA; tick_cnt_next = 0; end else begin tick_cnt_next = tick_cnt_reg + 1; end end end DATA: begin tx_next = temp_data_reg[0]; if (br_tick) begin if (tick_cnt_reg == 15) begin tick_cnt_next = 0; if (bit_cnt_reg == 7) begin tx_next_state = STOP; bit_cnt_next = 0; end else begin temp_data_next = {1'b0, temp_data_reg[7:1]}; bit_cnt_next = bit_cnt_reg + 1; end end else begin tick_cnt_next = tick_cnt_reg + 1; end end end STOP: begin tx_next = 1'b1; if (br_tick) begin if (tick_cnt_reg == 15) begin tx_next_state = IDLE; tx_done_next = 1; tx_busy_next = 0; tick_cnt_next = 0; end else begin tick_cnt_next = tick_cnt_reg + 1; end end end endcase end endmodule < Comment > uart Baudrate Generator: ์์คํ ํด๋ญ(์: 100 MHz)์์ UART ์๋(9600 bps, 16๋ฐฐ ์ค๋ฒ์ํ๋ง)์ ๋ง์ถ br_tick ์์ฑ. ์กยท์์ ๋ชจ๋ ๋ชจ๋ ์ด ์ ํธ๋ก ํ์ด๋ฐ ๋๊ธฐํ. Receiver: rx ์ ๋ ฅ์ ์ํ๋งํด 8๋นํธ ๋ฐ์ดํฐ(rx_data) ๋ณต์, ์์ ์๋ฃ ์ rx_done=1 ์ถ๋ ฅ. Transmitter: rx_done ์ ํธ๋ฅผ start๋ก ๋ฐ์, ์์ ํ ๋ฐ์ดํฐ๋ฅผ ๊ทธ๋๋ก ์ง๋ ฌ ์ก์ (tx). uart_data: rx_done ์์ ์๋ง ์ ํจ ๋ฐ์ดํฐ๋ฅผ ์ถ๋ ฅ, ๊ทธ ์ธ์๋ 0 ์ ์ง. ์ ์ฒด์ ์ผ๋ก ์์ ํ ๋ฐ์ดํฐ๋ฅผ ์ฆ์ ์ฌ์ ์ก(Echo)ํ๋ ๊ตฌ์กฐ์ด๋ฉฐ, ๋ชจ๋ ์ํ์ค๋ br_tick ๊ธฐ๋ฐ์ผ๋ก ์กยท์์ ๋๊ธฐ๋ฅผ ์ ์งํ๋ค. receiver UART ์์ ๊ธฐ. rx์ start-bit(๋ํ) ๊ฐ์ง ํ 16๋ฐฐ ์ค๋ฒ์ํ๋ง ๊ธฐ์ค br_tick์ ๋ง์ถฐ ๋นํธ ์ค์์์ ์ํ๋งํ๋ค. < Code : top_Uart_UpDownCounter > `timescale 1ns / 1ps module top_Uart_UpDownCounter ( input logic clk, input logic reset, input logic [2:0] btn, input logic rx, output logic tx, output logic [1:0] led_mode, output logic [1:0] led_run_stop, output logic [3:0] fndCom, output logic [7:0] fndFont ); logic [7:0] uart_data; uart U_Uart ( .clk (clk), .reset (reset), .rx (rx), .tx (tx), .uart_data(uart_data) ); top_UpDownCounter U_Top_UpDownCounter ( .clk (clk), .reset (reset), .btn (btn), .uart_data (uart_data), .led_mode (led_mode), .led_run_stop(led_run_stop), .fndCom (fndCom), .fndFont (fndFont) ); endmodule < Code : UpDownCounter (control_unit) > // ... module control_unit ( input logic clk, input logic reset, input logic btn_mode, input logic btn_run_stop, input logic btn_clear, input logic [7:0] uart_data, output logic mode, output logic run_stop, output logic clear, output logic [1:0] led_mode, output logic [1:0] led_run_stop ); /******************** MODE FSM ********************/ typedef enum { UP, DOWN } state_mode_e; state_mode_e state_mode, next_state_mode; // state memory always_ff @(posedge clk, posedge reset) begin if (reset) begin state_mode <= UP; end else begin state_mode <= next_state_mode; end end // transition logic always_comb begin next_state_mode = state_mode; mode = 0; led_mode = 2'b00; case (state_mode) UP: begin led_mode = 2'b01; if (btn_mode || (uart_data == "m")) begin next_state_mode = DOWN; end end DOWN: begin mode = 1; led_mode = 2'b10; if (btn_mode || (uart_data == "m")) begin next_state_mode = UP; end end endcase end /******************** RUN STOP CLEAR FSM ********************/ typedef enum { STOP, RUN, CLEAR } state_counter_e; state_counter_e state_counter, next_state_counter; always_ff @(posedge clk, posedge reset) begin if (reset) begin state_counter <= STOP; end else begin state_counter <= next_state_counter; end end always_comb begin next_state_counter = state_counter; run_stop = 0; clear = 0; led_run_stop = 2'b00; case (state_counter) STOP: begin led_run_stop = 2'b01; if (btn_run_stop || (uart_data == "r")) next_state_counter = RUN; else if (btn_clear || (uart_data == "c")) next_state_counter = CLEAR; end RUN: begin run_stop = 1; led_run_stop = 2'b10; if (btn_run_stop || (uart_data == "s")) next_state_counter = STOP; end CLEAR: begin clear = 1; next_state_counter = STOP; end endcase end endmodule < Schematic > < Video > < ๊ณ ์ฐฐ > control_unit์์ UART ๋ฐ์ดํฐ๋ฅผ ์ ๋ ฅ๋ฐ์ ์ํ ๋ณ๊ฒฝ ์ฌํญ์ ์ ๋ฐ์ดํธํ๋๋ก ์ค๊ณ โ ํ์ฅ์ฑ ํ๋ณด < ํ์ผ > sources (Homework) top_Uart_UpDownCounter.sv uart.sv top_UpDownCounter.sv button_detector.sv UpDownCounter.sv fndController.sv constrs (Homework) Basys-3-Master.xdc
Final
ยท 2025-08-08
2025-08-07
๋์งํธ ํ๋ก ๊ธฐ๋ณธ ๋ฐ ํ์ด๋ฐ ํน์ฑ D-flip flop , Latch ์ฐจ์ด ๋ฉ๋ชจ๋ฆฌ ๊ธฐ๋ฅ์ ์ ๋ฌด โ ๋ ๋ค ๋ฉ๋ชจ๋ฆฌ ๊ธฐ๋ฅ์ด ์์ง๋ง, ๋์ ๋ฐฉ์์ ์ฐจ์ด๊ฐ ์์ Latch: ์ ๋ ฅ ์ ํธ๊ฐ ํ์ฑํ๋ ๋์ ๊ฐ์ ๊ณ์ ๋ฐ์ํจ (๋ ๋ฒจ ๋ฏผ๊ฐ) D Flip-Flop: ํด๋ก ์์น/ํ๊ฐ ์์ง์์๋ง ๊ฐ์ ๋ฐ์ (์ฃ์ง ํธ๋ฆฌ๊ฑฐ) ์กฐํฉํ๋ก (Combinational Circuit) ํ์ฌ ์ ๋ ฅ์ ์ํด์๋ง ์ถ๋ ฅ์ด ๊ฒฐ์ ๋จ ๊ณผ๊ฑฐ ์ ๋ ฅ์ด๋ ์ํ์๋ ๋ฌด๊ด ์์: AND, OR, MUX, Decoder ๋ฑ ์์ฐจํ๋ก (Sequential Circuit) ํด๋ก ์ ํธ์ ๋ฐ๋ผ ๋์ (๋๊ธฐ์ ์ค๊ณ) ์ถ๋ ฅ์ ํ์ฌ ์ ๋ ฅ + ์ด์ ์ํ์ ์์กด ์์: D Flip-Flop, ๋ ์ง์คํฐ, FSM ๋ฑ SR Latch S=0, R=0 โ Q=์ ์ง, Qโฒ=์ ์ง โ ์ ์ ์ํ (Hold) S=0, R=1 โ Q=0, Qโฒ=1 โ Reset ๋์ S=1, R=0 โ Q=1, Qโฒ=0 โ Set ๋์ S=1, R=1 โ Q=0, Qโฒ=0 โ ๊ธ์ง ์ํ (Invalid) D Latch D=0, S=0, R=1 โ Reset D=1, S=1, R=0 โ Set Gated D Latch Gate=0, D=x, Q=์ ์ง, Qโ=์ ์ง โ Hold ์ํ Gate=1, D=0, Q=0, Qโ=1 โ Reset ๋์ Gate=1, D=1, Q=1, Qโ=0 โ Set ๋์ D-Filp Flop D Flip-Flop์ Master-Slave ๊ตฌ์กฐ์ ๋ ๊ฐ์ D-Latch๋ก ๊ตฌ์ฑ Master: ํด๋ก์ด 0์ผ ๋ ์ ๋ ฅ ๊ฐ์ ์ ์ฅ Slave: ํด๋ก์ด 1์ผ ๋ Master์ ๊ฐ์ ์ถ๋ ฅ์ ์ ๋ฌ ๋ฐ๋ผ์ ํด๋ก์ ์์น/ํ๊ฐ ์ฃ์ง์๋ง ์ถ๋ ฅ์ด ๋ฐ๋ (์ฃ์ง ํธ๋ฆฌ๊ฑฐ) Metastability ํด๋ก ์ฃ์ง ์์ ์ ์ ๋ ฅ(D)์ด ๋ณํ ๊ฒฝ์ฐ, ์ถ๋ ฅ(Q)์ด ์ผ์ ์๊ฐ ๋์ ์ ์๋์ง ์์ ์ํ์ ๋จธ๋ฌด๋ฅผ ์ ์์ Setup Time: ํด๋ก ์ฃ์ง ์ด์ ์ผ์ ์๊ฐ ๋์ D ์ ๋ ฅ์ด ์์ ์ ์ผ๋ก ์ ์ง๋์ด์ผ ํจ Hold Time: ํด๋ก ์ฃ์ง ์ดํ ์ผ์ ์๊ฐ ๋์๋ D ์ ๋ ฅ์ด ์ ์ง๋์ด์ผ ํจ Metastability ๋ฐฉ์ง ๋ฐฉ๋ฒ โ ๋๊ธฐํ ํ๋ก (Synchronizer) ์ธ๋ถ ์ ํธ(๋น๋๊ธฐ ์ ๋ ฅ ๋ฑ)๋ ํด๋ก ๋๋ฉ์ธ์ ๋ฐ๋ผ metastable ์ํ์ด ์์ D Flip-Flop์ 2๊ฐ ์ด์ ์ง๋ ฌ๋ก ์ฐ๊ฒฐ ์ฒซ ๋ฒ์งธ F/F๋ ์ ํธ๋ฅผ ์ ์ ๋ฐ์๋ค์ด๊ณ ๋ ๋ฒ์งธ F/F๋ ํด๋ก์ ๋๊ธฐํ๋ ์์ ๋ ์ถ๋ ฅ์ ์์ฑ Glitch (์๊ฐ ์ถ๋ ฅ ์ค๋ฅ) ์กฐํฉ ํ๋ก์์ ์ ๋ ฅ์ด ๋์์ ๋ณํ ๋, ๋ด๋ถ ๊ฒ์ดํธ์ ์ ํ ์ง์ฐ ์ฐจ์ด๋ก ์ธํด ์ผ์์ ์ธ ์๋ชป๋ ์ถ๋ ฅ์ด ๋ฐ์ํ ์ ์์ ํด๋ก ์ฃ์ง ์ง์ ๊น์ง ์ถ๋ ฅ์ด ์์ ๋์ง ์์ผ๋ฉด ์์คํ ์ค๋์ ๊ฐ๋ฅ์ฑ ์กด์ฌ Propagation Delay (์ ํ ์ง์ฐ) ์ ๋ ฅ ๋ณํ ์ดํ ์ถ๋ ฅ์ด ์์ ๋ ๋๊น์ง์ ์๊ฐ ์ง์ฐ ์กฐํฉ ํ๋ก๊ฐ ๋ณต์กํ๊ฑฐ๋ ๊น์ด๊ฐ ๊น์์๋ก ์ง์ฐ ์๊ฐ์ด ๊ธธ์ด์ง ์: FFT filter ์ค๊ณ ์ ๊ณฑ์ ์ฐ์ฐ์ ์๊ฐ์ด ์ค๋ ๊ฑธ๋ฆฌ๋ฏ๋ก, ์ค๊ฐ์ ๋ ์ง์คํฐ๋ฅผ ์ฝ์ ํ์ฌ ์ฒ๋ฆฌ Pipeline ์ฒ๋ฆฌ ์ฐ์ฐ ์ค๊ฐ์ ๋ ์ง์คํฐ๋ฅผ ์ถ๊ฐํ์ฌ ์ฐ์ฐ ๋จ๊ณ๋ฅผ ์ฌ๋ฌ ํด๋ก ์ฌ์ดํด๋ก ๋ถํ ์กฐํฉ ๋ ผ๋ฆฌ์ ๊ธธ์ด๋ฅผ ์ค์ฌ glitch๋ฅผ ๋ฐฉ์งํ ์ ์์ ๋ณต์กํ ์ฐ์ฐ์ ๋ถํ ์ฒ๋ฆฌํด ํด๋ก ํ์ด๋ฐ ์ฌ์ ํ๋ณด ๊ฐ๋ฅ ํ ํด๋ญ ๋ด์ ์ฐ์ฐ์ด ๋๋๋๋ก ํ๋ก๋ฅผ ๊ตฌ์ฑํ๋ฉด ์์ ์ ์ธ ์์คํ ์ค๊ณ ๊ฐ๋ฅ Button_Detector Design < Block Diagram > < Code : button_detector > `timescale 1ns / 1ps module button_detector ( input logic clk, input logic reset, input logic i_btn, output logic rising_edge, output logic falling_edge, output logic both_edge ); logic clk_1khz; logic debounce; logic [ 7:0] shift_reg; logic [$clog2(100_000)-1:0] div_counter; // create 1kHz pulse (for button sampling) always_ff @(posedge clk, posedge reset) begin if (reset) begin div_counter <= 0; clk_1khz <= 1'b0; end else begin if (div_counter == 100_000 - 1) begin div_counter <= 0; clk_1khz <= 1'b1; end else begin div_counter <= div_counter + 1; clk_1khz <= 1'b0; end end end shift_register U_SHIFT_REG ( .clk (clk_1khz), .reset (reset), .i_data(i_btn), .o_data(shift_reg) ); assign debounce = &shift_reg; // assign o_btn = debounce; logic [1:0] edge_reg; // edge detector (rising/falling/both) always_ff @(posedge clk, posedge reset) begin if (reset) begin edge_reg <= 0; end else begin edge_reg[0] <= debounce; edge_reg[1] <= edge_reg[0]; end end assign rising_edge = edge_reg[0] & ~edge_reg[1]; assign falling_edge = ~edge_reg[0] & edge_reg[1]; assign both_edge = rising_edge | falling_edge; endmodule module shift_register ( input logic clk, input logic reset, input logic i_data, output logic [7:0] o_data ); always_ff @(posedge clk, posedge reset) begin if (reset) begin o_data <= 0; end else begin o_data <= {i_data, o_data[7:1]}; // right shift //o_data <= {o_data[6:0], i_data};// left shift end end endmodule < Comment > shift_register ์ํํธ ๋ ์ง์คํฐ์ ๊ธฐ๋ณธ ํํ๋ฅผ ๊ตฌํํ ์์๋ก, ๊ตฌ์กฐ์ ๋์ ์๋ฆฌ๋ฅผ ์ตํ๋๋ฉด ์ข๋ค. Right shift : ์๋ก์ด ์ ๋ ฅ(i_data)์ด MSB ์์น๋ก ๋ค์ด๊ฐ๊ณ , ๊ธฐ์กด ๋ฐ์ดํฐ๋ ์ค๋ฅธ์ชฝ(LSB ๋ฐฉํฅ)์ผ๋ก ํ ๋นํธ์ฉ ์ด๋ํ๋ค. Left shift : ์๋ก์ด ์ ๋ ฅ(i_data)์ด LSB ์์น๋ก ๋ค์ด๊ฐ๊ณ , ๊ธฐ์กด ๋ฐ์ดํฐ๋ ์ผ์ชฝ(MSB ๋ฐฉํฅ)์ผ๋ก ํ ๋นํธ์ฉ ์ด๋ํ๋ค. edge detector edge_reg๋ฅผ ํตํด ํ์ฌ debounce์ ์ง์ ์ํ๋ฅผ ์ ์ฅ. rising_edge : 0โ1 ๋ณํ๋ฅผ ๊ฒ์ถ. falling_edge : 1โ0 ๋ณํ๋ฅผ ๊ฒ์ถ. both_edge : ์์น ๋๋ ํ๊ฐ ๋ณํ๋ฅผ ๋ชจ๋ ๊ฒ์ถ. < Code : UpDownCounter > `timescale 1ns / 1ps module UpDownCounter ( input logic clk, input logic reset, input logic button, output logic [13:0] count ); logic tick_10hz; logic mode; clk_div_10hz U_CLK_DIV_10hz ( .clk (clk), .reset (reset), .tick_10hz(tick_10hz) ); up_down_counter U_UP_DOWN_COUNTER ( .clk (clk), .reset(reset), .tick (tick_10hz), .mode (mode), .count(count) ); control_unit U_CU ( .clk(clk), .reset(reset), .button(button), .mode(mode) ); endmodule module up_down_counter ( input logic clk, input logic reset, input logic tick, input logic mode, output logic [13:0] count ); always_ff @(posedge clk, posedge reset) begin if (reset) begin count <= 0; end else begin if (mode == 1'b0) begin // up counter if (tick) begin if (count == 9999) begin count <= 0; end else begin count <= count + 1; end end end else begin // down counter if (tick) begin if (count == 0) begin count <= 9999; end else begin count <= count - 1; end end end end end endmodule module clk_div_10hz ( input logic clk, input logic reset, output logic tick_10hz ); //logic [23:0] div_counter; logic [$clog2(10_000_000)-1:0] div_counter; always_ff @(posedge clk, posedge reset) begin if (reset) begin div_counter <= 0; tick_10hz <= 1'b0; end else begin if (div_counter == 10_000_000 - 1) begin div_counter <= 0; tick_10hz <= 1'b1; end else begin div_counter <= div_counter + 1; tick_10hz <= 1'b0; end end end endmodule module control_unit ( input logic clk, input logic reset, input logic button, output logic mode ); typedef enum { UP, DOWN } state_e; state_e state, next_state; // transition logic always_ff @(posedge clk, posedge reset) begin if (reset) begin state <= UP; end else begin state <= next_state; end end // output logic always_comb begin next_state = state; case (state) UP: begin mode = 0; if (button) begin next_state = DOWN; end end DOWN: begin mode = 1; if (button) begin next_state = UP; end end endcase end endmodule < Comment > control_unit ๋ฒํผ ์ ๋ ฅ์ ๋ฐ๋ผ UP, DOWN ์ํ๋ฅผ ์ ํํ๋ FSM์ ๊ตฌํ typedef enum์ ์ฌ์ฉํ์ฌ ์ํ ์ด๋ฆ(UP, DOWN)์ ์ด๊ฑฐํ์ผ๋ก ์ ์ธ < Schematic > < ํ์ผ > sources (Class) top_UpDownCounter.sv button_detector.sv UpDownCounter.sv fndController.sv constrs (Class) Basys-3-Master.xdc Homework < Design Specification > button 3๊ฐ ์ฌ์ฉ : run_stop ๋ฒํผ, clear ๋ฒํผ, mode ๋ฒํผ mode = 0 : up counting / mode = 1 : down counting up counter : led[0] on down counter : led[1] on stop : led[2] on run : led[3] on < FSM > < Code : UpDownCounter > //... module up_down_counter ( input logic clk, input logic reset, input logic tick, input logic mode, input logic clear, output logic toggle_state, output logic [13:0] count ); always_ff @(posedge clk or posedge reset) begin if (reset) begin toggle_state <= 0; end else begin if (mode) begin toggle_state <= ~toggle_state; end end end always_ff @(posedge clk, posedge reset) begin if (reset | clear) begin count <= 0; end else begin if (toggle_state == 1'b0) begin // up counter if (tick) begin if (count == 9999) begin count <= 0; end else begin count <= count + 1; end end end else begin // down counter if (tick) begin if (count == 0) begin count <= 9999; end else begin count <= count - 1; end end end end end endmodule module cu ( input logic clk, input logic reset, input logic btn_L, input logic btn_R, output logic runstop, output logic clear ); typedef enum { STOP, RUN, CLEAR } state_e; state_e state, next_state; always_ff @(posedge clk, posedge reset) begin if (reset) begin state <= STOP; end else begin state <= next_state; end end always_comb begin next_state = state; runstop = 0; clear = 0; case (state) STOP: begin runstop = 0; clear = 0; if (btn_L) begin next_state = CLEAR; end else if (btn_R) begin next_state = RUN; end end CLEAR: begin clear = 1; if (btn_L) begin next_state = STOP; end end RUN: begin runstop = 1; if (btn_R) begin next_state = STOP; end end endcase end endmodule module state_led ( input logic runstop, input logic clear, input logic mode, output logic [3:0] led ); // (condition) ? true : false assign led[1:0] = mode ? 2'b10 : 2'b01; assign led[3:2] = runstop ? 2'b10 : 2'b01; endmodule < Schematic > < Video > < ๊ณ ์ฐฐ > led ๋ณ์๋ช ์ led_mode, led_runstop์ฒ๋ผ ์๋ฏธ๋ฅผ ๋ช ํํ ์ ์ ์๋๋ก ๊ฐ์ ํด์ผ ํจ ๊ธฐ๋ฅ๋ณ๋ก ๋ถ๋ฆฌํ์ฌ ์ฝ๋์ ํ์ฅ์ฑ์ ํ๋ณดํ ํ์๊ฐ ์์ ํ๋์ control_unit์์ ์ํ๋ฅผ ๊ตฌ๋ถํ๋ ์ ์ด ์ ํธ๋ค์ ๋ฐ์, ์ฌ๋ฌ ๊ฐ์ FSM์ ๋์์ ์ฒ๋ฆฌํ๋ ๊ตฌ์กฐ๋ฅผ ๊ณ ๋ คํจ. (mode FSM์ ๊ธฐ์กด๋๋ก ์ ์ง) < ํ์ผ > sources (Homework) top_UpDownCounter.sv button_debounce.sv UpDownCounter.sv fndController.sv constrs (Homework) Basys-3-Master.xdc
Final
ยท 2025-08-07
2025-08-06
Review : Counter Design < Design Specification > up/down counter ์ค๊ณ mode 0 : up counter mode 1 : down counter 0.1์ด ๊ฐ๊ฒฉ์ผ๋ก counting ๋์ FND์ ์ซ์๊ฐ ์ถ๋ ฅ (0000~9999) ์ ์์ด ์ธ๊ฐ๋๋ฉด mode์ ๋ง๊ฒ counting ๋์ < Block Design > < Code : UpDownCounter > `timescale 1ns / 1ps module UpDownCounter ( input logic clk, input logic reset, input logic sw_mode, output logic [13:0] count ); logic tick_10hz; clk_div_10hz U_CLK_DIV_10hz ( .clk (clk), .reset (reset), .tick_10hz(tick_10hz) ); up_down_counter U_UP_DOWN_COUNTER ( .clk (clk), .reset(reset), .tick (tick_10hz), .mode (sw_mode), .count(count) ); endmodule module clk_div_10hz ( input logic clk, input logic reset, output logic tick_10hz ); //logic [23:0] div_counter; logic [$clog2(10_000_000)-1:0] div_counter; always_ff @(posedge clk, posedge reset) begin if (reset) begin div_counter <= 0; tick_10hz <= 1'b0; end else begin if (div_counter == 10_000_000 - 1) begin div_counter <= 0; tick_10hz <= 1'b1; end else begin div_counter <= div_counter + 1; tick_10hz <= 1'b0; end end end endmodule module up_down_counter ( input logic clk, input logic reset, input logic tick, input logic mode, output logic [13:0] count ); always_ff @(posedge clk, posedge reset) begin if (reset) begin count <= 0; end else begin if (mode == 1'b0) begin // up counter if (tick) begin if (count == 9999) begin count <= 0; end else begin count <= count + 1; end end end else begin // down counter if (tick) begin if (count == 0) begin count <= 9999; end else begin count <= count - 1; end end end end end endmodule < Comment > clk_div_10hz system clock = 100_000_000Hz = 100MHz (1์ด์ 1์ต ์ธ์ดํด) clk_div_10hz โ 10_000_000 ์ธ์ดํด๋ง๋ค tick_10hz๋ฅผ 1๋ก ์ถ๋ ฅ (0.1์ด ์ฃผ๊ธฐ) ์ฆ, tick_10hz๋ 10Hz๋ก ๋์ (1์ด์ 10๋ฒ ํ์ค ๋ฐ์) up_down_counter ์ด๊ธฐ์ up_counter์ down_counter๋ฅผ ๊ฐ๊ฐ ๋ฐ๋ก ์ค๊ณํ๊ณ top ๋ชจ๋์์ sw๋ฅผ ํตํด ์ถ๋ ฅ๋ง ์ ํ(MUX)ํ๋ ค ํ์ผ๋, ์ด ๊ฒฝ์ฐ mode ์ ํ ์ ํ์ฌ ์นด์ดํฐ ๊ฐ์ด ์๋ ์ ํ๋ ๋ค๋ฅธ ์นด์ดํฐ์ ์ด์ ๊ฐ์ด ๊ฐ์๊ธฐ ์ถ๋ ฅ๋ ์ฐ๋ ค๊ฐ ์์๋ค. โ ๊ฒฐ๊ณผ์ ์ผ๋ก ์ถ๋ ฅ ๊ฐ์ด ๋ถ์ฐ์์ ์ผ๋ก ๋ณํ ์ ์์ ๋ฐ๋ผ์ ํ๋์ ์์ฐจํ๋ก(counter)์์ mode๋ฅผ ์ ๋ ฅ์ผ๋ก ๋ฐ์, ๋์ผํ ๋ ์ง์คํฐ(count)์ ๋ํด up/down ์ ์ด๋ฅผ ํ๋ ๋ฐฉ์์ด ์ฐ์์ ์ธ ๋์์ ๋ณด์ฅํ๊ณ ์ค๊ณ ๋ชฉํ์๋ ๋ ์ ํฉํ๋ค๊ณ ํ๋จํ๋ค. < Code : FndController > `timescale 1ns / 1ps module FndController ( input logic clk, input logic reset, input logic [13:0] number, output logic [ 3:0] fndCom, output logic [ 7:0] fndFont ); logic tick_1khz; logic [1:0] count; logic [3:0] digit_1, digit_10, digit_100, digit_1000, digit; clk_div_1khz U_CLK_DIV_1KHZ ( .clk (clk), .reset (reset), .tick_1khz(tick_1khz) ); counter_2bit U_COUNTER_2BIT ( .clk (clk), .reset(reset), .tick (tick_1khz), .count(count) ); decoder_2x4 U_DECODER_2X4 ( .x(count), .y(fndCom) ); digitSplitter U_DIGITSPLITTER ( .number (number), .digit_1 (digit_1), .digit_10 (digit_10), .digit_100 (digit_100), .digit_1000(digit_1000) ); mux_4x1 U_MUX_4X1 ( .sel(count), .x0 (digit_1), .x1 (digit_10), .x2 (digit_100), .x3 (digit_1000), .y (digit) ); BCDtoFND_Decoder U_BCDTOFND_DECODER ( .bcd(digit), .fnd(fndFont) ); endmodule module clk_div_1khz ( input logic clk, input logic reset, output logic tick_1khz ); logic [$clog2(100_000):0] div_counter; always_ff @(posedge clk, posedge reset) begin if (reset) begin div_counter <= 0; tick_1khz <= 0; end else begin if (div_counter == 100_000 - 1) begin div_counter <= 0; tick_1khz <= 1; end else begin div_counter <= div_counter + 1; tick_1khz <= 0; end end end endmodule module counter_2bit ( input logic clk, input logic reset, input logic tick, output logic [1:0] count ); always_ff @(posedge clk, posedge reset) begin if (reset) begin count <= 0; end else begin if (tick) begin count <= count + 1; end end end endmodule module decoder_2x4 ( input logic [1:0] x, output logic [3:0] y ); always_comb begin case (x) 2'b00: y = 4'b1110; 2'b01: y = 4'b1101; 2'b10: y = 4'b1011; 2'b11: y = 4'b0111; endcase end endmodule module digitSplitter ( input logic [13:0] number, output logic [ 3:0] digit_1, output logic [ 3:0] digit_10, output logic [ 3:0] digit_100, output logic [ 3:0] digit_1000 ); assign digit_1 = number % 10; assign digit_10 = number / 10 % 10; assign digit_100 = number / 100 % 10; assign digit_1000 = number / 1000 % 10; endmodule module mux_4x1 ( input logic [1:0] sel, input logic [3:0] x0, input logic [3:0] x1, input logic [3:0] x2, input logic [3:0] x3, output logic [3:0] y ); always_comb begin y = 4'b0000; case (sel) 2'b00: y = x0; 2'b01: y = x1; 2'b10: y = x2; 2'b11: y = x3; endcase end endmodule module BCDtoFND_Decoder ( input logic [3:0] bcd, output logic [7:0] fnd ); always_comb begin case (bcd) 4'h0: fnd = 8'hc0; 4'h1: fnd = 8'hf9; 4'h2: fnd = 8'ha4; 4'h3: fnd = 8'hb0; 4'h4: fnd = 8'h99; 4'h5: fnd = 8'h92; 4'h6: fnd = 8'h82; 4'h7: fnd = 8'hf8; 4'h8: fnd = 8'h80; 4'h9: fnd = 8'h90; 4'ha: fnd = 8'h88; 4'hb: fnd = 8'h83; 4'hc: fnd = 8'hc6; 4'hd: fnd = 8'ha1; 4'he: fnd = 8'h86; 4'hf: fnd = 8'h8e; default: fnd = 8'hff; endcase end endmodule < Comment > clk_div_1khz 1ms ๋ง๋ค tick_1khz๋ฅผ ์์ฑ counter_2bit tick ๋ฐ์ ๋๋ง๋ค count 0โ1โ2โ3 ์ํ decoder_2x4 count์ ๋ฐ๋ผ FND์ ์๋ฆฟ์ ์ ํ (fndCom ์ถ๋ ฅ) digitSplitter 14๋นํธ ์ ๋ ฅ ์ซ์๋ฅผ ์ฒ/๋ฐฑ/์ญ/์ผ์ 4์๋ฆฌ๋ก ๋ถํ mux_4x1 count ์๋ฆฌ์ ํด๋นํ๋ ์๋ฆฟ์ ๊ฐ์ ์ ํ BCDtoFND_Decoder ์๋ฆฟ์ ๊ฐ์ FND ๋์ฝ๋ฉ (fndFont ์ถ๋ ฅ) < Code : top_UpDownCounter > `timescale 1ns / 1ps module top_UpDownCounter ( input logic clk, input logic reset, input logic sw_mode, output logic [3:0] fndCom, output logic [7:0] fndFont ); logic [13:0] count; UpDownCounter U_UPDOWNCOUNTER ( .clk (clk), .reset (reset), .sw_mode(sw_mode), .count (count) ); FndController U_FNDCONTROLLER ( .clk (clk), .reset (reset), .number (count), .fndCom (fndCom), .fndFont(fndFont) ); endmodule < Schematic > < ํ์ผ > sources (Class) top_UpDownCounter.sv UpDownCounter.sv FndController.sv constrs (Class) Basys-3-Master.xdc Homework < Design Specification > mode ๋ฒํผ์ ๋๋ ๋ค ๋์ ๋ up_counter โ down_counter mode ๋ฒํผ์ ๋๋ ๋ค ๋์ ๋ down_counter โ up_counter mode ๋ฒํผ 1๊ฐ๋ก counter ๋์ toggle < ๊ตฌ์ > ๊ธฐ์กด ์ค์์น ์ ๋ ฅ์ ๋ฒํผ ์ ๋ ฅ์ผ๋ก ๋์ฒดํ๊ณ ์ ํ์ผ๋ฉฐ, ๋ฒํผ ํน์ฑ์ ๋ ธ์ด์ฆ๊ฐ ๋ฐ์ํ๋ฏ๋ก ๋๋ฐ์ด์ฑ ์ฒ๋ฆฌ๊ฐ ํ์ํ๋ค๊ณ ํ๋จํ๋ค. ํนํ, ๋ฒํผ์ ๋๋ ๋ค ๋ผ๋ ์๊ฐ(falling edge)์๋ง ๋์์ด ๋ฐ์ํด์ผ ํ๋ฏ๋ก, ์ฃ์ง ๊ฒ์ถ ๊ธฐ๋ฐ ๋์ ์ค๊ณ๊ฐ ์ด๋ฒ ๊ตฌํ์ ํต์ฌ์ด ๋์๋ค. < Code : btn_debounce > `timescale 1ns / 1ps module btn_debounce ( input logic clk, input logic rst, input logic i_btn, output logic o_btn ); parameter F_COUNT = 10_000; logic [$clog2(F_COUNT)-1:0] r_counter; logic r_clk; logic [7:0] q_reg, q_next; logic w_debounce; // 10,000Hz clock divider (0.1ms) always_ff @(posedge clk, posedge rst) begin if (rst) begin r_counter <= 0; r_clk <= 0; end else begin if (r_counter == (F_COUNT - 1)) begin r_counter <= 0; r_clk <= 1'b1; end else begin r_counter <= r_counter + 1; r_clk <= 1'b0; end end end // shift register always_comb begin q_next = {i_btn, q_reg[7:1]}; end always_ff @(posedge r_clk, posedge rst) begin if (rst) begin q_reg <= 0; end else begin q_reg <= q_next; end end // 8 input and gate assign w_debounce = &q_reg; logic r_edge_q; // edge detector always_ff @(posedge clk, posedge rst) begin if (rst) begin r_edge_q <= 0; end else begin r_edge_q <= w_debounce; end end // rising edge // assign o_btn = (~r_edge_q) & w_debounce; // falling edge assign o_btn = r_edge_q & ~w_debounce; endmodule < Comment > 10,000Hz clock divider 0.1ms ๋ง๋ค tick_1khz๋ฅผ ์์ฑ shift register 0.1ms๋ง๋ค ๋ฒํผ ์ ๋ ฅ i_btn์ ๊ฐ์ฅ ์์ ๋นํธ์ ๋ฃ๊ณ , ๊ธฐ์กด ๊ฐ์ ํ ์นธ์ฉ ์ค๋ฅธ์ชฝ์ผ๋ก ๋ฐ์ด ์ ์ฅ โ ์ต๊ทผ 0.8ms ๊ฐ์ ์ ๋ ฅ ์ด๋ ฅ์ ์ ์ฅ 8 input and gate 8๋นํธ shift register์ ๋ชจ๋ ๋นํธ๊ฐ 1์ผ ๋๋ง w_debounce = 1 โ ๋ฒํผ์ด 0.8ms ์ด์ ์์ ์ ์ผ๋ก ๋๋ ธ๋์ง๋ฅผ ํ๋ณ edge detector w_debounce์ ์ํ๋ฅผ ํ ํด๋ญ ์ง์ฐ์ํจ r_edge_q์ ๋น๊ต โ ํ์ฌ ์ํ์ ์ด์ ์ํ์ ์ฐจ์ด๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋ฒํผ ๋ณํ ์์ ์ ๊ฐ์ง falling edge r_edge_q = 1, w_debounce = 0์ธ ๊ฒฝ์ฐ์๋ง o_btn = 1 โ ๋ฒํผ์ด ๋ผ์ด์ง๋ ์๊ฐ(falling edge)๋ง ํ ํด๋ญ ๋์ ์ถ๋ ฅ < Code : UpDownCounter (up_down_counter) > // ... logic toggle_state; always_ff @(posedge clk or posedge reset) begin if (reset) begin toggle_state <= 0; end else begin if (mode) begin toggle_state <= ~toggle_state; end end end //... // counter ๋ณํ ์กฐ๊ฑด ๋ณ๊ฒฝ : mode โ toggle_state < Schematic > < Video > < ๊ณ ์ฐฐ > ๋จ์ํ ์ผ์ ์๊ฐ ๋์ ๋ฒํผ์ด ๋๋ ธ๋์ง๋ฅผ ํ๋จํ๋ ๋ฐฉ์์ด ์๋, ํ์ฌ ์ํ์ ์ด์ ์ํ์ ์ฐจ์ด๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋ฒํผ์ด ๋๋ฆฌ๋ ์๊ฐ๊ณผ ๋ผ์ด์ง๋ ์๊ฐ์ ๊ฐ์งํ๋ ์ฃ์ง ๊ฒ์ถ(edge detection) ๋ฐฉ์์ด ์๋ก์ ๋ค. ๋ํ, shift register๋ฅผ ํ์ฉํด ๋ฒํผ ์ ๋ ฅ์ ์ด๋ ฅ์ ์ ์ฅํจ์ผ๋ก์จ ๋ ธ์ด์ฆ์ ๊ฐํ ์์ ์ ์ธ ๋๋ฐ์ด์ฑ ๋ก์ง์ ๊ตฌํํ ์ ์๋ค๋ ์ ์ด ์ธ์ ๊น์๋ค. < ํ์ผ > sources (Homework) top_UpDownCounter.sv button_debounce.sv UpDownCounter.sv fndController.sv constrs (Homework) Basys-3-Master.xdc
Final
ยท 2025-08-06
<
>
Touch background to close