pythonバイナリデータを扱う①

pythonでバイナリデータを2進数にした後、いろいろ操作する方法をまとめてみた。 いろいろ操作した後にバイナリデータや整数に変換する方針にしている。正しいのかな?

import sys

def main():
    binary_data = b'\x08'
    # binary_data = b'\x48\x65\x6c\x6c\x6f'
    data = int.from_bytes(binary_data, sys.byteorder)
    binary_num = to_binary_number(data,10)
    binary_num = bit_slice(binary_num,4,2)
    print (binary_num)
    binary_num += create_0(5)
    print (binary_num)

def to_binary_number(data,bit_width):
    binary_number = format(data,"0"+str(bit_width)+"b")
    return binary_number

def create_0(num):
    return str("0"*int(num))

def bit_slice(binary_num,msb,lsb):
    data_len = len(binary_num)
    if data_len < msb+1:
        print ("[    ERROR    ] msb is bigger than binary_num width")
        return -1
    if msb < lsb:
        print ("[    ERROR    ] msb is less than lsb")
        return -1
    first_pos = data_len - msb - 1
    last_pos = data_len - lsb - 1
    return binary_num[first_pos:last_pos+1]

if __name__ == "__main__":
    main()

openpyxlを使ってみた②

こちらは本体。入力データと出力データそれぞれ、選ばれた時用と選ばれてない時用の2種類、計4種類(2×2)を準備する。

その後、1つのテストの設定にする。

#test.py

import openpyxl
from common_function import get_position_from_ws
from common_function import get_port_data_list
from common_function import peer_to_peer

hsize = 320 
vsize = 240 

base_port_row    =0  
base_port_column =0

in_select_list     = []
in_no_select_list  = []
in_color_list      = []
out_select_list    = []
out_no_select_list = []
out_color_list     = []

wb = openpyxl.load_workbook(filename = 'sample_1.xlsx',data_only=True)
ws = wb.active

base_port_row,base_port_column     = get_position_from_ws(ws,target_chr="port")

#                     [port name,sel_number,color,file name,  bit width,reserve,hsize,vsize]
# in_select_list    : [port_name,sel_number,1,    file_name,  bit_width,1,      hsize,vsize]
# in_no_select_list : [port_name,sel_number,0,    "empty.bin",bit_width,1,      0,    0    ]
in_select_list, in_no_select_list  = get_port_data_list("in", ws,base_port_row,base_port_column,hsize,vsize)

#                      [port name,reg name,color,file name,bit width,reserve,hsize,vsize]
# out_select_list    : [port_name,reg_name,1,    file_name,bit_width,1,      hsize,vsize]
# out_no_select_list : [port_name,reg_name,0,    file_name,bit_width,1,      0,    0    ]
out_select_list, out_no_select_list = get_port_data_list("out",ws,base_port_row,base_port_column,hsize,vsize)

#peer to peer
data_testlist,color_testlist = peer_to_peer(ws,base_port_row,base_port_column,in_no_select_list,in_select_list,out_no_select_list,out_select_list)
print (data_testlist)
print (color_testlist)
#common_function.py

def to_bit_width(char_bit_width_raw):
    data = char_bit_width_raw.replace('[','').replace(']','')
    f_pos = data.find(':')
    return int(data[:f_pos])+1

def get_position_from_ws(ws,target_chr):
    for test in ws: 
        for data in test:
            if data.value == str(target_chr) :
               return data.row, data.column

def get_port_data_list(port_is,ws,base_port_row,base_port_column,hsize,vsize):
    select_list    = []
    no_select_list = []
    if (port_is == "in"):
        for i in range(base_port_row+1,ws.max_row+1):
            sel_number =              ws.cell(i,base_port_column-2).value
            bit_width  = to_bit_width(ws.cell(i,base_port_column-1).value)
            port_name  =              ws.cell(i,base_port_column-0).value
            file_name  = port_name + ".bin"
                         #port name,sel_number,color,file name,  bit width,reserve,hsize,vsize
            select     = [port_name,sel_number,1,    file_name,  bit_width,1,      hsize,vsize]
            no_select  = [port_name,sel_number,0,    "empty.bin",bit_width,1,      0,    0    ]   
            select_list.append    (select)
            no_select_list.append (no_select)

    if (port_is == "out"):
        for i in range(base_port_column+1,ws.max_column+1):
            reg_name  =              ws.cell(base_port_row-2,i).value
            bit_width = to_bit_width(ws.cell(base_port_row-1,i).value)
            port_name =              ws.cell(base_port_row-0,i).value
            file_name = port_name + ".bin"
                        #port name,reg name,color,file name,bit width,reserve,hsize,vsize
            select    = [port_name,reg_name,1,    file_name,bit_width,1,      hsize,vsize]
            no_select = [port_name,reg_name,0,    file_name,bit_width,1,      0,    0    ]   
            select_list.append    (select)
            no_select_list.append (no_select)
    return select_list, no_select_list
