高位合成言語Polyphony (windowsでiverilog その11）

#概要

windowsでiverilogやってみた。
polyphony、やってみた。

#サンプルコード


```
import polyphony
from polyphony import testbench, module
from polyphony.io import Port
from polyphony.typing import uint3, uint4, uint8
from polyphony.timing import clksleep, clkfence, wait_rising, wait_falling

@module
class mul:
	def __init__(self):
		self.a = Port(uint4, 'in', protocol='valid')
		self.b = Port(uint4, 'in', protocol='valid')
		self.c = Port(uint8, 'out', protocol='valid')
		self.append_worker(self._worker)
	def _worker(self):
		while polyphony.is_worker_running():
			a3:uint4 = self.a.rd()
			b3:uint4 = self.b.rd()
			r8:uint8 = a3 * b3
			self.c(r8)

m = mul()

@testbench
def test(m):
	m.a.wr(3)
	m.b.wr(9)
	s = m.c.rd()
	print("3 * 9 = ", s)

test(m)
```

#python実行結果


```
3 * 9 = 27
```

#コンパイル結果

```
module mul_m
  (
    input wire clk,
    input wire rst,
    input wire [3:0] a,
    input wire a_valid,
    input wire [3:0] b,
    input wire b_valid,
    output reg [7:0] c = 0,
    output reg c_valid = 0
  );

  //localparams
  localparam mul_m__worker_cb_b1_INIT = 0;
  localparam mul_m__worker_cb_b1_FINISH = 1;
  localparam mul_m__worker_cb_L1_while2_S0 = 2;
  localparam mul_m__worker_cb_L1_while2_S1 = 3;
  localparam mul_m__worker_cb_L1_while2_S2 = 4;
  localparam mul_m__worker_cb_L1_while2_S3 = 5;
  localparam mul_m__worker_cb_L1_while2_S4 = 6;
  localparam mul_m__worker_cb_L1_while2_S5 = 7;
  localparam mul_m__worker_cb_L1_while2_S6 = 8;
  
  //signals: 
  wire        [7:0] m__worker_cb_r8;
  reg        [3:0] m__worker_cb_a3;
  reg        [3:0] m__worker_cb_b3;
  reg        [3:0] m__worker_cb_state;
  //combinations: 
  assign m__worker_cb_r8 = (m__worker_cb_a3 * m__worker_cb_b3);
  
  always @(posedge clk) begin
    if (rst) begin
      c <= 0;
      c_valid <= 0;
      m__worker_cb_a3 <= 0;
      m__worker_cb_b3 <= 0;
      m__worker_cb_state <= mul_m__worker_cb_b1_INIT;
    end else begin //if (rst)
      case(m__worker_cb_state)
      mul_m__worker_cb_b1_INIT: begin
        m__worker_cb_state <= mul_m__worker_cb_L1_while2_S0;
      end
      mul_m__worker_cb_L1_while2_S0: begin
        if (a_valid == 1) begin
          m__worker_cb_a3 <= a;
          m__worker_cb_state <= mul_m__worker_cb_L1_while2_S2;
        end
      end
      mul_m__worker_cb_L1_while2_S2: begin
        if (b_valid == 1) begin
          m__worker_cb_b3 <= b;
          m__worker_cb_state <= mul_m__worker_cb_L1_while2_S4;
        end
      end
      mul_m__worker_cb_L1_while2_S4: begin
        c <= m__worker_cb_r8;
        c_valid <= 1;
        /* m__worker_cb_r8 <= (m__worker_cb_a3 * m__worker_cb_b3); */
        m__worker_cb_state <= mul_m__worker_cb_L1_while2_S5;
      end
      mul_m__worker_cb_L1_while2_S5: begin
        c_valid <= 0;
        m__worker_cb_state <= mul_m__worker_cb_L1_while2_S0;
      end
      endcase
    end
  end
  

endmodule

module test
  (
    
  );

  //localparams
  localparam CLK_PERIOD = 10;
  localparam CLK_HALF_PERIOD = 5;
  localparam INITIAL_RESET_SPAN = 100;
  localparam test_b1_INIT = 0;
  localparam test_b1_S2 = 1;
  localparam test_b1_S3 = 2;
  localparam test_b1_S4 = 3;
  localparam test_b1_S5 = 4;
  localparam test_b1_S6 = 5;
  localparam test_b1_S7 = 6;
  localparam test_b1_FINISH = 7;
  
  //signals: 
  reg clk;
  reg rst;
  reg        [7:0] s;
  reg        [3:0] test_state;
  //signals: a
  reg        [3:0] m_a;
  reg m_a_valid;
  //signals: b
  reg        [3:0] m_b;
  reg m_b_valid;
  //signals: c
  wire        [7:0] m_c;
  wire m_c_valid;
  //sub modules
  //m instance
  mul_m m(
    .clk(clk),
    .rst(rst),
    .a(m_a),
    .a_valid(m_a_valid),
    .b(m_b),
    .b_valid(m_b_valid),
    .c(m_c),
    .c_valid(m_c_valid)
  );
  
  
  initial begin
    clk = 0;
    #CLK_HALF_PERIOD
    forever #CLK_HALF_PERIOD clk = ~clk;
  end
  initial begin
    rst <= 1;
    #INITIAL_RESET_SPAN
    rst <= 0;
  end
  

  always @(posedge clk) begin
    if (rst) begin
      m_a <= 0;
      m_a_valid <= 0;
      m_b <= 0;
      m_b_valid <= 0;
      s <= 0;
      test_state <= test_b1_INIT;
    end else begin //if (rst)
      case(test_state)
      test_b1_INIT: begin
        m_a <= 3;
        m_a_valid <= 1;
        test_state <= test_b1_S2;
      end
      test_b1_S2: begin
        m_a_valid <= 0;
        test_state <= test_b1_S3;
      end
      test_b1_S3: begin
        m_b <= 9;
        m_b_valid <= 1;
        test_state <= test_b1_S4;
      end
      test_b1_S4: begin
        m_b_valid <= 0;
        test_state <= test_b1_S5;
      end
      test_b1_S5: begin
        if (m_c_valid == 1) begin
          s <= m_c;
          test_state <= test_b1_S7;
        end
      end
      test_b1_S7: begin
        $display("%s %1d", "3 * 9 = ", s);
        test_state <= test_b1_FINISH;
      end
      test_b1_FINISH: begin
        $display("%5t:finish", $time);
        $finish();
      end
      endcase
    end
  end
  

endmodule


```



#実行結果


```


3 * 9 =  27
  180:finish


```

以上。