module example_a_m_axi_fifo
#(parameter
    DATA_BITS  = 8,
    DEPTH      = 16,
    DEPTH_BITS = 4
)(
    input  wire                 sclk,
    input  wire                 reset,
    input  wire                 sclk_en,
    output reg                  empty_n,
    output reg                  full_n,
    input  wire                 rdreq,
    input  wire                 wrreq,
    output reg  [DATA_BITS-1:0] q,
    input  wire [DATA_BITS-1:0] data
);
//------------------------Parameter----------------------

//------------------------Local signal-------------------
wire                  push;
wire                  pop;
wire                  full_cond;
reg                   data_vld;
reg  [DEPTH_BITS-1:0] pout;
reg  [DATA_BITS-1:0]  mem[0:DEPTH-1];
//------------------------Body---------------------------
assign push = full_n & wrreq;
assign pop  = data_vld & (~(empty_n & ~rdreq));
if (DEPTH >= 2) begin
assign full_cond = push && ~pop && pout == DEPTH - 2 && data_vld;
end else begin
assign full_cond = push && ~pop;
end

// q
always @(posedge sclk)
begin
    if (reset)
        q <= 0;
    else if (sclk_en) begin
        if (~(empty_n & ~rdreq))
            q <= mem[pout];
    end
end

// empty_n
always @(posedge sclk)
begin
    if (reset)
        empty_n <= 1'b0;
    else if (sclk_en) begin
        if (~(empty_n & ~rdreq))
            empty_n <= data_vld;
    end
end