def peer_to_peer(ws,base_port_row, base_port_column, in_no_select_list, in_select_list, out_no_select_list, out_select_list):
    data_testlist  = []
    color_testlist = []
    test_num = 0
    in_num = 0
    for i in range(base_port_row+1,ws.max_row):
        out_num = 0
        temp_in_list          = in_no_select_list.copy()
        temp_in_list[in_num]  = in_select_list[in_num]
        in_color_list         = len(temp_in_list) * [len(temp_in_list[0])* [0]]
        in_color_list[in_num] = [0,0,0,1,1]
        sel_number            = temp_in_list[in_num][1]

        for j in range(base_port_column+1,ws.max_column):
            if ws.cell(i,j).value is not None:
                temp_out_list           = out_no_select_list.copy()
                temp_out_list[out_num]  = out_select_list[out_num]
                out_color_list          = len(temp_out_list) * [len(temp_out_list[0])* [0]]
                out_color_list[out_num] = [0,0,0,1,1]
                temp_reg_list           = len(temp_out_list) * [0]
                temp_reg_list[out_num]  = sel_number
                reg_color_list          = len(temp_reg_list) * [0]
                reg_color_list[out_num] = 1

                in_name_for_testlist  = [data[0] for data in temp_in_list ]
                out_name_for_testlist = [data[0] for data in temp_out_list]
                reg_name_for_testlist = [data[1] for data in temp_out_list]
                in_data_for_testlist  = [data for test in temp_in_list  for data in test[3:8]]
                out_data_for_testlist = [data for test in temp_out_list for data in test[3:8]]
                reg_data_for_testlist = temp_reg_list
                data_testlist.append(in_data_for_testlist + out_data_for_testlist + [""] + reg_data_for_testlist)

                in_color_for_testlist  = [x for color in in_color_list  for x in color]
                out_color_for_testlist = [x for color in out_color_list for x in color]
                reg_color_for_testlist = reg_color_list
                color_testlist.append(in_color_for_testlist + out_color_for_testlist + [""] + reg_color_for_testlist)
                test_num += 1
            out_num += 1 
    return data_testlist, color_testlist

openpyxlを使ってみた①

openpyxlを使ってみた。整理できていないけど、参考として記載。

import openpyxl

base_port_row    =0
base_port_column =0
wb = openpyxl.load_workbook(filename = 'sample_1.xlsx')
ws = wb.active

#test_list = [[input_1,infile,bpp,epp,hsize,vsize],[...],]
for test in ws:
    for data in test:
        if data.value == "port" :
           base_port_row    = data.row
           base_port_column = data.column
           break

inport_no_select_list = []
inport_select_list    = []
outport_no_select_list = []
outport_select_list    = []
regport_no_select_list = []
for i in range(base_port_row+1,ws.max_row+1):
    sel_num     = ws.cell(i,base_port_column-2).value
    bit_wid     = ws.cell(i,base_port_column-1).value
    port_name   = ws.cell(i,base_port_column-0).value
    file_name   = str(ws.cell(i,base_port_column-0).value) + ".bin"
    inport_select_list.append   ([port_name,file_name,  bit_wid,1,320,240,sel_num])
    inport_no_select_list.append([port_name,"empty.bin",bit_wid,1,320,240,sel_num])

for i in range(base_port_column+1,ws.max_column+1):
    reg_name    = ws.cell(base_port_row-2,i).value
    bit_wid     = ws.cell(base_port_row-1,i).value
    port_name   = ws.cell(base_port_row-0,i).value
    file_name   = str(ws.cell(base_port_row-0,i).value) + ".bin"
    outport_no_select_list.append([port_name,file_name,bit_wid,1,320,240,reg_name])
    outport_select_list.append   ([port_name,file_name,bit_wid,1,320,240,reg_name])
    regport_no_select_list.append([reg_name,0])

#peer to peer
test_list = []
input_num = 0
for i in range(base_port_row+1,ws.max_row):
    temp_in_list            = inport_no_select_list.copy()
    temp_in_list[input_num] = inport_select_list[input_num]

    output_num = 0
    for j in range(base_port_column+1,ws.max_column):
        if ws.cell(i,j).value is not None:
            temp_out_list                = outport_no_select_list.copy()
            temp_out_list[output_num]    = outport_select_list[output_num]

            temp_reg_list                = regport_no_select_list.copy()
            temp_reg_list[output_num][1] = temp_in_list[input_num][6]

            test_list.append(temp_in_list + temp_out_list + temp_reg_list)
        output_num += 1
    input_num += 1
