一、將一個串行執行的C語言算法轉化爲單拍完成的並行可綜合verilog
unsigned char cal_table_high_first(unsigned char value)
{
unsigned char i ;
unsigned char checksum = value ;
for (i=8;i>0;--i)
{
if (check_sum & 0x80)
{
check_sum = (check_sum<<1) ^ 0x31;
}
else
{
check_sum = (check_sum << 1);
}
}
return check_sum;
}
相當於
module loop(
input clk,
input rst_n,
input [7:0] value,
output reg [7:0] checksum);
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
checksum<=0;
else
begin
for(i=0;i<8;i--)
checksum<={value[6:0],1'b0}^(8{value[7]}&8'h31);
end
end
endmodule
二、設計一個序列信號發生器電路,能在CLK信號作用下週期性輸出“0010110111”的序列信號
(相當於使用移位寄存器串行輸出,左移或者右移均可)
module sequence(
input clk,
input rst_n,
output sequence_out);
reg [9:0]sequence;
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
sequence<=10'd0;
else
sequence<={sequence[0],sequence[9:1]};
end
assign sequence_out=sequence[0];
endmodule
三、設計一個自動飲料售賣機,共有兩種飲料,其中飲料A每個10分錢,飲料B每個5分錢,硬幣有5分和10分兩種,並考慮找零。要求用狀態機實現,定義狀態,畫出狀態轉移圖,並用Verilog完整描述該模塊
module state(
input A,//5fen
input B,//10fen
output reg okay_A,
output reg okay_B,
output reg [2:0] coin,
input clk,
input rst_n,
input mode//0爲5fen,1爲10fen);
reg [1:0] state;
parameter idle = 3'b00;
parameter s1 = 3'b001;
parameter s2 = 3'b010;
parameter s3 = 3'b011;
parameter s4 = 3'b100;
parameter s5 = 3'b101;
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
state<=idle;
else
case(state)
idle:
begin
if(!mode&&A)
begin
state<=s1;//投5分錢買5分錢的飲料
end
else if(mode&&B)
begin
state<=s2;//投10分錢買10分錢的飲料
end
else if(mode&&A)
begin
state<=s3;//投5分錢買10分錢的飲料
end
else if(!mode&&B)
begin
state<=s4;//投10分錢買5分錢的飲料
end
end
s1:
begin
state<=idle;
end
s2:
state<=idle;
s3:
state<=s5;//繼續投錢
s4:
state<=idle;
s5:
state<=idle;
always@(posedge clk or negedge rst_n)
begin
case(state):
idle:
begin
okay_A<=0;
okay_B<=0;
coin<=0;
end
s1:
begin
okay_A<=1;
end
s2:
okay_B<=1;
s3:
begin
okay_A<=0;
okay_B<=0;
coin<=0;
end
s4:
begin
okay_A<=1;
okay_B<=0;
coin<=3'd5;
end
s5:
begin
if(A&&!B)
okay_B<=1;
else(!A&&B)
begin
okay_B<=1;
coin<=3'd5;
end
end
endcase
end
endmodule
四、請實現對(1011001)2的序列檢測功能,模塊每拍並行輸入2bit,且順序爲高位先輸入,當檢測到序列,輸出一拍高電平脈衝。請用Verilog描述該模塊
即檢測兩種情況:
(1)10_11_00_1x
(2) x1_01_10_01
module test(
input [1:0] data,
output pulse);
reg [3:0] state;
reg pulse1;
reg pulse2;
parameter idle = 4'b0000;
parameter s1 = 4'b0001;
parameter s2 = 4'b0010;
parameter s3 = 4'b0011;
parameter s4 = 4'b0100;
parameter s5 = 4'b0101;
parameter s6 = 4'b0110;
parameter s7 = 4'b0111;
parameter s8 = 4'b1000;
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
state<=idle;
else
begin
case(state)
idle:
begin
if(data==2'b10)
state<=s1;
else if(data[0]==1'b1)
state<=s5;
end
s1:
begin
if(data==11)
state<=s2;
else
state<=idle;
end
s2:
begin
if(data==2'b00)
state<=s3;
else
state<=idle;
end
s3:
begin
if(data[1]=1'b1)
state<=s4;
else
state<=idle;
end
s4:
state<=idle;
s5:
begin
if(data==2'b01)
state<=s6;
else
state<=idle;
end
s6:
begin
if(data==2'b10)
state<=s7;
else
state<=idle;
end
s7:
begin
if(data==2'b01)
state<=s8;
else
state<=idle;
end
endcase
end
end
always@(posedge clk or negedge rst_n)
begin
case(state):
s4:
pulse1<=1'b1;
s8:
pulse1<1'b1;
default:
pulse1<=1'b0;
endcase
end
always@(posedge clk or negedge rst_n)
begin
pulse2<=pulse1;
end
assign pulse=pulse1&pulse2;
endmodule
五、請基於f = 100Hz的Clock設計一個數字時鐘,用Verilog實現以下功能
1、產生時、分、秒的計時
2、可通過3個按鍵來設置時、分、秒值
module clock(
input clk ,
input rst_n ,
input hour_set,
input [4:0] hour_set_value ,
input minute_set,
input [5:0] minute_set_value ,
input second_set ,
input [5:0] second_set_value ,
output [5:0] second_out ,
output [5:0] minute_out ,
output [4:0] hour_out
);
reg [5:0] second_reg ;
reg [5:0] minute_reg ;
reg [4:0] hour_reg ;
always@(posedge clk or negedge rst_n ) begin
if(!rst_n) begin
second_reg <= 0 ;
end
else if(second_set) second_reg <= second_set_value ;
else if(second_reg == 59) second_reg <= 0;
else second_reg <= second_reg +1 ;
end
always@(posedge clk or negedge rst_n ) begin
if(!rst_n) begin
minute_reg <= 0 ;
end
else if(minute_set) minute_reg <= minute_set_value ;
else if(minute_reg == 59 && second_reg == 59) minute_reg <= 0;
else if(second_reg == 59) minute_reg <= minute_reg +1 ;
end
always@(posedge clk or negedge rst_n ) begin
if(!rst_n) begin
hour_reg <= 0 ;
end
else if(hour_set) hour_reg <= hour_set_value ;
else if(hour_reg == 23 && minute_reg == 59 && second_reg == 59) hour_reg <= 0;
else if(minute_reg == 59 && second_reg == 59 ) hour_reg <= hour_reg +1 ;
end
assign second_out = second_reg ;
assign minute_out = minute_reg;
assign hour_out = hour_reg;
endmodule