VHDLのstd_logic_vectorとloopの変換

結論から書きます。この記事を書くことになった経緯や思いは後半部分に書こうと思います。

loop 変数からstd_logic_vectorの変換方法

一度、unsignedに直して、std_logic_vectorに入れる。 ghdlでコンパイルしました。 断片的にコードを書き写すのが難しい言語なので、簡単な加算器のテストベンチを貼ります。

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;


entity ADDER_2BIT_TEST is
end ADDER_2BIT_TEST;


architecture RTL of ADDER_2BIT_TEST is
        component ADDER_2BIT
                port(A,B: in std_logic_vector(1 downto 0);
                S: out std_logic_vector(1 downto 0);
                OVERFLOW: out std_logic);
        end component;

        constant STEP: Time := 100 ns;
        signal A,B,S: std_logic_vector(1 downto 0);
        signal OVERFLOW: std_logic;
begin
        U0: ADDER_2BIT port map(A,B,S,OVERFLOW);
        process
        begin
                for I in 0 to 3 loop
                        for J in 0 to 3 loop
                                A <= std_logic_vector(to_unsigned(I,2)); B <= std_logic_vector(to_unsigned(J,2));
                                wait for STEP;
                        end loop;
                end loop;
                wait;
        end process;
end RTL;

このprocess文のところ。unsignedに直して、std_logic_vectorに直すとイける。 adaの型変換の話がまだ掴めていないのでなんとも言えないです。 強い静的型付け言語感をひしひしと感じています。オブジェクト指向らしいのですが、std_logic_vector()がキャストで、to_unsignedでunsignedのオブジェクトを生成してるらしいです。unsignedがわかって、その後std_logic_vector(unsigned(I,2))ってコンストラクタっぽく使ってたらずっとエラー出てました。 vhdl std_logic_vector loop で検索してたらあんまいい情報が出なくて、これ書いてる途中に std_logic_vector unsignedで検索したら一発だった...さっきの猛烈に検索してた時間はなんだったのか...

まぁ、新しいこと学べたのでよしとします。

経緯

学校でVHDLをやっていまして、これからFPGAのボード触るらしいです。個人的に前からFPGAは調べてた割には、環境が統一、一貫されてなさすぎて、調べて終わりみたいな感じになってたので嬉しいです。最初の方でコリコリ書いてたら少し面白みが出てきてしまったので、やる気がモリモリなのです。

教科書もなかなかわかりやすいと思っています。誤字は少し多いですけど。後、v08に対応してないみたいですね。これを調べたそもそものきっかけがuse ieee.std_logic_arith.all;だったせいなんですよね。ghdlのライブラリに標準的に備わってなくて悲しかったです。わかりやすいと思うんだけどなぁ。残念。CPU周りは面白いので、これを機にadaとヘネパタよく読みたいですね。 CPU作りたみが深いですね。4 bitのCPUの作りかたの本はだいぶ有名なので、そっちを先に読もうかな。まぁ結果はともかく色々触ってみたいですね。

ところで、カテゴリーを追加してみました。目的は毎日の変化(成長)だけども目標はそれぞれのカテゴリーで50項目ぐらい作りたいです。1 週間にそれぞれ 1 記事書けば50週...w まぁそんな冗談は置いといて、地道にやっていきたいですね。やっとやりたいことができるモチベーションになってきたのに、時間がないんですよね。これが人生というものなのでしょうか。少しずつでもやっていきたいです(強い意志)

esp wroom 32を使い始めた

esp使い始めました。 先日、usb to serial変換モジュールが壊れたので、今回はesp wroom 32の大人しく開発キット買いました。

esp wroom 32 devkit C

秋月で売ってた esp-woom-32 dev kit cを買いました。 1500円くらい。micro usbを差すだけですぐ使える優れもの。正確にいうと差すだけでは使えない(os x) OS Xではドライバーを入れないと使えないです。

USB - UART ブリッジ VCP ドライバ|Silicon Labs

こっから落としてインストールする。

esp-wroom-32のflashバックアップ

esp-wroom-32にはSPI Flash と呼ばれる記憶領域がある。

https://www.espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf

このリファレンスのExternal Memoryの項を読むと書いてある. SPIを使用したFlashなのかな。とSPI SRAMも書いてある。Flashはread onlyでSRAMは読み書き可らしきことが書いてある。このFlashの方に色々書き込まれるみたいで、出荷時のバックアップをするときはこっから読みだして、保存すればいいんだと思う。4MB読み出せばいいことはわかったんだけど、なんで的な。これでわかった。

qiita.com

この方みたいに、esptoolsをcloneして読み出せばおk。パーティションとかどこに載ってるのかがまだわかんないけど、これで使う準備はできた。書き込み放題だ。

リファレンス読んだらだいぶできることあって面白そうだ。

余談

このdevkit cは普通のブレッドボード(真ん中が5行:5行で別れているやつ)を使うと片側1列しかなくて詰むんですよね。知らなくて買ったんですけど、家にあったブレッドボードを崩して使いました。ブレッドボードの裏側というか構造初めて見ました。

ちょっと時間がないのでここまでで。

ARC 103 D - Robot Arms

個人的に学ぶことが多かったのでメモメモ。

学んだこと

  • 観察力の足りなさ
  • 小さい例でもっと考える
  • ちょっとずつ
  • マンハッタン距離と45度回転

マンハッタン距離と45度回転

ちょっとここは数学的っぽいのでメモ。
マンハッタン距離を考える。
2次元の場合、
d_{AB}=|x_{A}-x_{B}|+|y_{A}-y_{B}|
で定義される。例えば、原点から(1,2)までのマンハッタン距離は 3 とかね。

次に、適当にA(x_{A},y_{A})を考えるじゃん。
これから上下左右それぞれdだけ動いた点Bを考える。
上 : B(x_{A} , y_{A}+d)
下 : B(x_{A} , y_{A}-d)
右 : B(x_{A}+d , y_{A})
左 : B(x_{A}-d , y_{A})
こんな感じになる。

そして、45度回転させた座標系(u,v)を考える。つまり、(u, v) = (x+y, x-y) というような感じ。
正確には、\frac{1}{\sqrt{2}}を除いているわけだけど。

これが、ここで、u, v 上では、点Aは

A(x_{A}+y_{A},x_{A}-y_{A})

になってるわけだ。
じゃあ、点Bは?

上 : B(x_{A}+y_{A}+d , x_{A}-y_{A}-d)
下 : B(x_{A}+y_{A}-d , x_{A}-y_{A}+d)
右 : B(x_{A}+y_{A}+d , x_{A}-y_{A}+d)
左 : B(x_{A}+y_{A}-d , x_{A}-y_{A}-d)

こんな感じになってるわけ。

ここで、
 x_{A}+y_{A} = u_{A}
 x_{B}-y_{A} = v_{A}
とすると、
点Bの u座標は u_{A}+d, v座標はv_{A}といったように、u と v を分離することができたわけだ。これを用いるとそれぞれの座標u,vでdの足し引きだけで、次の点にいけるみたいだ。

これを用いたのが、解答

解答

def solve(xy):
    p = False
    if all([(x+y)%2==0 for x,y in xy]):
        p = True
    elif all([(x+y)%2==1 for x,y in xy]):
        pass
    else:
        print(-1)
        return
    m = [2**i for i  in range(30,-1,-1)]
    if p:
        m.append(1)
    anses = []
    for x,y in xy:
        usum, vsum = (0, 0)
        ans = []
        u = x+y
        v = x-y
        anses.append(ans)
        for d in m:
            if usum <= u:
                usum += d
                if vsum <= v:
                    vsum += d
                    ans.append('R')
                else:
                    vsum -= d
                    ans.append('U')
            else:
                usum -= d
                if vsum <= v:
                    vsum += d
                    ans.append('D')
                else:
                    vsum -= d
                    ans.append('L')
    print(len(m))
    print(" ".join([str(i) for i in m]))
    for a in anses:
        print("".join(a))


def main():
    n = int(input())
    xy = []
    for i in range(n):
        xy.append([int(i) for i in input().split()])
    solve(xy)

if __name__ == '__main__':
    main()

ということになる。

pwnable.kr(7)(1) ~input~