print (test_list[0])

python ライブラリreを使った例①

pythonで、正規表現を使って文字を抜き取りたいと思って作成した。 自分用のメモ書きです。

import re

text    = "*[13:0]*[23:14]*[25:24]"
pattern = r'\*\[(\d+:\d+)\]'
matches = re.findall(pattern,text)
numbers = []

for match in matches:
    start,end = match.split(':')
    numbers.append([int(start),int(end)])
print (numbers)

【verilog】内部信号をモニタする2

便利なモニタ用のモジュールを作成中。今回はシンプルな2つのデータを常時監視するモニタを作成しました。

このモニタは、bindでdutの内部にインスタンス化することを想定しています。内部信号をモニタに接続して、CSVファイルに格納します。

CSVファイルに格納する意図は、波形を目視して確認しないため。 リファレンスモデル側でも同じようにファイル出力ができれば、diffで差分比較ができます。

// monitor.v

module monitor#(
    parameter p_width_data1     =4,
    parameter p_width_data2     =8,
    parameter p_dly_cycle_data1 =0,
    parameter p_dly_cycle_data2 =1,
    parameter output_file_name  ="test_output.csv",
    parameter data1_name        ="data1",
    parameter data2_name        ="data2"
) (
    input                     clk,
    input                     rst,
    input [p_width_data1-1:0] data1,
    input [p_width_data2-1:0] data2
);
    integer fp; 
    logic [p_width_data1-1:0] queue_data1[$];
    logic [p_width_data2-1:0] queue_data2[$];
    logic [p_width_data1-1:0] print_data1;
    logic [p_width_data2-1:0] print_data2;

    //Set up output file
    initial begin
        fp = $fopen(output_file_name);
        $fdisplay(fp,"monitor %s and %s",data1_name,data2_name);
    end 

    //monitor
    always@(posedge clk or negedge rst)begin
        queue_data1.push_front(data1);
        queue_data2.push_front(data2);
        if(queue_data1.size() >= p_dly_cycle_data2-p_dly_cycle_data1+1)begin
            print_data1 = queue_data1.pop_back;
        end
        if(queue_data2.size() >= p_dly_cycle_data1-p_dly_cycle_data2+1)begin
            print_data2 = queue_data2.pop_back;
        end

        if(print_data1 !== {p_width_data1{1'bX}} && print_data2 !== {p_width_data2{1'bX}})begin
            $fwrite(fp,"%t,%h,%h\n",$realtime,print_data1,print_data2);
        end
    end 
endmodule
module tb_top();
・・・


bind dut monitor #(
    .p_width_data1(4),
    .p_width_data2(8),
    .p_dly_cycle_data1(0),
    .p_dly_cycle_data2(1),
    .output_file_name("output_1.csv"),
    .data1_name("add"),
    .data2_name("rdata_r")
)u_monitor_1(
    .clk(clk),
    .rst(rst_n),
    .data1(add),
    .data2(rdata_r)
);

endmodule

【verilog】bindを使ってdutをモニターする

verilogのデータをモニターして結果をcsvファイルにダンプしようと思った。 データを取得開始するタイミングは、if($realtime >= 時間)で行うようにした。

module dut(
input        clk,
input        rst_n,
input  [3:0] add,
input        we,
input  [7:0] wdata,
output [7:0] rdata
);
    reg [7:0] array [0:15];
    reg [4:0] i;
    reg [7:0] rdata_r;

    initial begin
        for (i=0; i<=15; i=i+1)begin
            array[i] = 8'h0;
        end
    end
    
    always@(posedge clk or negedge rst_n)begin
        if(we)begin
            array[add] <= wdata;
            rdata_r <= array[add];
        end
    end
    assign rdata = rdata_r;

