Ubuntu 18.04(Bionic) does not support arm-none-eabi-gdb. 

However, we can use gdb-multiarch for remote debugging

 

Installation

$ sudo apt-get install gdb-multiarch

 

Run & attach

$ gdb-multiarch
(gdb) set arc arm
(gdb) symbol-file <path_to_vmlinux>
(gdb) target remote localhost:7000

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

Linux kernel module compile from linux source  (0) 2019.01.17
Kernel module programming  (0) 2018.05.23
Kernel Version Check  (0) 2018.05.23
Kernel 프로그래밍 - printk  (0) 2017.06.20
module example_a_m_axi_buffer
#(parameter
    MEM_STYLE  = "block",
    DATA_WIDTH = 32,
    ADDR_WIDTH = 5,
    DEPTH      = 32
) (
    // system signal
    input  wire                  clk,
    input  wire                  reset,
    input  wire                  sclk_en,

    // write
    output wire                  if_full_n,
    input  wire                  if_write_ce,
    input  wire                  if_write,
    input  wire [DATA_WIDTH-1:0] if_din,

    // read
    output wire                  if_empty_n,
    input  wire                  if_read_ce,
    input  wire                  if_read,
    output wire [DATA_WIDTH-1:0] if_dout
);
//------------------------Parameter----------------------

//------------------------Local signal-------------------
(* ram_style = MEM_STYLE *)
reg  [DATA_WIDTH-1:0] mem[0:DEPTH-1];
reg  [DATA_WIDTH-1:0] q_buf = 1'b0;
reg  [ADDR_WIDTH-1:0] waddr = 1'b0;
reg  [ADDR_WIDTH-1:0] raddr = 1'b0;
wire [ADDR_WIDTH-1:0] wnext;
wire [ADDR_WIDTH-1:0] rnext;
wire                  push;
wire                  pop;
reg  [ADDR_WIDTH-1:0] usedw = 1'b0;
reg                   full_n = 1'b1;
reg                   empty_n = 1'b0;
reg  [DATA_WIDTH-1:0] q_tmp = 1'b0;
reg                   show_ahead = 1'b0;
reg  [DATA_WIDTH-1:0] dout_buf = 1'b0;
reg                   dout_valid = 1'b0;


//------------------------Instantiation------------------

//------------------------Task and function--------------

//------------------------Body---------------------------
assign if_full_n  = full_n;
assign if_empty_n = dout_valid;
assign if_dout    = dout_buf;
assign push       = full_n & if_write_ce & if_write;
assign pop        = empty_n & if_read_ce & (~dout_valid | if_read);
assign wnext      = !push                ? waddr :
                    (waddr == DEPTH - 1) ? 1'b0  :
                    waddr + 1'b1;
assign rnext      = !pop                 ? raddr :
                    (raddr == DEPTH - 1) ? 1'b0  :
                    raddr + 1'b1;

// waddr
always @(posedge clk) begin
    if (reset == 1'b1)
        waddr <= 1'b0;
    else if (sclk_en)
        waddr <= wnext;
end

// raddr
always @(posedge clk) begin
    if (reset == 1'b1)
        raddr <= 1'b0;
    else if (sclk_en)
        raddr <= rnext;
end

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

// full_n
always @(posedge clk) begin
    if (reset == 1'b1)
        full_n <= 1'b1;
    else if (sclk_en)
        if (push & ~pop)
            full_n <= (usedw != DEPTH - 1);
        else if (~push & pop)
            full_n <= 1'b1;
end

// empty_n
always @(posedge clk) begin
    if (reset == 1'b1)
        empty_n <= 1'b0;
    else if (sclk_en)
        if (push & ~pop)
            empty_n <= 1'b1;
        else if (~push & pop)
            empty_n <= (usedw != 1'b1);
end

// mem
always @(posedge clk) begin
    if (push)
        mem[waddr] <= if_din;
end

// q_buf
always @(posedge clk) begin
    q_buf <= mem[rnext];
end

// q_tmp
always @(posedge clk) begin
    if (reset == 1'b1)
        q_tmp <= 1'b0;
    else if (sclk_en)
        if (push)
            q_tmp <= if_din;
end

// show_ahead
always @(posedge clk) begin
    if (reset == 1'b1)
        show_ahead <= 1'b0;
    else if (sclk_en)
        if (push && usedw == pop)
            show_ahead <= 1'b1;
        else
            show_ahead <= 1'b0;
end

// dout_buf
always @(posedge clk) begin
    if (reset == 1'b1)
        dout_buf <= 1'b0;
    else if (sclk_en)
        if (pop)
            dout_buf <= show_ahead? q_tmp : q_buf;
end

// dout_valid
always @(posedge clk) begin
    if (reset == 1'b1)
        dout_valid <= 1'b0;
    else if (sclk_en)
        if (pop)
            dout_valid <= 1'b1;
        else if (if_read_ce & if_read)
            dout_valid <= 1'b0;
end

endmodule

code is generated from Xilinx Vivado HLS

 

full_n : queue is not full which means enqueuing is available

empty_n : queue is not empty which means pop is available

 

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

Verilog log2 function  (0) 2020.02.13
AXI FIFO  (0) 2020.02.13
AXI Register Slice  (0) 2020.02.12
Verilog Generate  (2) 2018.07.05
Xilinx bootgen  (0) 2017.06.21

1. Compilation for GDB

Compile with -g flag

 

2. Run GDB

 -  Run a program with gdb

$ gdb <program>

 - Attach a running program with gdb

$ gdb
(gdb)attach <pid>

 - Run a program and a core with gdb

$ gdb <program> <core_file>

 

3. GDB commands

 - quit / q: quit GDB

 - run / r: run from start

 - break / b <location>: set a break point

 - watch <variable>: set a watch point

 - step / s: run a step

 - next / n: run next

 - continue / c: continue to the next break point

 - info break / locals / args: print the information of breakpoints / local variables / arguments for stack frame function

 - print <variable / pointer / function>: print the value of variable / address of pointer / address of function

 - list: print 10 lines of current source code

* location = file_name:function_name | file_name:line_number | class::function_name

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

PCI device rescan  (0) 2022.09.25
Piping ls to cp  (0) 2020.12.02
PhantomJS Installation on Ubuntu from source  (0) 2018.12.10
Linux screen  (0) 2018.09.27
Xshell + Xming  (0) 2018.09.10
function integer log2;
    input integer x;
    integer n, m;
begin
    n = 0;
    m = 1;
    while (m < x) begin
        n = n + 1;
        m = m * 2;
    end
    log2 = n;
end
endfunction

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

AXI Buffer  (1) 2020.04.04
AXI FIFO  (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_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

+ Recent posts