risc-v中文社区

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

[原创] 自动售货机(when)

  [复制链接]

347

主题

564

帖子

2237

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2237
发表于 2021-9-22 11:48:19 | 显示全部楼层 |阅读模式
import chisel3._
import chisel3.util._
//自动售货机 sOk表示达到或超过20分需要返回valid表示可以售货
class VendingMachine extends Module{
  val io = IO(new Bundle {
    val nickel = Input(Bool()) //nickel是一枚5分的硬币
    val dime = Input(Bool()) //dime是一枚10分的硬币
    val valid = Output(Bool())
  })
  val sIdle :: s5 :: s10 :: s15 :: sOk :: Nil = Enum(5)
  val state = RegInit(sIdle)
  when (state === sIdle) {
    when(io.nickel) {
      state := s5
}
    when(io.dime) {
      state := s10
}
  }
  when (state === s5) {
    when(io.nickel) {
      state := s10
}
    when(io.dime) {
      state := s15
}
  }
  when (state === s10) {
    when(io.nickel) {
      state := s15
}
    when(io.dime) {
      state := sOk
}
  }
  when (state === s15) {
    when(io.nickel) {
      state := sOk
}
    when(io.dime) {
      state := sOk
}
  }
  when (state === sOk) {
    state := sIdle
}
  io.valid := state === sOk  //  io.valid := (state === sOk) 达到sOk之后需要发出一个脉冲给出发货提示
}

回复

使用道具 举报

347

主题

564

帖子

2237

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2237
 楼主| 发表于 2021-9-22 11:53:27 | 显示全部楼层
产生的verilog文件内容如下:
module VendingMachine(
  input   clock,
  input   reset,
  input   io_nickel,
  input   io_dime,
  output  io_valid
);
  reg [2:0] state; // @[VendingMachine.scala 17:22]
  reg [31:0] _RAND_0;
  wire  _T = state == 3'h0; // @[VendingMachine.scala 18:15]
  wire [2:0] _GEN_0 = io_nickel ? 3'h1 : state; // @[VendingMachine.scala 19:22]
  wire [2:0] _GEN_1 = io_dime ? 3'h2 : _GEN_0; // @[VendingMachine.scala 20:22]
  wire [2:0] _GEN_2 = _T ? _GEN_1 : state; // @[VendingMachine.scala 18:26]
  wire  _T_1 = state == 3'h1; // @[VendingMachine.scala 22:15]
  wire  _T_2 = state == 3'h2; // @[VendingMachine.scala 26:15]
  wire  _T_3 = state == 3'h3; // @[VendingMachine.scala 30:15]
  wire  _T_4 = state == 3'h4; // @[VendingMachine.scala 34:15]
  assign io_valid = state == 3'h4; // @[VendingMachine.scala 37:12]
`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}};
  state = _RAND_0[2:0];
  `endif // RANDOMIZE_REG_INIT
  `endif // RANDOMIZE
end // initial
`endif // SYNTHESIS
  always @(posedge clock) begin
    if (reset) begin
      state <= 3'h0;
    end else if (_T_4) begin
      state <= 3'h0;
    end else if (_T_3) begin
      if (io_dime) begin
        state <= 3'h4;
      end else if (io_nickel) begin
        state <= 3'h4;
      end else if (_T_2) begin
        if (io_dime) begin
          state <= 3'h4;
        end else if (io_nickel) begin
          state <= 3'h3;
        end else if (_T_1) begin
          if (io_dime) begin
            state <= 3'h3;
          end else if (io_nickel) begin
            state <= 3'h2;
          end else if (_T) begin
            if (io_dime) begin
              state <= 3'h2;
            end else if (io_nickel) begin
              state <= 3'h1;
            end
          end
        end else if (_T) begin
          if (io_dime) begin
            state <= 3'h2;
          end else if (io_nickel) begin
            state <= 3'h1;
          end
        end
      end else if (_T_1) begin
        if (io_dime) begin
          state <= 3'h3;
        end else if (io_nickel) begin
          state <= 3'h2;
        end else if (_T) begin
          if (io_dime) begin
            state <= 3'h2;
          end else if (io_nickel) begin
            state <= 3'h1;
          end
        end
      end else if (_T) begin
        if (io_dime) begin
          state <= 3'h2;
        end else if (io_nickel) begin
          state <= 3'h1;
        end
      end
    end else if (_T_2) begin
      if (io_dime) begin
        state <= 3'h4;
      end else if (io_nickel) begin
        state <= 3'h3;
      end else if (_T_1) begin
        if (io_dime) begin
          state <= 3'h3;
        end else if (io_nickel) begin
          state <= 3'h2;
        end else begin
          state <= _GEN_2;
        end
      end else begin
        state <= _GEN_2;
      end
    end else if (_T_1) begin
      if (io_dime) begin
        state <= 3'h3;
      end else if (io_nickel) begin
        state <= 3'h2;
      end else begin
        state <= _GEN_2;
      end
    end else begin
      state <= _GEN_2;
    end
  end
endmodule
回复

使用道具 举报

347

主题

564

帖子

2237

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2237
 楼主| 发表于 2021-9-22 11:56:14 | 显示全部楼层
我们写的when代码中:
when (io.nickel) { state := xxxx }
when (io.dime) { state := xxxxx }
然后可以看到产生的verilog代码是先判断io.dime,然后再else if(io.nickel)判断,虽然没有问题,我们需要记住这种语法产生的verilog判断逻辑是如何判断的即可。
回复

使用道具 举报

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

本版积分规则



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

GMT+8, 2024-5-5 14:10 , Processed in 0.016297 second(s), 17 queries .

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

Copyright © 2018-2021, risc-v open source

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