endmodule
module top(
・
・
・

bind dut monitor u_monitor(.*);

endmodule

module monitor (
    input clk,
    input rst_n,
    input we,
    input [3:0] add,
    input [7:0] rdata_r
);
    //monitor
    integer fp;
    logic [3:0] add_1dly;
    int cnt_x=0;
    int cnt_y=0;
    initial begin
        fp = $fopen("data_1.csv");
        $fdisplay(fp,"Output data monitor,");
    end
    always@(posedge clk or negedge rst_n)begin
        add_1dly <= add;
        if($realtime >= 3.5us && $realtime <= 16.1us)begin
            $fdisplay(fp,"%t,%d,%d,%h,%h",$realtime,cnt_x,cnt_y,add_1dly,rdata_r);
            if (cnt_x == 15)begin
                cnt_x = 0;
                cnt_y +=1;
            end
            else begin
                cnt_x +=1;
            end
        end
    end
endmodule

【c言語】画像データをモニターする

verilogの検証時に、c言語でリファレンスモデルを作成する場合がある。 出力データが、verilogとリファレンスモデルで合わない時に、それぞれの内部の信号を確認する必要が出てくる。

その時に、いちいち内部信号用のprintf文を書いていると、時間がかかるし目視で確認するのは大変。 そこで、fprintfを使って、csvファイルにデータを書き込むmonitorを作成してみた。

//monitor.h

#ifndef __MONITOR_H__
#define __MONITOR_H__

#include "stdio.h"

typedef struct{
    FILE      *fp;
    int       x;
    int       y;
    int       pos_start_x;
    int       pos_end_x;
    int       pos_start_y;
    int       pos_end_y;
    long long data[5];
} S_TARGET_DATA;

extern void monitor_init (S_TARGET_DATA *p);
extern void monitor_write(S_TARGET_DATA *p);
extern void monitor_close(S_TARGET_DATA *p);
#endif
//monitor.c

#include "monitor.h"

void monitor_init(S_TARGET_DATA *p){
    printf("Hello init.\n");

    fprintf(p->fp,"Output image monitor\n");
    fprintf(p->fp,",x,y,data_upper2,data_upper1,data_center,data_down1,data_down2\n");
}

void monitor_write(S_TARGET_DATA *p){
    if (p->x >= p->pos_start_x && p->x <= p->pos_end_x && p->y >= p->pos_start_y && p->y <= p->pos_end_y){
        fprintf(p->fp,",%d,%d,",p->x,p->y);
        int data_kind = sizeof(p->data)/sizeof(p->data[0]);
        int i;
        for (i=0;i<data_kind;i++){
            fprintf(p->fp,"0x%llx,", p->data[i]);
        }
        fprintf(p->fp,"\n");
    }
}

void monitor_close(S_TARGET_DATA *p){
    fclose(p->fp);
}
//main.c 
#include "stdio.h"
#include "../monitor/monitor.h"

#define IMAGE_WIDTH  512
#define IMAGE_HEIGHT 512

void main(void) {
    FILE * fp_rgb1 = NULL;
    long long data_u2 = 0;
    long long data_u1 = 0;
    long long data_c  = 0;
    long long data_d1 = 0;
    long long data_d2 = 0;
    int x,y;

    //DEBUG::set parm for monitor 1//////////////////
    S_TARGET_DATA data1;
    data1.fp          = fopen("data_rgb1.csv","w");
    data1.pos_start_x = 0;
    data1.pos_start_y = 0;
    data1.pos_end_x   = 511;
    data1.pos_end_y   = 0;
    monitor_init(&data1);
    /////////////////////////////////////////////////
    //DEBUG::set parm for monitor 2//////////////////
    S_TARGET_DATA data2;
    data2.fp          = fopen("data_rgb2.csv","w");
    data2.pos_start_x = 0;
    data2.pos_start_y = 0;
    data2.pos_end_x   = 510;
    data2.pos_end_y   = 0;
    monitor_init(&data2);
    /////////////////////////////////////////////////

    for (y=0;y<IMAGE_HEIGHT;y++){
        for (x=0;x<IMAGE_WIDTH;x++){
            data_u2 += 1;   //データ1と過程
            data_u1 += 2;   //データ2と過程
            data_c  += 4;    //データ3と過程
            data_d1 += 8;   //データ4と過程
            data_d2 += 16; //データ5と過程

            //DEBUG::set data to monitor 1///
            data1.x       = x;
            data1.y       = y;
            data1.data[0] = data_u2;
            data1.data[1] = data_u1;
            data1.data[2] = data_c ;
            data1.data[3] = data_d1;
            data1.data[4] = data_d2;
            monitor_write(&data1);
            /////////////////////////////////
            //DEBUG::set data to monitor 2///
            data2.x       = x;
            data2.y       = y;
            data2.data[0] = data_u2;
            data2.data[1] = data_u1;
            data2.data[2] = data_c ;
            data2.data[3] = data_d1;
            data2.data[4] = data_d2;
            monitor_write(&data2);
            /////////////////////////////////
        }
    }
    //DEBUG::close monitor 1////
    monitor_close(&data1);
    ////////////////////////////
    //DEBUG::close monitor 2////
    monitor_close(&data2);
    ////////////////////////////
}