반응형

ISE Design Suite 환경에서 Multiplexer 개발하기 위해 다음과 같은 설정을 한다.

 

Multiplexer 의 Verilog source code는 다음과 같다.

 

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date:    21:22:52 11/01/2022 
// Design Name: 
// Module Name:    multiplexer 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////
module multiplexer(
	input s0,
	input s1,
	input d0,
	input d1,
	input d2,
	input d3,
	output y
    );
	 
	 assign y = ( ((~s0)&(~s1)&d0) | ((s0)&(~s1)&d1) | ((~s0)&(s1)&d2) |((s0)&(s1)&d3) );


endmodule

 

위의 Source Code를 타이핑 후에 다음과 같은 Setup들을 순차적으로 클릭한다.

 

Simulate Behavitoral Model를 클릭하면, 다음과 같은 화면이 나타난다.

 

다음 그림에서 Objects 항목의 Object Name에서 Input Signal에 팝업 메뉴를 활성화하면 아래와 같은 화면이 나타나는데, 우리는 Force Constant Force Clock의 설정에서 원하는 설정값을 입력하여 원하는 출력을 확인할 수가 있다.

 

 

* AMD XILINK Documentatation Portal에서 각각의 설정에 대해 내용을 확인할 수가 있다.

https://docs.xilinx.com/r/2021.1-English/ug900-vivado-logic-simulation/Force-Clock

 

Force Clock - 2021.1 English

The Force Clock command lets you assign a signal a value that toggles at a specified rate between two states, in the manner of a clock signal, for a specified length of time. When you select the Force Clock option in the Objects window menu, the Force Cloc

docs.xilinx.com

원하는 입력 타이밍을 설정한 후에 우측 상단의 Tool Bar에서 원하는 command 를 클릭하여 출력 상태를 확인할 수가 있다.

 

아래 그림은 s0, s1를 default clock timing에서 s1의 경우,  반주기로 설정하여 (1/2) s0의 1clock period 동안에 2clock가 동작되도록 한 다음에 d0/d1/d2/d3 순으로 Low State에서 s0의 clock 동안에 High State로 toggling 되도록 한후에, s0과 s1의 입력 상태에 따라 d0/d1/d2/d3 의 signal의 상태가 그대로 y의 출력되는 출력 상태를 관찰하였다.

 

즉, [s0s1]=00b=d0, [s0s1]=01b=d1, [s0s1]=10b=d2, [s0s1]=11b=d3 의 logic이 동작되는 것을 확인할 수가 있다. 참고로 dx의 상태가 Low / High state의 값에 관계없이 s0 / s1의 입력 상태에 따라 dx 데이터가 그대로 출력되는 것을 확인할 수가 있다. 

 

반응형
반응형

디지털시스템 설계 과목을 수강하면서, 실습 관련 Verilog를 사용하기 위해서는 Tool을 필요로 하는데, 그에 관련한 설치 프로세스를 남겨보려고 한다. 시간이 지나면 까먹을까봐, 이렇게 글을 남겨야지 다시한번 써먹을 기회가 있을 때에 유용한 글이 되기 때문이다.

 

**** 중요 ****

- ISE Design Suite for Windows 10 - 14.7를 설치하기 위해서는 다음 사양이 필수적이다.

- Windows 10 & 64bit (32bit 환경에서는 설치가 진행되지 않음)

- Computer 사양은 CPU 2cores, RAN 8GB, HDD 85GB를 요구하지만, Hard한 프로젝트를 개발하지 않는다면, 낮은 사양에서도 구동이 가능하다.

 

ug1227-ise-vm-windows10.pdf
0.46MB

 

먼저, 아래 사이트를 접속해서 회원가입 마친 후에 다운로드를 시작한다.

 

https://www.xilinx.com/downloadNav/vivado-design-tools/archive-ise.html

 

ISE Archive

ISE download archived pages : 3X - 14X

www.xilinx.com

사이트를 접속하면 아래와 같은 내용이 나타나는데, 14.7 Window 10 (TAR/GZIP - 15.52GB)를 클릭하여 다운로드를 한다. 생각보다 큰 용량에 놀랄수도 있다.

 

