条件语句
由于if被scala语言占用了,SpinalHDL使用when…elsewhen…otherwise来用作硬件的条件语句
class top extends Module{ val a,b = UInt(8 bits) val mode = Bits(2 bits) when(a === b) { mode := 0 } elsewhen(a>b) { mode := 1 } otherwise { mode := 2 } }
module top ( ); wire [7:0] a; wire [7:0] b; reg [1:0] mode; always @(*) begin if((a == b)) begin mode = 2'b00; end else begin if((b < a)) begin mode = 2'b01; end else begin mode = 2'b10; end end end endmodule
三元操作符
SpinalHDL有2种方法实现verilog的en ? a : b,建议使用后2个方法,第一种方法的|容易与逻辑或混淆。复杂条件建议使用when,这样更加清晰。
- en ? a | b
- en ? a otherwise b,推荐
- Mux(en,a,b),推荐
class top extends Module{ val a,b = UInt(8 bits) val mode1 = (a===b) ? B"2'd0" | B"2'd1" val mode2 = (a===b) ? B"2'd0" otherwise B"2'd1" val mode3 = Mux(a===b,B"2'd0",B"2'd1") }
module top ( ); wire [7:0] a; wire [7:0] b; wire [1:0] mode1; wire [1:0] mode2; wire [1:0] mode3; assign mode1 = ((a == b) ? 2'b00 : 2'b01); assign mode2 = ((a == b) ? 2'b00 : 2'b01); assign mode3 = ((a == b) ? 2'b00 : 2'b01); endmodule
case语句
class top extends Module{ val sel = Bits(2 bits) val mode = Bits(3 bits) switch(sel) { is(0,2) { mode := B"3'd0" } is(1) { mode := B"3'd1" } default { mode := B"3'd2" } } }
module top ( ); wire [1:0] sel; reg [2:0] mode; always @(*) begin case(sel) 2'b00, 2'b10 : begin mode = 3'b000; end 2'b01 : begin mode = 3'b001; end default : begin mode = 3'b010; end endcase end endmodule
case简写方式
class top extends Module{ val sel = Bits(2 bits) val mode = sel.mux( (0,1) -> B"3'd0", 2 -> B"3'd1", default -> B"3'd2" ) val mode_reg = Reg(UInt(3 bits)) mode_reg.switchAssign(sel)( (0,1) -> U"3'd0", 2 -> U"3'd1" ) }
module top ( input clk, input rstn ); wire [1:0] sel; reg [2:0] mode; reg [2:0] mode_reg; always @(*) begin case(sel) 2'b00, 2'b01 : begin mode = 3'b000; end 2'b10 : begin mode = 3'b001; end default : begin mode = 3'b010; end endcase end always @(posedge clk) begin case(sel) 2'b00, 2'b01 : begin mode_reg <= 3'b000; end 2'b10 : begin mode_reg <= 3'b001; end default : begin end endcase end endmodule
等分case
class top extends Module{ val sel = UInt(2 bits) val data = Bits(128 bits) // Dividing a wide Bits type into smaller chunks, using a mux: val dataWord1 = sel.muxList(for (index <- 0 until 4) yield (index, data(index*32+32-1 downto index*32))) val dataWord2 = sel.muxList(data.divideIn(4 slices)) // A shorter way to do the same thing: val dataWord3 = data.subdivideIn(32 bits)(sel) }
module top ( ); reg [31:0] dataWord3_bits; wire [1:0] sel; wire [127:0] data; reg [31:0] dataWord1; reg [31:0] dataWord2; wire [31:0] dataWord3; always @(*) begin case(sel) 2'b00 : begin dataWord3_bits = data[31 : 0]; end 2'b01 : begin dataWord3_bits = data[63 : 32]; end 2'b10 : begin dataWord3_bits = data[95 : 64]; end default : begin dataWord3_bits = data[127 : 96]; end endcase end always @(*) begin case(sel) 2'b00 : begin dataWord1 = data[31 : 0]; end 2'b01 : begin dataWord1 = data[63 : 32]; end 2'b10 : begin dataWord1 = data[95 : 64]; end default : begin dataWord1 = data[127 : 96]; end endcase end always @(*) begin case(sel) 2'b00 : begin dataWord2 = data[31 : 0]; end 2'b01 : begin dataWord2 = data[63 : 32]; end 2'b10 : begin dataWord2 = data[95 : 64]; end default : begin dataWord2 = data[127 : 96]; end endcase end assign dataWord3 = dataWord3_bits; endmodule
casez
class top extends Module{ val sel = Bits(4 bits) val mode = Bits(3 bits) switch(sel) { is(M"---1") { mode := B"3'd0" } is(M"--1-") { mode := B"3'd1" } is(M"-1--") { mode := B"3'd2" } default { mode := B"3'd3" } } }
module top ( ); wire [3:0] sel; reg [2:0] mode; always @(*) begin casez(sel) 4'b???1 : begin mode = 3'b000; end 4'b??1? : begin mode = 3'b001; end 4'b?1?? : begin mode = 3'b010; end default : begin mode = 3'b011; end endcase end endmodule
生活不止眼前的苟且,还有诗和远方
本文链接: https://dxsm.github.io/p/spinalhdl-conditional.html
版权声明: 本博客所有文章除特别声明外,均采用CC BY-NC-SA 3.0许可协议。转载请注明出处!