今回はなかば書き写す面が多いです。正直、わからないことが多かったので。
言わずもがな、使ってるpythonは2系です。

問題概要

以下のソースコードを実行して、flagを読み出す。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>

int main(int argc, char* argv[], char* envp[]){
	printf("Welcome to pwnable.kr\n");
	printf("Let's see if you know how to give input to program\n");
	printf("Just give me correct inputs then you will get the flag :)\n");

	// argv
	if(argc != 100) return 0;
	if(strcmp(argv['A'],"\x00")) return 0;
	if(strcmp(argv['B'],"\x20\x0a\x0d")) return 0;
	printf("Stage 1 clear!\n");	

	// stdio
	char buf[4];
	read(0, buf, 4);
	if(memcmp(buf, "\x00\x0a\x00\xff", 4)) return 0;
	read(2, buf, 4);
        if(memcmp(buf, "\x00\x0a\x02\xff", 4)) return 0;
	printf("Stage 2 clear!\n");
	
	// env
	if(strcmp("\xca\xfe\xba\xbe", getenv("\xde\xad\xbe\xef"))) return 0;
	printf("Stage 3 clear!\n");

	// file
	FILE* fp = fopen("\x0a", "r");
	if(!fp) return 0;
	if( fread(buf, 4, 1, fp)!=1 ) return 0;
	if( memcmp(buf, "\x00\x00\x00\x00", 4) ) return 0;
	fclose(fp);
	printf("Stage 4 clear!\n");	

	// network
	int sd, cd;
	struct sockaddr_in saddr, caddr;
	sd = socket(AF_INET, SOCK_STREAM, 0);
	if(sd == -1){
		printf("socket error, tell admin\n");
		return 0;
	}
	saddr.sin_family = AF_INET;
	saddr.sin_addr.s_addr = INADDR_ANY;
	saddr.sin_port = htons( atoi(argv['C']) );
	if(bind(sd, (struct sockaddr*)&saddr, sizeof(saddr)) < 0){
		printf("bind error, use another port\n");
    		return 1;
	}
	listen(sd, 1);
	int c = sizeof(struct sockaddr_in);
	cd = accept(sd, (struct sockaddr *)&caddr, (socklen_t*)&c);
	if(cd < 0){
		printf("accept error, tell admin\n");
		return 0;
	}
	if( recv(cd, buf, 4, 0) != 4 ) return 0;
	if(memcmp(buf, "\xde\xad\xbe\xef", 4)) return 0;
	printf("Stage 5 clear!\n");

	// here's your flag
	system("/bin/cat flag");	
	return 0;
}

Stage1

	if(argc != 100) return 0;
	if(strcmp(argv['A'],"\x00")) return 0;
	if(strcmp(argv['B'],"\x20\x0a\x0d")) return 0;
	printf("Stage 1 clear!\n");	

この部分。
プログラムの引数の数を変化させて、内容も変える。

input2@ubuntu:~$ ./input `python -c "args=['a' for i in range(99)];args[ord('A')-1]='\x00';args[ord('B')-1]='\x20\x0a\x0d';print ' '.join(args)"`

でStage 1 clearかなと安易に思った。残念。

この問題点は、

  • ヌル文字で引数が止まる
  • スペース(\x20)を引数にできない
  • ラインフィード(\x0a)を引数にできない
  • キャリッジリターン(\x0d)を引数にできない

とたくさん問題がある。何も満たせていない...
ここで、わからなかったので、答えを検索した。
で、出てきたのが、これ

0x3f97.github.io

コードがわかりやすかった。
この部分は、
exec系のシステムコールを使って、引数を渡すようだ。
これを見て思ったのが、

ox.execv("/home/input2/input", ["input"]+args)

の部分で、自分で、引数の0番目を渡しているということ。
ここら辺は全部シェル(bash, zsh etc)がやってくれてるんだなという新たな知見を得ました。
なるほど。
じゃあ、やってみよう。

# /tmp/myfiles/stage1.py
import os
def main():
        args = ["0"] * 99
        args[ord("A")-1] = ""
        args[ord("B")-1] = "\x20\x0a\x0d"
        pid = os.fork()
        if pid == 0:
                os.execv("/home/input2/input",["input"]+args)

