I like fpga

change the world by fpga
2021/06/06

floor(log2)をverilogで実装した[floor log2 in verilog]

VERILOG   

いろいろ疑問はあるのですが。。。。とりあえず、log2のfloorをverilogで実装しました。C言語で記述すると、

#include <math.h>

int32_t out_val =floor(log2(val));

これをverilogで実装します。

module clog2(
	input clk,
	input reset_n,
	input [18:0] val,
	output reg [31:0] out_val
);

reg [31:0] clog2 = 32'h0;
reg [18:0] in_val;
always @(posedge clk, negedge reset_n) begin
	if (!reset_n) begin
		out_val = 32'h0;
	end else begin
		in_val = val;
		for (clog2=0; in_val>0; clog2=clog2+1) begin
			in_val = in_val>>1;
		end
		out_val = clog2 - 1;
	end
end

forの中で、演算結果を利用しているので、ブロッキングで記述しているが、順序回路で、ブロッキングで書いていいのか不安。。。。

次は、verilatorのテストコード

#include <iostream>
#include <verilated.h>
#include "Vclog2.h"
#include <verilated_fst_c.h> 
#include <math.h>

int time_counter = 0;
int main(int argc, char** argv) {
	Verilated::commandArgs(argc, argv);

	// Instantiate DUT
	Vclog2 *dut = new Vclog2();
	// Trace DUMP ON
	Verilated::traceEverOn(true);
	VerilatedFstC* tfp = new VerilatedFstC;

	dut->trace(tfp, 100);  // Trace 100 levels of hierarchy
	tfp->open("simx.fst");

	// Format
	dut->reset_n = 0;
	dut->clk = 0;

	// Reset Time
	while (time_counter < 10) {
		dut->eval();
		tfp->dump(time_counter);  // 波形ダンプ用の記述を追加
		time_counter++;
	}
	// Release reset
	dut->reset_n = 1;
	dut->val=0;
	while (time_counter < 4000 && !Verilated::gotFinish()) {
		dut->clk = !dut->clk; // Toggle clock
		if (dut->clk)
			dut->val++;
		// Evaluate DUT
		dut->eval();
		if (dut->clk) {
			int c_lang_result = (int)floor(log2(dut->val));
			if (c_lang_result != dut->out_val) {
				printf("%d %d %f %f\n", dut->val, dut->out_val, floor(log2(dut->val)), log2(dut->val));
			}
		}
		tfp->dump(time_counter);  // 波形ダンプ用の記述を追加
		time_counter++;

	}

	dut->final();
	tfp->close(); 

dut->val++;のところ、最初、clkが1、0で両方で実行していたので、結果が期待通りにならなかった。入力値を買えるところもclkを意識しないとね。

ビルド方法

verilator --cc --exe  --trace-fst --trace-params --trace-structs --trace-underscore \
    clog2.v -exe test_clog2.cpp
make -C obj_dir -f Vclog2.mk

実行は、

 ./obj_dir/Vclog2  

で、行います。

実装したコードは、こちらになります。

https://github.com/y38y38/floor_log2

« »