그 다음에 "ISE Design Suite for Windows 10" 개발 툴은 Windows 10 OS 환경에서 Virtual Machine이라는 가상 OS 환경에서 구동하기 때문에 아래 사이트를 방문해서 VM (Virtual Machine)를 다운로드 하도록 하자. 처음에 VM Tool를 미설치하여  "ISE Design Suite for Windows 10" 가 설치가 안되는 경우가 발생하길래, 위의 공식 사이트에서 Documentation 항목의 "14.7 Installation Guide and Release Notes.PDF"를 읽어보면 관련 VM Tool을 설치하라고 언급이 되어있다.

 

https://www.virtualbox.org/wiki/Download_Old_Builds_5_2

 

Download_Old_Builds_5_2 – Oracle VM VirtualBox

Download VirtualBox (Old Builds): VirtualBox 5.2 The Extension Packs in this section are released under the VirtualBox Personal Use and Evaluation License. All other binaries are released under the terms of the GPL version 2. By downloading, you agree to t

www.virtualbox.org

Oracle VirtualBox site에서 다양한 version의 VM Tool이 list-up이 되어있는데, "14.7 Installation Guide and Release Notes.PDF"에서 위와 같은 VirtualBox 5.2.34 version을 언급하여서 해당 version을 설치하기로 한다.

 

먼저, "VirtualBox-5.2.34-133893-Win.exe"를 실행하면 다음과 같은 화면이 나타난다.

 

이렇게해서 Oracle VM VirtualBox 5.2.34 Tool이 설치완료가 된다. 그 다음에 이어서 "Xilinx_ISE_14.7_Win10_14.7_VM_0213_1.zip" 압축해제하여 아래와 같은 파일을 실행시킨다.

 

위의 설치 파일을 순서대로 설치를 마치고 나면, 바탕화면에 다음과 같은 아이콘들을 확인할 수가 있다.

 

Project Navigator를 실행하면, Virtual Machine이 구동되면서 일정 시간을 기다리고 나면, 다음과 같은 화면을 볼 수가 있다. 

 

만약 아래 그림의 ISE Design Suite가 자동실행이 되지 않는다면, 리눅스 환경의 바탕화면에 있는 Project Navigator를 실행하면 다음과 화면이 나타나며, 대학생/대학원생 신분으로 30days trial version이 아닌 영구적인 프로그램 사용을 위해 Help 탭의 Manage License를 클릭한다.

 

https://www.xilinx.com/ 사이트에서 회원가입을 마쳤다는 하에, 아래와 같은 화면에서 "Get Free Vivado/ISE WebPack License"를 선택하고 Next를 클릭한다. 물론 Vitural Machine Setup에서 Network 환경이 내부 연결이 되어따는 가정하에 진행한다. (자세한 Setup 설정은 구글 검색해서 설정)

 

다음과 같은 화면이 나타나는데, Connect Now를 클릭한다.

 

이어서 Webpage로 연결이 되는데, 회원가입 때 등록한 로그인 정보를 입력하고 Sign In을 클릭한다.

 

 

Webpage 상의 Product Licensing Page에서 요구하는 모든 정보를 입력한 후에 Job Funtion에서 "Student"를 선택한 후에 Next를 클릭한다.

 

정상적으로 위의 과정을 거치고 나면, 아래 그림처럼 해당 이메일 계정으로 라이센스 파일을 받을 수가 있다.

 

위에서 받은 라이센스 파일을 리눅스 환경의 공유폴더로 복사를 한 후에, 다음과 같은 Manage License 페이지에서 Load License를 클릭한 후에 해당 파일을 등록하면 정상적으로 라이센스가 등록이 된다.

 

다음과 같이 Feature  항목의 webPACK이 Permanent로 변경이 되어 있으면 정상적으로 등록이 된 것이다.

 

위의 과정을 잘 거치면, 이제 ISE Design Suite S/W를 정상적으로 사용할 수가 있게 된다.

반응형

'Engineer > 소프트웨어 정보' 카테고리의 다른 글

[ISE Design Suite] Multiplexer  (0) 2022.11.20
CRC example code [TE HTU21D datasheet]  (0) 2021.02.15
[STM32] hardware SPI example code  (0) 2020.09.09
[STM32F103] delay_us 함수  (0) 2020.07.24
[STM32] Interrupt 사용하기  (0) 2020.06.24
반응형

CRC calculation 

