1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Posted at

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

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

Go言語実装 1

func xor3

Go言語って3入力XORないんですか?
作っていきます。
pwm2.png
真理値表とカルノー図がこちら。

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

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について
各疑似ビットは

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

キャリーcは

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

コード群

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?