verilogHDLで作ったpwmをGo言語でシミュレーションする

# pwmをgolangでシミュレーションする
# 目的
LPFシミュレータを作成する際に、実際のpwm波形生成してくれる関数郡があるととても助かるため。

え？ ModelSim いえ、知らない子ですね。

# Virolog HDL 実装
VerilogHDL で記述（更新見込み）
10bit固定

```pwmc.sv
module pwmc (
	input wire clk,
	input wire [9:0] vq,
	output wire pulse
);

reg [9:0] cnt;
wire [10:0] qc = {1'b1, vq} - {1'b0, cnt};

assign pulse = qc[10];

always @(posedge clk) begin
	cnt <= cnt + 10'b1;
end

initial begin
	cnt = 10'b0;
end

endmodule
```
![pwm1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253609/877e1dd2-77ab-6a00-07e4-459499f9b570.png)

こんな感じの回路。
簡単だね。

# Go言語実装 1

## func xor3
Go言語って３入力XORないんですか？
作っていきます。
![pwm2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253609/5fba6612-f28c-dd9f-9e89-74349dfe60ca.png)
真理値表とカルノー図がこちら。

これらより以下の論理関数が導き出せる

```math
y = a\cdot b\cdot c + a\cdot\overline{b}\cdot\overline{c} + \overline{a}\cdot b \cdot\overline{c} + \overline{a}\cdot\overline{b}\cdot c
```
つまり

```main.go
func xor3(a, b, c bool) bool {
	return a && b && c || a && !b && !c || 
		!a && b && !c || !a && !b && c
}
```
こうですね。

## func fullAdder
全加算器もないんですか？
作っていきます。

### 和
入力a, bについて
各疑似ビットは

```math
ans[i] = xor3(a[i], b[i], キャリーc)
```

キャリーcは

```math
c = a[i] \cdot b[i] + b[i] \cdot c + c \cdot a[i]
```
と表せる。
つまり

```main.go
func fullAdder(a, b []bool) []bool {
	ans := make([]bool, len(a))
	c := false

	for i := 0; i < len(ans); i++ {
		ans[i] = xor3(a[i], b[i], c)
		c = (a[i] && b[i]) || (b[i] && c) || (c && a[i])
	}

	return ans
}
```
こうですね。

## func countUp
カウンタ回路作るのに、
インクリメントないんですか？
作っていきます。

fullAdderを使用してもいいのですが、
もう少し簡略化できますね。

```main.go
func countUp(inp []bool) []bool {
	ans := make([]bool, len(inp))
	c := true

	for i := 0; i < len(ans); i++ {
		ans[i] = xor3(inp[i], c, false)
		c = inp[i] && c
	}

	return ans
}
```

## func allFlip
減算回路作るためにすべての疑似ビットを反転させる関数を用意しておきます。

```main.go
func allFlip(inp []bool) []bool {
	ans := make([]bool, len(inp))

	for i := 0; i < len(ans); i++ {
		ans[i] = !inp[i]
	}

	return ans
}
```

## func fullSubber
減算回路のための準備が整いました。
真の減算回路ではないのでご注意ください。

```main.go
func fullSubber(a, b []bool) []bool {
	return fullAdder(a, allFlip(b))
}
```
真の減算回路は以下の記述となります。

```hoge.go
func subber(a, b []bool) []bool {
	return fullAdder(a, countUp(allFlip(b)))
}
```
差 = 引かれる数 + ビット反転（引く数）+ 1

## func lb
string -> []bool
変換関数。なお、
inp[n] -> ans[0],
inp[0] -> ans[n]
というエンディアン変換（？）も行う。

つまり
"0100"は

inp[0] : 0
inp[1] : 1
inp[2] : 0
inp[3] : 0

であるが、

ans[0] : 0
ans[1] : 0
ans[2] : 1
ans[3] : 0

としてくれる。
ありがたい。

```main.go
func lb(inp string) []bool {
	ans := make([]bool, len(inp))

	for i := 0; i < len(ans); i++ {
		if inp[len(ans) - 1 - i] == '1' {
			ans[i] = true
		} else {
			ans[i] = false
		}
	}
	return ans
}
```
## pwmc struct

```main.go
type Pwmc struct {
	count []bool
	bitWidth int
}

func NewPwmc(bw int) *Pwmc {
	ins := new(Pwmc)
	ins.bitWidth = bw
	ins.count = make([]bool, bw)
	return ins
}

func (ins *Pwmc) ClockUp (vq []bool) bool {
	qc := fullSubber(
		append(vq, lb("1")...), append(ins.count, lb("0")...))

	ins.count = countUp(ins.count)

	return qc[ins.bitWidth]
}
```
順に　宣言、コンストラクタ、alwaysブロック

## メイン関数
```main.go
func main() {

	num_plot := 50
	pwmins := NewPwmc(5)
	val_inp := lb ("01000")

	for i := 0; i < num_plot; i++ {
		if pwmins.ClockUp(val_inp) {
			fmt.Println (i, 1)
		} else {
			fmt.Println (i, 0)
		}
	}
}
```
そのままです。

## gnuplot
![res.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253609/32cc3733-8230-e3da-76b4-44c22cb37f23.png)

## コード群
https://github.com/soleiyu/Golang/tree/master/LPF_sim/PWM_sim