risc-v中文社区

 找回密码
 立即注册
查看: 1016|回复: 2

[原创] chisel求最大公约数

  [复制链接]

347

主题

564

帖子

2237

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2237
发表于 2021-9-18 08:29:01 | 显示全部楼层 |阅读模式
class RealGCDInput extends Bundle {
  val a = UInt(16.W)
  val b = UInt(16.W)
}

class RealGCD extends Module {
  val io  = IO(new Bundle {
    val in  = DeqIO(new RealGCDInput())
    val out = Output(Valid(UInt(16.W)))
  })

  val x = Reg(UInt())
  val y = Reg(UInt())
  val p = RegInit(false.B)

  io.in.ready := !p

  when (io.in.valid && !p) {
    x := io.in.bits.a
    y := io.in.bits.b
    p := true.B
  }

  when (p) {
    when (x > y)  { x := y; y := x }
    .otherwise    { y := y - x }
  }

  io.out.bits  := x
  io.out.valid := y === 0.U && p
  when (io.out.valid) {
    p := false.B
  }
}


回复

使用道具 举报

347

主题

564

帖子

2237

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2237
 楼主| 发表于 2021-9-18 08:30:41 | 显示全部楼层
生成的verilog文件内容如下:
module RealGCD(
  input         clock,
  input         reset,
  output        io_in_ready,
  input         io_in_valid,
  input  [15:0] io_in_bits_a,
  input  [15:0] io_in_bits_b,
  output        io_out_valid,
  output [15:0] io_out_bits
);
  reg [15:0] x; // @[RealGCD.scala 17:14]
  reg [31:0] _RAND_0;
  reg [15:0] y; // @[RealGCD.scala 18:14]
  reg [31:0] _RAND_1;
  reg  p; // @[RealGCD.scala 19:18]
  reg [31:0] _RAND_2;
  wire  _T = ~p; // @[RealGCD.scala 20:18]
  wire  _T_2 = io_in_valid & _T; // @[RealGCD.scala 21:21]
  wire  _GEN_2 = _T_2 | p; // @[RealGCD.scala 21:28]
  wire  _T_3 = x > y; // @[RealGCD.scala 28:13]
  wire [15:0] _T_5 = y - x; // @[RealGCD.scala 29:30]
  wire  _T_6 = y == 16'h0; // @[RealGCD.scala 33:21]
  assign io_in_ready = ~p; // @[RealGCD.scala 20:15]
  assign io_out_valid = _T_6 & p; // @[RealGCD.scala 33:16]
  assign io_out_bits = x; // @[RealGCD.scala 32:16]
`ifdef RANDOMIZE_GARBAGE_ASSIGN
`define RANDOMIZE
`endif
`ifdef RANDOMIZE_INVALID_ASSIGN
`define RANDOMIZE
`endif
`ifdef RANDOMIZE_REG_INIT
`define RANDOMIZE
`endif
`ifdef RANDOMIZE_MEM_INIT
`define RANDOMIZE
`endif
`ifndef RANDOM
`define RANDOM $random
`endif
`ifdef RANDOMIZE_MEM_INIT
  integer initvar;
`endif
`ifndef SYNTHESIS
initial begin
  `ifdef RANDOMIZE
    `ifdef INIT_RANDOM
      `INIT_RANDOM
    `endif
    `ifndef VERILATOR
      `ifdef RANDOMIZE_DELAY
        #`RANDOMIZE_DELAY begin end
      `else
        #0.002 begin end
      `endif
    `endif
  `ifdef RANDOMIZE_REG_INIT
  _RAND_0 = {1{`RANDOM}};
  x = _RAND_0[15:0];
  `endif // RANDOMIZE_REG_INIT
  `ifdef RANDOMIZE_REG_INIT
  _RAND_1 = {1{`RANDOM}};
  y = _RAND_1[15:0];
  `endif // RANDOMIZE_REG_INIT
  `ifdef RANDOMIZE_REG_INIT
  _RAND_2 = {1{`RANDOM}};
  p = _RAND_2[0:0];
  `endif // RANDOMIZE_REG_INIT
  `endif // RANDOMIZE
end // initial
`endif // SYNTHESIS
  always @(posedge clock) begin
    if (p) begin
      if (_T_3) begin
        x <= y;
      end else if (_T_2) begin
        x <= io_in_bits_a;
      end
    end else if (_T_2) begin
      x <= io_in_bits_a;
    end
    if (p) begin
      if (_T_3) begin
        y <= x;
      end else begin
        y <= _T_5;
      end
    end else if (_T_2) begin
      y <= io_in_bits_b;
    end
    if (reset) begin
      p <= 1'h0;
    end else if (io_out_valid) begin
      p <= 1'h0;
    end else begin
      p <= _GEN_2;
    end
  end
endmodule
回复

使用道具 举报

347

主题

564

帖子

2237

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2237
 楼主| 发表于 2021-9-18 08:52:28 | 显示全部楼层
最大公约数求法中,辗转相除法的基本原理是:两个数的最大公约数等于它们中较小的数和两数之差的最大公约数。
比如252和105的最大公约数:252-105=147 147-105=42  105-42=63 63-42=21,所以求出最大公约数为21
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



Archiver|手机版|小黑屋|risc-v中文社区

GMT+8, 2024-5-3 05:23 , Processed in 0.018299 second(s), 17 queries .

risc-v中文社区论坛 官方网站

Copyright © 2018-2021, risc-v open source

快速回复 返回顶部 返回列表