// data_vld
always @(posedge sclk)
begin
    if (reset)
        data_vld <= 1'b0;
    else if (sclk_en) begin
        if (push)
            data_vld <= 1'b1;
        else if (~push && pop && pout == 1'b0)
            data_vld <= 1'b0;
    end
end

// full_n
always @(posedge sclk)
begin
    if (reset)
        full_n <= 1'b1;
    else if (sclk_en) begin
        if (pop)
            full_n <= 1'b1;
        else if (full_cond)
            full_n <= 1'b0;
    end
end

// pout
always @(posedge sclk)
begin
    if (reset)
        pout <= 1'b0;
    else if (sclk_en) begin
        if (push & ~pop & data_vld)
            pout <= pout + 1'b1;
        else if (~push && pop && pout != 1'b0)
            pout <= pout - 1'b1;
    end
end

integer i;
always @(posedge sclk)
begin
    if (sclk_en) begin
        if (push) begin
            for (i = 0; i < DEPTH - 1; i = i + 1) begin
                mem[i+1] <= mem[i];
            end
            mem[0] <= data;
        end
    end
end
endmodule

Code is generated from Xilinx Vivado HLS

 

full_n : FIFO queue is not full which means enqueuing is available

empty_n : FIFO queue is not empty which means output q is valid

 

'Programming > Verilog' 카테고리의 다른 글

AXI Buffer  (1) 2020.04.04
Verilog log2 function  (0) 2020.02.13
AXI Register Slice  (0) 2020.02.12
Verilog Generate  (2) 2018.07.05
Xilinx bootgen  (0) 2017.06.21
module example_a_m_axi_reg_slice
#(parameter
    N = 8   // data width
) (
    // system signals
    input  wire         sclk,
    input  wire         reset,
    // slave side
    input  wire [N-1:0] s_data,
    input  wire         s_valid,
    output wire         s_ready,
    // master side
    output wire [N-1:0] m_data,
    output wire         m_valid,
    input  wire         m_ready
);
//------------------------Parameter----------------------
// state
localparam [1:0]
    ZERO = 2'b10,
    ONE  = 2'b11,
    TWO  = 2'b01;
//------------------------Local signal-------------------
reg  [N-1:0] data_p1;
reg  [N-1:0] data_p2;
wire         load_p1;
wire         load_p2;
wire         load_p1_from_p2;
reg          s_ready_t;
reg  [1:0]   state;
reg  [1:0]   next;
//------------------------Body---------------------------
assign s_ready = s_ready_t;
assign m_data  = data_p1;
assign m_valid = state[0];

assign load_p1 = (state == ZERO && s_valid) ||
                 (state == ONE && s_valid && m_ready) ||
                 (state == TWO && m_ready);
assign load_p2 = s_valid & s_ready;
assign load_p1_from_p2 = (state == TWO);

// data_p1
always @(posedge sclk) begin
    if (load_p1) begin
        if (load_p1_from_p2)
            data_p1 <= data_p2;
        else
            data_p1 <= s_data;
    end
end

// data_p2
always @(posedge sclk) begin
    if (load_p2) data_p2 <= s_data;
end

// s_ready_t
always @(posedge sclk) begin
    if (reset)
        s_ready_t <= 1'b0;
    else if (state == ZERO)
        s_ready_t <= 1'b1;
    else if (state == ONE && next == TWO)
        s_ready_t <= 1'b0;
    else if (state == TWO && next == ONE)
        s_ready_t <= 1'b1;
end

// state
always @(posedge sclk) begin
    if (reset)
        state <= ZERO;
    else
        state <= next;
end

// next
always @(*) begin
    case (state)
        ZERO:
            if (s_valid & s_ready)
                next = ONE;
            else
                next = ZERO;
        ONE:
            if (~s_valid & m_ready)
                next = ZERO;
            else if (s_valid & ~m_ready)
                next = TWO;
            else
                next = ONE;
        TWO:
            if (m_ready)
                next = ONE;
            else
                next = TWO;
        default:
            next = ZERO;
    endcase
end

endmodule

code is generated from Xilinx Vivado HLS

 

 AXI Interface 연결 간(Interconnect 등)에 동작 Clock frequency 증가를 위한 대표적인 Logic으로 Channel 간 Handshake 사이의 일종의 Pipeline register로 동작함

'Programming > Verilog' 카테고리의 다른 글

Verilog log2 function  (0) 2020.02.13
AXI FIFO  (0) 2020.02.13
Verilog Generate  (2) 2018.07.05
Xilinx bootgen  (0) 2017.06.21
Xilinx SDK disable cache  (0) 2017.06.12

Bash script 실행 할 때, 다양한 option에 대한 argument를 넣고, parsing 하는 방법

 

#!/bin/bash

while getopts "hvf:" shortopt
do
	case $shortopt in 
    	h)
        	echo "Usage: $0 [-h] [-v] [-f file_name]"
            	echo "    -h: help"
            	echo "    -v: verbose"
            	echo "    -f filename: input file"
            	exit
            	;;
    	v)
        	VERBOSE=1
            	;;
        f)
        	FILE=$OPTARG
            	;;
        *)
        	echo "default settings"
            	;;
    esac
done

shortopt 가 OPTARG를 가지는 경우 ":"(Colon) 을 포함하고, 그외의 경우의 알파벳을 열거하여 while 문을 구성하면 된다.

'Programming > Bash Script' 카테고리의 다른 글

Bash if statement with regex  (0) 2021.09.06
Bash script for statement  (0) 2018.05.21
Bash Script case statement  (0) 2018.02.06
Bash Script Variable Split by Space  (0) 2018.02.04
Bash Script Echo  (0) 2018.02.04

2019.11.19 기준 Rasbian 의 최신 버전은 Debian Buster 기반으로 되어있다. 따라서, Rasbian에 qbittorrent-nox 를 설치하고자 하는 경우 add-apt-repository 명령으로 repository를 추가하고자 하면 에러가 발생한다.

따라서 Debian 홈페이지로 부터 qbittorrent-nox deb 파일을 다운받아 설치하면 된다.

라즈베리파이3의 경우 armhf 아키텍쳐 용을 라즈베리파이4의 경우 arm64 아키텍쳐 용을 다운받아 설치 하면 될 것이다.

설치 명령어는 다음과 같다.

$ sudo dpkg -i <downloaded_deb_file>

 

설치 후 Service 등록 등은 Github 설명 참조.

 