if __name__ == '__main__':
        main()
input2@ubuntu:/tmp/myfiles$ python stage1.py 
Welcome to pwnable.kr
Let's see if you know how to give input to program
Just give me correct inputs then you will get the flag :)
Stage 1 clear!

おっけい。
補足的な説明になるんだが、飛んだ先のパイプを使ったstage1クリアー方法はまちがっているんですよね。どうやら、execvが勝手に引数の後にヌル文字を追加してくれるので。
とりあえず、今日はここまでで。

AE-232Rが壊れちゃった

タイトル通り、壊してしまいました。

原因がわからないのがまた謎なんですよね。

ことの経緯

esp wroom 32 にファームウェアを書き込もうと思ってブレッドボードにセットしたんですよね。それで、電源装置から供給しました。
1 V ぐらいには 1 A近く流れてたんですよ。おかしい。
その後も線形で上がってく...

おかしいなぁと思って、IC触ったら激アツ。
これ壊れてるなぁと。

結論

原因がわからなかったのがまた辛いですね。配線は死ぬほど確認したので大丈夫だと思うんですけど、埃がたまりそうなところに野ざらしにしてたから...
とてもつらいです。
埃でショートが可能性一番ありうる。
ちゃんと埃の被らないところに置いておこうという教訓を得ました。

ARC103 C-/\/\/\/

なんとなく載せます

from collections import Counter


def main():
    n = int(input())
    v = [int(i) for i in input().split()]
    ans = 0
    odd = Counter(v[1::2])
    even = Counter(v[::2])
    odd_mosts = odd.most_common(2)
    even_mosts = even.most_common(2)
    if odd_mosts[0][0] == even_mosts[0][0]:
        if len(odd) == len(even) == 1:
            ans = n//2
        else:
            ans_sel = []
            ans_sel.append(n//2-odd_mosts[0][1]+n//2-even_mosts[1][1])
            ans_sel.append(n//2-odd_mosts[1][1]+n//2-even_mosts[0][1])
            ans = min(ans_sel)
    else:
        ans+=(n//2-odd_mosts[0][1])
        ans+=(n//2-even_mosts[0][1])
    print(ans)

うん。久々にやったからかすごい時間かかった気がした。

最近の近況報告

ToDoを真面目に作っている。自分で使うための。
githubに一応公開している

基本的に使っているものは

でバックエンドをたてた。
テストも真面目に書いてる。
アプリ側のUIとかまだ決まってないのでまだなんともって感じですけど。


前回作ったkivyのメニューバーなんだけど、クラスの構成ミスったなって感じがする。まだ、README.mdとか整えていないのでなんとも言えないが、直して公開したいなって思ってたり思ってなかったりする。


余談だが、昨日aitendoでTFTの2.8インチの半田付け必須のモジュール買ったんだけど、半田付けのところじゃない部分でミスってイキました。2000円無駄になりました。具体的には、基盤に付いてた表面実装の抵抗がクリップに引っかかってどっか飛んでいくという凄惨な事件です。何Ωだったのかもわからない。TFT本体は生きてるので、変換のフラットケーブルを入手できるか....

あと、全然格闘ゲームとかやらないんだけど、梅原さんの勝ち続ける意志力を読みました。

昨日変な時間に起きてしまい、夜中ずっと読んでたんです。めちゃめちゃ参考になりましたのん... 梅原さん本当に精神が強いなと思いました。弱々な僕とは全然違う... 読んでいて、めちゃめちゃかっこよかったです。やっぱり考えたり悩んだりするのって重要なんだなって思いました。ゲームだけじゃなくて、多分、世の中のあらゆることに通じているんじゃないかなと思うことしかなかったです。僕の中での何度も読みたい新書ランキングトップですね。前に、潔い生き方?みたいな本を読んだんですけど、塵ほどつまらなかったと感じたことがありました。それに比べると本当に実用的だし、それを実践する梅原さんはすごいなと。僕もちょっとずつ実践していきたいです。というかします。梅原さんみたいに幼少期から死ぬほど頑張って続けたものは遠い過去に自ら捨ててしまったけど、また1からでもやりたいです。