day4 Alwaysblock1
// synthesis verilog_input_version verilog_2001
module top_module(
input a,
input b,
output wire out_assign,
output reg out_alwaysblock
);
assign out_assign=a&b;
always@(*) out_alwaysblock=a&b;
endmodule
// synthesis verilog_input_version verilog_2001
module top_module(
input clk,
input a,
input b,
output wire out_assign,
output reg out_always_comb,
output reg out_always_ff );
assign out_assign=a^b;
always@(*) out_always_comb=a^b;
always@(posedge clk) out_always_ff<=a^b;
endmodule
// synthesis verilog_input_version verilog_2001
module top_module(
input a,
input b,
input sel_b1,
input sel_b2,
output wire out_assign,
output reg out_always );
always@(*)begin
if((sel_b1&sel_b2)==1) begin
out_always=b;
end
else begin
out_always=a;
end
end
assign out_assign=((sel_b1&sel_b2)==1)?b:a;
endmodule
如何避免在使用if语句时生成锁存器?
tip:锁存器与触发器的区别?
锁存器是一种对脉冲电平(也就是0或者1)敏感的存储单元电路,而触发器是一种对脉冲边沿(即上升沿或者下降沿)敏感的存储电路。
当我们在设计电路时,不能直接先写成代码然后期望它直接生成为合适的电路,如下典型错误所示:
- If (cpu_overheated) then shut_off_computer = 1;
- If (~arrived) then keep_driving = ~gas_tank_empty;
语法上正确的代码并不意味着设计成的电路也是合理的。我们来思考这么一个问题,如上图的错误示例,如果if条件不满足,输出如何变化呢?Verilog给出的解决方法是:保持输出不变。因为组合逻辑电路不能记录当前的状态,所以就会综合出锁存器。
所以当我们使用if语句或者case语句时,我们必须考虑到所有情况并给对应情况的输出进行赋值,就意味着我们要为else或者default中的输出赋值。
// synthesis verilog_input_version verilog_2001
module top_module (
input cpu_overheated,
output reg shut_off_computer,
input arrived,
input gas_tank_empty,
output reg keep_driving ); //
always @(*) begin
if (cpu_overheated) begin
shut_off_computer = 1;
end
else begin
shut_off_computer=0;
end
end
always @(*) begin
if (~arrived) begin
keep_driving = ~gas_tank_empty;
end
else begin
keep_driving = 0;
end
end
endmodule
// synthesis verilog_input_version verilog_2001
module top_module (
input [2:0] sel,
input [3:0] data0,
input [3:0] data1,
input [3:0] data2,
input [3:0] data3,
input [3:0] data4,
input [3:0] data5,
output reg [3:0] out );//
always@(*) begin // This is a combinational circuit
case(sel)
3'b000:out=data0;
3'b001:out=data1;
3'b010:out=data2;
3'b011:out=data3;
3'b100:out=data4;
3'b101:out=data5;
default:out=3'b000;
endcase
end
endmodule
// synthesis verilog_input_version verilog_2001
module top_module (
input [3:0] in,
output reg [1:0] pos );
always@(*)begin
if(in&(4'b0001))begin
pos=2'b00;
end
else if((in>>1)&(4'b0001))begin
pos=2'b01;
end
else if((in>>2)&(4'b0001))begin
pos=2'b10;
end
else if((in>>3)&(4'b0001))begin
pos=2'b11;
end
else if((in>>4)&(4'b0001))begin
pos=2'b00;
end
else begin
pos=2'b00;
end
end
endmodule
这里我写复杂了,有更简便的写法
// synthesis verilog_input_version verilog_2001
module top_module (
input [3:0] in,
output reg [1:0] pos );
always@(*)begin
case(1)
in[0] : pos = 2'd0;
in[1] : pos = 2'd1;
in[2] : pos = 2'd2;
in[3] : pos = 2'd3;
default: pos = 2'd0;
endcase
end
endmodule
// synthesis verilog_input_version verilog_2001
module top_module (
input [7:0] in,
output reg [2:0] pos );
always@(*)begin
casez(in)
8'bzzzzzzz1: pos=3'd0;
8'bzzzzzz1z: pos=3'd1;
8'bzzzzz1zz: pos=3'd2;
8'bzzzz1zzz: pos=3'd3;
8'bzzz1zzzz: pos=3'd4;
8'bzz1zzzzz: pos=3'd5;
8'bz1zzzzzz: pos=3'd6;
8'b1zzzzzzz: pos=3'd7;
default:pos=3'd0;
endcase
end
endmodule
这里用到了“casez”
// synthesis verilog_input_version verilog_2001
module top_module (
input [15:0] scancode,
output reg left,
output reg down,
output reg right,
output reg up );
always@(*)begin
up=1'b0; down=1'b0; left=1'b0; right=1'b0;
case(scancode)
16'he06b:left=1'b1;
16'he072:down=1'b1;
16'he074:right=1'b1;
16'he075:up=1'b1;
endcase
end
endmodule
reg 置高
键盘那题
// synthesis verilog_input_version verilog_2001
module top_module (
input [15:0] scancode,
output reg left,
output reg down,
output reg right,
output reg up );
always@(*)begin
up = 1'b0;
down = 1'b0;
left = 1'b0;
right = 1'b0;
case(scancode)
16'he06b: left = 1'b1;
16'he072: down = 1'b1;
16'he074: right = 1'b1;
16'he075: up = 1'b1;
endcase
end
endmodule