To compute an n-bit binary CRC, line the bits representing the input in a row, and position the (n+1)-bit pattern representing the CRC's divisor (called a "polynomial") underneath the left-hand end of the row. This is first padded with zeroes corresponding to the bit length n of the CRC. If the input bit above the leftmost divisor bit is 0, do nothing. If the input bit above the leftmost divisor bit is 1, the divisor is XORed into the input (in other words, the input bit above each 1-bit in the divisor is toggled). The divisor is then shifted one bit to the right, and the process is repeated until the divisor reaches the right-hand end of the input row.

 

void crc_check(uint16_t value, uint8_t crc) {
  uint32_t polynom = 0x988000; // x^8 + x^5 + x^4 + 1
  uint32_t msb = 0x800000;
  uint32_t mask = 0xFF8000;
  uint32_t result = (uint32_t)value << 8; // Pad with zeros as specified in spec

  while (msb != 0x80) {

    // Check if msb of current value is 1 and apply XOR mask
    if (result & msb)
      result = ((result ^ polynom) & mask) | (result & ~mask);

    // Shift by one
    msb >>= 1;
    mask >>= 1;
    polynom >>= 1;
  }
}

 

polynom CRC = x^8 + x^5 + x^4 + 1 의 조합을 생각해서 polynom, msb, mask를 잘 조합하면 될 듯하다.

반응형
반응형

STM32F103 series MCU의 hardware SPI interface를 사용하기 위해서 아래와 같이 GPIO 설정이 필요로 한다.

 

STM32F103RBT6 datasheet

#define GPIO_HW_SPI            GPIOA
#define GPIO_HW_SPI_CS                  GPIO_Pin_4    // NSS PIN
#define GPIO_HW_SPI_SCLK                GPIO_Pin_5    // Clock
#define GPIO_HW_SPI_MISO                GPIO_Pin_6    // Master Input to Slave Output
#define GPIO_HW_SPI_MOSI                GPIO_Pin_7    // Master Output to Slave Input

#define HW_SPI_READ_BIT			0x80
#define HW_SPI_WRITE_BIT		0x00

/* Select hardware SPI: Chip Select pin low  */
#define HW_SPI_CS_LOW()       GPIO_ResetBits(GPIO_HW_SPI, GPIO_HW_SPI_CS)
/* Deselect hardware SPI: Chip Select pin high */
#define HW_SPI_CS_HIGH()      GPIO_SetBits(GPIO_HW_SPI, GPIO_HW_SPI_CS)

void MXM1160_HW_SPI_GPIO_Init(void){

    SPI_InitTypeDef  SPI_InitStructure;
    GPIO_InitTypeDef GPIO_InitStructure;

    /* Enable SPI1 and GPIO clocks */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_SPI1, ENABLE);

    /* Configure SPI1 pins: SCK, MISO and MOSI */
    GPIO_InitStructure.GPIO_Pin   =  GPIO_HW_SPI_SCLK | GPIO_HW_SPI_MOSI | GPIO_HW_SPI_MISO;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;
    GPIO_Init(GPIO_HW_SPI, &GPIO_InitStructure);

    /* Configure I/O for the sensor select */
    GPIO_InitStructure.GPIO_Pin   =  GPIO_HW_SPI_CS;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
    GPIO_Init(GPIO_HW_SPI, &GPIO_InitStructure);

    /* Deselect the hardware SPI : Sensor Select high */
    HW_SPI_CS_HIGH();

    /* SPI1 configuration */
    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
    SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
    SPI_InitStructure.SPI_CRCPolynomial = 1;
    SPI_Init(SPI1, &SPI_InitStructure);

    /* Enable SPI1  */
    SPI_Cmd(SPI1, ENABLE);    
}

 

위의 'SPI_InitStructure.SPI_CPOL"와 'SPI_InitStructure.SPI_CPHA'는 사용자 개발 환경과 SPI 통신을 사용하는 slave chip의 통신 모드의 Clock Plarity (CPOL), Clock Phase (CPHA)의 의해 결정되므로 개별적으로 확인하길 바란다.

 

그 다음에 SPI 통신은 양방향 통신이기 때문에 Read / Write command에 따라 dummy byte 등 적절한 array index 관리를 해주면 된다.

 