'Programming > RaspberryPi' 카테고리의 다른 글

Install Nextcloud on RaspberryPi  (0) 2023.03.15
Install Owncloud on RaspberryPi  (0) 2023.03.15
SD card image backup  (0) 2018.10.12
SDcard Partition Resize  (0) 2018.08.21
RaspberryPi Remote Desktop Client  (0) 2018.06.01

FPGA 같은 하드웨어를 사용하다보면, 가끔 데이터가 꼬일 때, Endianness 문제일 까 싶을 때가 있다.

간단한 C 코드를 통해 System의 Endianness 를 확인 할 수 있다.

 

예 1) 전처리기 활용

#if __BYTE_ORDER == __LITTLE_ENDIAN
	printf("Little Endian\n");
#elif __BYTE_ORDER == __BIG_ENDIAN
	printf("Big Endian\n");

예 2) Pointer 활용

int x = 1;
char* cp = &x;

if(*cp == 1){
	printf("Little Endian\n");
}
else{
	printf("Big Endian\n");
}

 

'Programming > C Language' 카테고리의 다른 글

C progress printing  (0) 2018.08.07
static  (0) 2018.07.13
가변 인자(variable arguments) stdarg.h  (0) 2017.12.11
extern  (0) 2017.06.21
static  (0) 2017.06.20

Hierarchy of the DRAM Subsystem

Every channel has its own memory controller that means it has its own address, command, and data bus.

In a rank, the address and command bus are shared to all chips, but the data bus is dedicated to a chip. Therefore the rank can offer a wide interface.

In a chip, all of the address, command, and data bus are shared to banks. However, in each bank, the address, command, and data are latched, and each bank operates its own command.

A column can be accessed when a row is open(activated).

 

DRAM Operation

DRAM Operation starts with row activation. Activating a row means select and open a row of DRAM cells in a specific bank and then the data could be accessed through row buffer(which is also called sense amplifier) in size of a column. When accessing a row is finished then, the row should be precharged(closed) for activating another row. 

The most critical timing parameters of DRAM are tRCD, tCL, tRP. tRCD stands for RAS to CAS delay time which means activating a row is finished and the row is ready to read or write, after tRCD from the ACT(Activation) command. Once RD(Read) or WR(Write) command, data could be transferred after tCL. And when accessing a row is finished, the PRE(Precharge) command should be followed. Precharging a row takes tRP. 

Because the row address is transferred with ACT command and the column address is transferred with RD/WR, which means that row and column address are not used simultaneously, address pins could be shared. 

 

DRAM Bank Structure

DRAM Bank is a set of rows and columns, which operates a command. A DRAM chip consists of multiple banks, and each bank could operate its own command. However, the command, address, data pins are shared to all of the banks, and all of DRAM commands are synchronized, DRAM operations could be pipelined. With pipelining, bank structure is good for hiding long latency of DRAM(tRCD, tCL, tRP, etc).

This is a logical structure of a DRAM Bank. All of the pin counts are referenced from Micron DDR4 8Gb X8 DRAM Chip. In this case, a DRAM bank consists of 64K rows and 1K columns. This chip has 8 bit of data pin, generally, 8 of chips are combined into a DIMM. With 8 chips, each of 8 data pins, and 8 burst length, 64Byte of data could be read or write at single DRAM command. Row buffer size is 8Kb for each chip. 

This is a functional block diagram from Micron DDR4 8Gb X8 DRAM chip. Note that it is a chip. Because DDR4 uses 8 burst length, it seems that 64 bit of data in the row buffer could be transferred to FIFO, in a operation. The LSB 3 bits of column address are discarded, and 8 columns, each of 8 bits are accessed at once.

'Programming > Computer Architecture' 카테고리의 다른 글

Cache write policies  (0) 2022.10.31

일반적인 Linux 배포판을 쓰지 않고, Kernel source와 Root file system 으로 부터 Linux system 을 구성한 경우,

