當試圖編譯和模擬Verilog模塊和激勵時,我收到了一些奇怪的結果。如果我在筒倉中模擬它,則代碼按預期運行。如果我在Icarus(iverlog和vvp)中模擬它,時間不同於筒倉(從0開始而不是200,我不關心筒倉有235 - > 255,而伊卡洛斯有235 - > 265)。 Silos重複功能按我的預期工作,但使用Icarus時,我似乎無法弄清楚他們是如何得到這個結果的。另外,將重複R2GDELAY更改爲3時,Icarus似乎也沒有按預期那樣進行預成型。在使用Icarus時,我是否缺少某些東西,例如我必須手動將開始時間設置爲0,以便稍後在模擬中獲得準確結果,或者筒倉自動初始化我必須在Icarus中手動執行的變量?此代碼是採取形式的Verilog HDL語言的書,可以在這裏找到http://authors.phptr.com/palnitkar/Icarus產生與筒倉不同的結果
下面是代碼:
`define TRUE 1'b1
`define FALSE 1'b0
`define RED 2'd0
`define YELLOW 2'd1
`define GREEN 2'd2
//State definition HWY CNTRY
`define S0 3'd0 //GREEN RED
`define S1 3'd1 //YELLOW RED
`define S2 3'd2 //RED RED
`define S3 3'd3 //RED GREEN
`define S4 3'd4 //RED YELLOW
//Delays
`define Y2RDELAY 3 //Yellow to red delay
`define R2GDELAY 2 //Red to Green Delay
module sig_control (hwy, cntry, X, clock, clear);
//I/O ports
output [1:0] hwy, cntry;
//2 bit output for 3 states of signal
//GREEN, YELLOW, RED;
reg [1:0] hwy, cntry;
//declare output signals are registers
input X;
//if TRUE, indicates that there is car on
//the country road, otherwise FALSE
input clock, clear;
//Internal state variables
reg [2:0] state;
reg [2:0] next_state;
initial
begin
state = `S0;
next_state = `S0;
hwy = `GREEN;
cntry = `RED;
end
//state changes only at positive edge of clock
always @(posedge clock)
state = next_state;
//Compute values of main signal and country signal
always @(state)
begin
case(state)
`S0: begin
hwy = `GREEN;
cntry = `RED;
end
`S1: begin
hwy = `YELLOW;
cntry = `RED;
end
`S2: begin
hwy = `RED;
cntry = `RED;
end
`S3: begin
hwy = `RED;
cntry = `GREEN;
end
`S4: begin
hwy = `RED;
cntry = `YELLOW;
end
endcase
end
//State machine using case statements
always @(state or X)
begin
if(clear)
next_state = `S0;
else
case (state)
`S0: if(X)
next_state = `S1;
else
next_state = `S0;
`S1: begin //delay some positive edges of clock
repeat(`Y2RDELAY) @(posedge clock) ;
next_state = `S2;
end
`S2: begin //delay some positive edges of clock
//EDIT ADDED SEMICOLON
repeat(`R2GDELAY) @(posedge clock);
next_state = `S3;
end
`S3: if(X)
next_state = `S3;
else
next_state = `S4;
`S4: begin //delay some positive edges of clock
repeat(`Y2RDELAY) @(posedge clock) ;
next_state = `S0;
end
default: next_state = `S0;
endcase
end
endmodule
//Stimulus Module
module stimulus;
wire [1:0] MAIN_SIG, CNTRY_SIG;
reg CAR_ON_CNTRY_RD;
//if TRUE, indicates that there is car on
//the country road
reg CLOCK, CLEAR;
//Instantiate signal controller
sig_control SC(MAIN_SIG, CNTRY_SIG, CAR_ON_CNTRY_RD, CLOCK, CLEAR);
//Setup monitor
initial
$monitor($time, " Main Sig = %b Country Sig = %b Car_on_cntry = %b",
MAIN_SIG, CNTRY_SIG, CAR_ON_CNTRY_RD);
//setup clock
initial
begin
CLOCK = `FALSE;
forever #5 CLOCK = ~CLOCK;
end
//control clear signal
initial
begin
CLEAR = `TRUE;
repeat (5) @(negedge CLOCK);
CLEAR = `FALSE;
end
//apply stimulus
initial
begin
CAR_ON_CNTRY_RD = `FALSE;
#200 CAR_ON_CNTRY_RD = `TRUE;
#100 CAR_ON_CNTRY_RD = `FALSE;
#200 CAR_ON_CNTRY_RD = `TRUE;
#100 CAR_ON_CNTRY_RD = `FALSE;
#200 CAR_ON_CNTRY_RD = `TRUE;
#100 CAR_ON_CNTRY_RD = `FALSE;
#100 $finish;
end
endmodule
這裏是從筒倉輸出:
200 Main Sig = 10 Country Sig = 00 Car_on_cntry = 1
205 Main Sig = 01 Country Sig = 00 Car_on_cntry = 1
235 Main Sig = 00 Country Sig = 00 Car_on_cntry = 1
255 Main Sig = 00 Country Sig = 10 Car_on_cntry = 1
300 Main Sig = 00 Country Sig = 10 Car_on_cntry = 0
305 Main Sig = 00 Country Sig = 01 Car_on_cntry = 0
335 Main Sig = 10 Country Sig = 00 Car_on_cntry = 0
500 Main Sig = 10 Country Sig = 00 Car_on_cntry = 1
505 Main Sig = 01 Country Sig = 00 Car_on_cntry = 1
535 Main Sig = 00 Country Sig = 00 Car_on_cntry = 1
555 Main Sig = 00 Country Sig = 10 Car_on_cntry = 1
600 Main Sig = 00 Country Sig = 10 Car_on_cntry = 0
605 Main Sig = 00 Country Sig = 01 Car_on_cntry = 0
635 Main Sig = 10 Country Sig = 00 Car_on_cntry = 0
800 Main Sig = 10 Country Sig = 00 Car_on_cntry = 1
805 Main Sig = 01 Country Sig = 00 Car_on_cntry = 1
835 Main Sig = 00 Country Sig = 00 Car_on_cntry = 1
855 Main Sig = 00 Country Sig = 10 Car_on_cntry = 1
900 Main Sig = 00 Country Sig = 10 Car_on_cntry = 0
905 Main Sig = 00 Country Sig = 01 Car_on_cntry = 0
935 Main Sig = 10 Country Sig = 00 Car_on_cntry = 0
下面是從輸出iverilog:
0 Main Sig = 10 Country Sig = 00 Car_on_cntry = 0
200 Main Sig = 10 Country Sig = 00 Car_on_cntry = 1
205 Main Sig = 01 Country Sig = 00 Car_on_cntry = 1
235 Main Sig = 00 Country Sig = 00 Car_on_cntry = 1
265 Main Sig = 00 Country Sig = 10 Car_on_cntry = 1
300 Main Sig = 00 Country Sig = 10 Car_on_cntry = 0
305 Main Sig = 00 Country Sig = 01 Car_on_cntry = 0
335 Main Sig = 10 Country Sig = 00 Car_on_cntry = 0
500 Main Sig = 10 Country Sig = 00 Car_on_cntry = 1
505 Main Sig = 01 Country Sig = 00 Car_on_cntry = 1
535 Main Sig = 00 Country Sig = 00 Car_on_cntry = 1
565 Main Sig = 00 Country Sig = 10 Car_on_cntry = 1
600 Main Sig = 00 Country Sig = 10 Car_on_cntry = 0
605 Main Sig = 00 Country Sig = 01 Car_on_cntry = 0
635 Main Sig = 10 Country Sig = 00 Car_on_cntry = 0
800 Main Sig = 10 Country Sig = 00 Car_on_cntry = 1
805 Main Sig = 01 Country Sig = 00 Car_on_cntry = 1
835 Main Sig = 00 Country Sig = 00 Car_on_cntry = 1
865 Main Sig = 00 Country Sig = 10 Car_on_cntry = 1
900 Main Sig = 00 Country Sig = 10 Car_on_cntry = 0
905 Main Sig = 00 Country Sig = 01 Car_on_cntry = 0
935 Main Sig = 10 Country Sig = 00 Car_on_cntry = 0
編輯:如上面代碼中所示添加分號。
感謝您的幫助!
這是使用'repeat @(posedge clock)'編碼狀態機的奇怪方法。通常情況下,你會使用一個合適的順序邏輯塊。 – toolic