void  HW_SPI_Multi_TXRX(uint8_t Cmd, uint8_t addr, uint8_t count, uint8_t  *pData)
{
    uint8_t BufferSize = count;
    uint8_t SPI_Dummy_Tx = 0x00;
    uint8_t SPI_Dummy_Rx = 0x00;
	
    // Check the Command mode and Address
    SPI_Dummy_Tx = Cmd | addr;

    HW_SPI_CS_LOW();

    /* Wait for SPIy Tx buffer empty */
    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
    /* Send SPIy data */
    SPI_I2S_SendData(SPI1, SPI_Dummy_Tx);

    /* Wait for SPIy data reception */
    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
    /* Read SPIy received data */
    SPI_Dummy_Rx = SPI_I2S_ReceiveData(SPI1);

    while(count>1){

        /* Wait for SPIy Tx buffer empty */
        while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
        /* Send SPIy data */
        SPI_I2S_SendData(SPI1, pData[BufferSize-count]);

        /* Wait for SPIy data reception */
        while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
        /* Read SPIy received data */
        if ( Cmd == HW_SPI_READ_BIT ){
            pData[BufferSize-count] = SPI_I2S_ReceiveData(SPI1);
        }
        else{
            SPI_Dummy_Rx = SPI_I2S_ReceiveData(SPI1);
        }			
        count--;
    }

    /* Wait for SPIy Tx buffer empty */
    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
    /* Send SPIy data */
    SPI_I2S_SendData(SPI1, pData[BufferSize-count]);

    /* Wait for SPIy data reception */
    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
    /* Read SPIy received data */
    if ( Cmd == HW_SPI_READ_BIT ){
        pData[BufferSize-count] = SPI_I2S_ReceiveData(SPI1);
    }
    else{
        SPI_Dummy_Rx = SPI_I2S_ReceiveData(SPI1);
    }
		
    HW_SPI_CS_HIGH();
}

 

마지막으로 SPI 통신의 waveform grpah 관련 자료는 구글링을 하면 되므로, 검색 스킬을 발휘하길 바란다.

 

끝.

반응형
반응형

어느샌가 1us 마다 정확하게 delay 시키는 함수 및 방법이 궁금해서 아래와 같이 자료를 정리한다.

 

결과적으로 STM32F103에서 제공하는 timer interrupt event 처리로 1ms 마다 거의 정확하게 delay 함수를 사용할 수 있지만, 1us 마다 delay 함수 사용하는 것은 사용자 MCU 및 컴파일러 환경에 따라 달라지는 것을 확인할 수가 있다. 그럼에도 불구하고 거의 1us에 가깝게 GPIO toggling할 수 있는 방법을 찾고자 한다면 괜찮지 않을까?

 

구글링에서 검색되는 delay_us 함수 중에 가장 많이 검색되는 function structure는 아래와 같다.

 

void Delay_us(__IO u32 nCount)
{
    for (; nCount != 0;nCount--);
}

void Delay_us(__IO uint32_t nCount)
{
	if(nCount>1){
			uint32_t count=nCount*8-6;
			while(count--); //asm volatile("nop");
	}
	else{
		uint32_t count=2;
		while(count--); // asm volatile("nop");
	}
}

 

실험을 해보니, 굳이 번거롭게 및 제법 있어보이게(?) 어셈블러 코드 같은거 갖다 쓰는데, 나와 같이 평범한 사람들은 그냥 아래와 같은 간단한 코드를 사용하면 된다.

 

#define NOP_1   asm volatile("NOP")
#define NOP_2  NOP_1; NOP_1
#define NOP_4  NOP_2; NOP_2
#define NOP_10   NOP_4; NOP_4; NOP_2
#define NOP_20  NOP_10; NOP_10
#define NOP_40  NOP_20; NOP_20

void delay_1us(bool state){ // High & LOW

	if (state)
	{
		NOP_20;
	}

	else{
		NOP_40;
	}
}

void GPIO_Toggle(){

	GPIO_ResetBits(GPIOC, GPIO_Pin_0);
	delay_1us(LOW);
	GPIO_SetBits(GPIOC, GPIO_Pin_0);
	delay_1us(HIGH);
}

 

이클립스 개발 환경에서 default option으로 컴파일을 하고, delay_us(1)마다 GPIO toggling을 하면 아래와 같은 파형이 관찰된다. 아울러 High / Low level timing도 서로 다른 것도 확인할 수가 있다.

 

그래서 정확하게 delay_us(1) 마다 GPIO toggling을 하는 방법은 아래와 같이, 컴파일 옵션 중에 Optimization Level을 "Optimize size (-Os)"를 선택하고 컴파일을 하면 다음과 같은 파형(High 및 LOW)을 얻을 수가 있다.

 

반응형

+ Recent posts