Linux runtime 에 kernel module을 compile 하여 insmod/rmmod 를 할 수 있다.


Kernel module을 컴파일 하기 위해서는 현재 Linux system 에서 사용되고 있는 kernel source를 필요로 한다.

일반적인 방법과 유사하게 사용하기 위해

kernel source 를 /usr/src 디렉토리에 위치시키고,

/lib/modules/<kernel_version>/build 와 symbolic link 시킨다.

# cd /lib/modules/<kernel_version>

# ln -s /usr/src/<kernel_source_dir> build

커널 모듈을 컴파일 하기 위한 준비 작업은 아래 와 같다.

# cd /usr/src/<kernel_source_dir>

# make <defconfig>

# make prepare

# make scripts

※ 참조: http://www.fun25.co.kr/blog/linux-ubuntu-14-04-kernel-module-compile


kernel module을 컴파일 할 Makefile은 아래와 같이 구성한다.

obj-m := test_module.o


all:

make -C /lib/modules/<kernel_version>/build M=$(PWD) modules

clean:

make -C /lib/modules/<kernel_version>/build M=$(PWD) clean

아래는 테스트를 위한 기본적인 kernel module source code.

#include <linux/module.h>

#include <linux/kernel.h>


int init_module(void){

printk(KERN_ALERT"Hello"\n);

return 0;

}


void cleanup_module(void){

printk(KERN_ALERT"Bye"\n);

}


kernel module을 컴파일 하고, insmod/rmmod 를 통해 test 한다.

# make

# insmod <kernel_module>.ko

# rmmod <kernel_module>.ko

※ 이 때, 현재 Linux system 에서 사용되는 kernel 과 다른 source로 부터 kernel module을 컴파일 하게 되면 version 차이로 오류가 나타난다.

'Programming > Linux Kernel' 카테고리의 다른 글

cross kernel debugging  (0) 2020.06.19
Kernel module programming  (0) 2018.05.23
Kernel Version Check  (0) 2018.05.23
Kernel 프로그래밍 - printk  (0) 2017.06.20

Ubuntu 에서 Headless browser 인 PhantomJS를 설치하는 방법을 소개한다.


PhantomJS는 기본적으로 Multi platform 을 지원하여, Windows, Linux, FreeBSD 등 다양한 OS 상에서 구동 될 수 있다.

Architecture / OS 에 따라 기본적으로 제공되는 파일을 사용하여 설치 할 수 없는 경우

Github 로 부터 source code를 다운 받아 설치 할 수 있다.


PhantomJS에서 필요한 패키지(Qt, WebKit 등)를 자동으로 설치 하기 떄문에 Dependency가 없다고 하지만,

Ruby, gperf 등 일부 패키지를 설치 하지 않으면 install 도중 Error를 맞이하게 된다.


Prerequisites

1. Ruby Installation

Ruby install은 RVM(Ruby Version Manager)를 통해 할 수 있다. 따라서, Ruby install 을 위한 RVM install 이 필요하다. 

gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3

$ cd /tmp && \curl -sSL https://get.rvm.io -o rvm.sh

$ cat /tmp/rvm.sh | bash -s stable

*참조: https://www.rosehosting.com/blog/install-ruby-on-rails-on-ubuntu-16-04/

RVM이 설치 되면, Ruby를 설치 할 수 있다. 


RVM 실행

$ source /usr/local/rvm/scripts/rvm


RVM에서 설치 가능한 Ruby version 확인

$ rvm list known


Ruby 설치(stable 최신 버전 2.5.1, 2018.12.10 기준)

$ rvm install 2.5.1


2. Gperf Installation

$ sudo apt-get install gperf


Git source Fetch

$ git clone https://github.com/ariya/phantomjs


PhantomJS Installation from source

$ cd phantomjs

$ ./build.py 

(시간이 꽤 걸린다.)

'Programming > Linux' 카테고리의 다른 글

Piping ls to cp  (0) 2020.12.02
How to use GDB  (0) 2020.03.12
Linux screen  (0) 2018.09.27
Xshell + Xming  (0) 2018.09.10
Memtester  (0) 2018.07.15

라즈비안이 들어있는 SD 카드를 이미지로 백업하고 싶은 경우 

Win 32 Disk Imager 로 백업 이미지를 만들 수 있다.


방법은 간단하다.

1. Win 32 Disk Imager 설치

2. Backup 할 SD 카드를 꼽고

3. Win 32 Disk Imager 에서 Backup 할 Drive를 선택 + output Image 가 될 파일을 지정

※ 파티션이 여러개 여서, 여러 개의 Drive로 보이더라도, Linux File system 이라 윈도우에서 안보이는 경우여도 첫 번째 파티션을 선택하면 전체 백업 된다.

4. Read


백업된 이미지를 다시 SD 카드에 쓰기위해서는

1. Win 32 Disk Imager 에서 Backup 된 image를 선택 + Drive 지정

2. Write

※ 이때, Backup 된 이미지는 기존 SD 카드의 크기를 가지기 때문에, 복원을 위해서는 기존 SD 카드의 크기보다 크거나 같은 SD 카드가 필요하며, 기존 SD 카드보다 큰 SD 카드의 경우 복원 후 resize 가 필요하다.


'Programming > RaspberryPi' 카테고리의 다른 글

Install Owncloud on RaspberryPi  (0) 2023.03.15
Rasbian qbittorrent-nox installation  (0) 2019.11.19
SDcard Partition Resize  (0) 2018.08.21
RaspberryPi Remote Desktop Client  (0) 2018.06.01
Raspbian Korean(Hangul) Install  (0) 2018.05.18

Linux 명령어 중에 Shell 접속이 끊어지더라도, 프로세스를 죽이지 않기 위해 screen 을 사용할 수 있다.


screen 은 가상의 shell을 담당하여, 실제 shell의 접속 여부와 상관없이 프로세스를 계속적으로 진행하게 해준다.


초간단 사용법

1. 스크린 생성

$ screen

screen 명령어에 아무런 옵션이 없는 경우 임의의 이름을 가지는 screen을 생성한다.

이름을 지정하기 위해서는 screen -S <NAME> 과 같이 -S 옵션을 사용하면 된다.


2. Detach

screen에 접속한 상태에서 screen으로 명령을 전달하기 위해서는 ctrl+a 를 입력 한 뒤에 명령을 입력해야 한다.

screen에서 접속을 해제하는 detach 명령어는 d 이다


3. List 확인

Detach 한 screen에 재접속(Reattach) 하기 위해서는 우선 해당 screen의 이름을 알거나, Process ID를 알아야 한다.

Screen의 Process ID를 확인하기 위해서는 아래와 같이 -x 옵션을 사용한다.

$ screen -x

이 때, 활성화된 screen 이 1개밖에 없는 경우, 해당 screen으로 바로 재접속(Reattach) 된다.


4. Reattach

3에서 확인한 Process ID 혹은 screen 이름으로 Reattach 하는 명령은 -r 옵션을 사용한다.

$ screen -r <Process_ID | screen_name>


5. Kill

screen에 접속한 상태에서 해당 screen을 kill 하는 명령어는 k 이다.

Kill 명령의 경우 진짜로 죽일 것인지 한 번 더 확인한다.


6. Screen for running multiple processes

Screen command option 중 -dmS 옵션을 사용하면 각 Process를 동작하는 screen을 여러개 생성할 수 있다. 프로세스가 종료되면 screen 또한 종료된다.

Bash script 와 함께 활용하면 유용하다.

#!/bin/bash


for size in 2 4 8 16 32

do

    screen -dmS screen_${size} ./test.sh ${size}

done


'Programming > Linux' 카테고리의 다른 글

How to use GDB  (0) 2020.03.12
PhantomJS Installation on Ubuntu from source  (0) 2018.12.10
Xshell + Xming  (0) 2018.09.10
Memtester  (0) 2018.07.15
Ctags  (0) 2018.07.03

+ Recent posts