Untitled
unknown
verilog
3 years ago
34 kB
7
Indexable
//3-1
module lab3_1
(
input clk,
input rst,
input en,
input speed,
output [15:0] led
);
wire my_clk;
reg [15:0] led;
clock_divider #(.n(24))clk_d1 (.clk(clk), .clk_div(my_clk));
reg [3:0] pos=15;
reg [3:0] next_pos=15;
reg [3:0] count=0;
reg [3:0] next_count=0;
integer i;
always @(posedge my_clk, posedge rst) begin
if(rst) begin
pos <= 15;
end
else begin
pos <= next_pos;
end
end
always @(*) begin
if(en) begin
if(speed == 0) begin
if(pos == 0) begin
next_pos <= 15;
end
else begin
next_pos <= pos-1;
end
end
else begin
if(count == 7) begin
if(pos == 0) begin
next_pos <= 15;
end
else begin
next_pos <= pos-1;
end
end
else begin
next_pos <= pos;
end
end
end
else begin
next_pos <= pos;
end
end
always @(posedge my_clk, posedge rst) begin
if(rst) begin
count <= 0;
end
else begin
count <= next_count;
end
end
always @(*) begin
if(en) begin
if(speed == 0) begin
next_count <= 0;
end
else begin
if(count == 7) begin
next_count <= 0;
end
else begin
next_count <= count + 1;
end
end
end
else begin
next_count <= 0;
end
end
always @(pos, count) begin
for(i=0; i<16; i=i+1) begin
led[i] = 0;
end
led[pos] = 1;
end
endmodule
module clock_divider #(parameter n = 25)(
input clk,
output clk_div
);
wire [n-1:0] next_num ;
reg [n-1:0] num =0;
always @(posedge clk) begin
num <= next_num;
end
assign next_num = num+1;
assign clk_div = num[n-1];
endmodule
//3-2
module lab3_2
(
input clk,
input rst,
input en,
input speed,
input freeze,
output [15:0] led
);
wire my_clk;
reg [15:0] led;
clock_divider #(.n(24))clk_d1 (.clk(clk), .clk_div(my_clk));
reg [3:0] m_pos=10;
reg [3:0] m_next_pos=10;
reg [3:0] c_pos=12;
reg [3:0] c_next_pos=12;
reg [1:0] m_win;
reg [1:0] next_m_win;
reg [1:0] c_win;
reg [1:0] next_c_win;
reg [3:0] race_count;
reg [3:0] next_race_count;
reg [3:0] speed_count;
reg [3:0] next_speed_count;
reg [3:0] state_count;
reg [3:0] next_state_count;
wire m_fin;
wire c_fin;
reg speedup=0;
integer i;
parameter INIT = 4'd0;
parameter RACE = 4'd1;
parameter MOTOR_FIN = 4'd2;
parameter MOTOR_WIN = 4'd3;
parameter CAR_FIN = 4'd4;
parameter CAR_WIN = 4'd5;
reg [3:0] state;
reg [3:0] next_state;
always @(posedge my_clk, posedge rst) begin
if(rst) begin
state <= INIT;
end
else begin
state <= next_state;
end
end
always @(*) begin
case(state)
INIT: begin
next_state <= RACE;
end
RACE: begin
if(m_fin == 1 && c_fin == 1) begin
next_state <= MOTOR_FIN;
end
else if(m_fin == 1) begin
next_state <= MOTOR_FIN;
end
else if (c_fin == 1) begin
next_state <= CAR_FIN;
end
else begin
next_state <= state;
end
end
MOTOR_FIN: begin
if(state_count == 7) begin
if(m_win == 3) begin
next_state <= MOTOR_WIN;
end
else begin
next_state <= RACE;
end
end
else begin
next_state <= state;
end
end
MOTOR_WIN: begin
if(state_count == 7) begin
next_state <= INIT;
end
else begin
next_state <= state;
end
end
CAR_FIN: begin
if(state_count == 7) begin
if(c_win == 3) begin
next_state <= CAR_WIN;
end
else begin
next_state <= RACE;
end
end
else begin
next_state <= state;
end
end
CAR_WIN: begin
if(state_count == 7) begin
next_state <= INIT;
end
else begin
next_state <= state;
end
end
endcase
end
always @(posedge my_clk, posedge rst) begin
if(rst) begin
c_pos <= 12;
end
else begin
c_pos <= c_next_pos;
end
end
always @(*) begin
case (state)
INIT: begin
c_next_pos <= 12;
speedup = 0;
end
RACE: begin
if(en) begin
if(speedup == 1 && speed_count<5) begin
c_next_pos <= c_pos-1;
end
else if(speed == 1 && speed_count == 0) begin
c_next_pos <= c_pos-1;
speedup = 1;
end
else begin
if(race_count == 7) begin
c_next_pos <= c_pos-1;
end
else begin
c_next_pos <= c_pos;
end
end
end
else begin
c_next_pos <= c_pos;
end
end
MOTOR_FIN: begin
if(state_count == 7) begin
c_next_pos <= 12;
end
else begin
c_next_pos <= c_pos;
end
speedup = 0;
end
CAR_FIN: begin
if(state_count == 7) begin
c_next_pos <= 12;
end
else begin
c_next_pos <= c_pos;
end
speedup = 0;
end
default: begin
c_next_pos <= c_pos;
end
endcase
end
always @(posedge my_clk, posedge rst) begin
if(rst) begin
m_pos <= 10;
end
else begin
m_pos <= m_next_pos;
end
end
always @(*) begin
case (state)
INIT: begin
m_next_pos <= 10;
end
RACE: begin
if(en) begin
if(race_count == 7) begin
if(freeze == 0) begin
m_next_pos <= m_pos-1;
end
else begin
m_next_pos <= m_pos;
end
end
else begin
m_next_pos <= m_pos;
end
end
else begin
m_next_pos <= m_pos;
end
end
MOTOR_FIN: begin
if(state_count == 7) begin
m_next_pos <= 10;
end
else begin
m_next_pos <= m_pos;
end
end
CAR_FIN: begin
if(state_count == 7) begin
m_next_pos <= 10;
end
else begin
m_next_pos <= m_pos;
end
end
default: begin
m_next_pos <= m_pos;
end
endcase
end
always @(posedge my_clk, posedge rst) begin
if(rst) begin
race_count <= 0;
end
else begin
race_count <= next_race_count;
end
end
always @(*) begin
case(state)
RACE: begin
if(en) begin
if(race_count == 7) begin
next_race_count = 0;
end
else begin
next_race_count = race_count+1;
end
end
else begin
next_race_count = 0;
end
end
default: begin
next_race_count <= 0;
end
endcase
end
always @(posedge my_clk, posedge rst) begin
if(rst) begin
speed_count <= 0;
end
else begin
speed_count <= next_speed_count;
end
end
always @(*) begin
case(state)
RACE: begin
if(en) begin
if(speedup == 1 && speed_count<5) begin
next_speed_count <= speed_count+1;
end
else if(speed == 1 && speed_count == 0) begin
next_speed_count <= speed_count+1;
end
else begin
next_speed_count <= speed_count;
end
end
else begin
next_speed_count <= speed_count;
end
end
default: begin
next_speed_count <= 0;
end
endcase
end
always @(posedge my_clk, posedge rst) begin
if(rst) begin
state_count <= 0;
end
else begin
state_count <= next_state_count;
end
end
always @(*) begin
case(state)
MOTOR_FIN: begin
if(state_count == 7) begin
next_state_count <= 0;
end
else begin
next_state_count <= state_count + 1;
end
end
MOTOR_WIN: begin
if(state_count == 7) begin
next_state_count <= 0;
end
else begin
next_state_count <= state_count + 1;
end
end
CAR_FIN: begin
if(state_count == 7) begin
next_state_count <= 0;
end
else begin
next_state_count <= state_count + 1;
end
end
CAR_WIN: begin
if(state_count == 7) begin
next_state_count <= 0;
end
else begin
next_state_count <= state_count + 1;
end
end
default: begin
next_state_count <= 0;
end
endcase
end
always @(posedge my_clk, posedge rst) begin
if(rst) begin
m_win <= 0;
end
else begin
m_win <= next_m_win;
end
end
always @(*) begin
case(state)
INIT: begin
next_m_win <= 0;
end
MOTOR_FIN: begin
if(state_count == 7) begin
if(m_win == 3) begin
next_m_win <= 0;
end
else begin
next_m_win <= m_win+1;
end
end
else begin
next_m_win <= m_win;
end
end
CAR_FIN: begin
if(state_count == 7) begin
if(c_win == 3) begin
next_m_win <= 0;
end
else begin
next_m_win <= m_win;
end
end
else begin
next_m_win <= m_win;
end
end
default: begin
next_m_win <= m_win;
end
endcase
end
always @(posedge my_clk, posedge rst) begin
if(rst) begin
c_win <= 0;
end
else begin
c_win <= next_c_win;
end
end
always @(*) begin
case(state)
INIT: begin
next_c_win <= 0;
end
MOTOR_FIN: begin
if(state_count == 7) begin
if(m_win == 3) begin
next_c_win <= 0;
end
else begin
next_c_win <= c_win;
end
end
else begin
next_c_win <= c_win;
end
end
CAR_FIN: begin
if(state_count == 7) begin
if(c_win == 3) begin
next_c_win <= 0;
end
else begin
next_c_win <= c_win+1;
end
end
else begin
next_c_win <= c_win;
end
end
default: begin
next_c_win <= c_win;
end
endcase
end
assign m_fin = (m_pos == 2) ? 1 : 0;
assign c_fin = (c_pos == 2) ? 1 : 0;
always @(*) begin
case (state)
INIT: begin
for(i=0; i<16; i=i+1) begin
led[i] <= 0;
end
led[m_pos] <= 1;
led[c_pos] <= 1;
led[c_pos+1] <= 1;
end
RACE: begin
for(i=2; i<14; i=i+1) begin
led[i] <= 0;
end
led[m_pos] <= 1;
led[c_pos] <= 1;
led[c_pos+1] <= 1;
led[1:0] <= m_win;
led[15:14] <= c_win;
end
MOTOR_FIN: begin
for(i=2; i<14; i=i+1) begin
led[i] <= 0;
end
led[m_pos] <= 1;
led[c_pos] <= 1;
led[c_pos+1] <= 1;
led[1:0] <= m_win;
led[15:14] <= c_win;
end
MOTOR_WIN: begin
for(i=0; i<16; i=i+1) begin
led[i] <= 1;
end
led[15:14] <= 0;
end
CAR_FIN: begin
for(i=2; i<14; i=i+1) begin
led[i] <= 0;
end
led[m_pos] <= 1;
led[2] <= 1;
led[3] <= 1;
led[1:0] <= m_win;
led[15:14] <= c_win;
end
CAR_WIN: begin
for(i=0; i<16; i=i+1) begin
led[i] <= 1;
end
led[1:0] <= 0;
end
default: begin
for(i=0; i<16; i=i+1) begin
led[i] <= led[i];
end
end
endcase
end
endmodule
module clock_divider #(parameter n = 25)(
input clk,
output clk_div
);
wire [n-1:0] next_num ;
reg [n-1:0] num =0;
always @(posedge clk) begin
num <= next_num;
end
assign next_num = num+1;
assign clk_div = num[n-1];
endmodule
//4-1
module lab4_1 (
input wire clk,
input wire rst,
input wire start,
input wire direction,
output reg [3:0] DIGIT,
output reg [6:0] DISPLAY,
output reg max,
output reg min
);
wire start_de;
wire start_1;
wire direction_de;
wire direction_1;
parameter INIT = 0;
parameter STOP = 1;
parameter COUNTING = 2;
reg [2:0] state;
reg [2:0] next_state;
wire fsm_clk;
wire count_clk;
reg [9:0] count;
reg [9:0] next_count;
wire [3:0] D1;
wire [3:0] D2;
wire [3:0] D3;
reg [3:0] value;
//0==UP 1==DOWN
reg dir;
reg next_dir;
clock_divider #(15) clock1(.clk(clk), .clk_div(fsm_clk));
clock_div clock2(.clk(clk), .clk_div(count_clk));
//assign fsm_clk = clk;
//assign count_clk = clk;
debounce de1(.clk(fsm_clk), .pb(start), .pb_debounced(start_de));
debounce de2(.clk(fsm_clk), .pb(direction), .pb_debounced(direction_de));
one_pulse pulse1(.clk(fsm_clk), .pb_in(start_de), .pb_out(start_1));
one_pulse pulse2(.clk(fsm_clk), .pb_in(direction_de), .pb_out(direction_1));
always @(posedge fsm_clk, posedge rst) begin
if(rst) begin
state <= INIT;
dir <= 0;
end
else begin
state <= next_state;
dir <= next_dir;
end
end
always @(*) begin
case (state)
INIT: begin
if(start_1) begin
next_state = STOP;
next_dir = dir;
end
else begin
next_state = state;
next_dir = dir;
end
end
STOP: begin
if(start_1) begin
next_state = COUNTING;
next_dir = dir;
end
else begin
next_state = state;
next_dir = dir;
end
end
COUNTING: begin
if(start_1) begin
next_state = STOP;
next_dir = dir;
end
else begin
next_state = state;
if(direction_1) begin
next_dir = dir^1;
end
else begin
next_dir = dir;
end
end
end
default: begin
next_state = state;
next_dir = dir;
end
endcase
end
always @(posedge count_clk, posedge rst) begin
if(rst) begin
count <= 50;
end
else begin
count <= next_count;
end
end
always @(*) begin
case (state)
INIT: begin
if(start_1) begin
next_count = count;
end
else begin
next_count = count;
end
end
STOP: begin
if(start_1) begin
next_count = count;
end
else begin
next_count = count;
end
end
COUNTING: begin
if(start_1) begin
next_count = count;
end
else begin
if(count == 999 && dir == 0) begin
next_count = count;
end
else if(count == 0 && dir == 1) begin
next_count = count;
end
else begin
if(dir == 0) begin
next_count = count+1;
end
else begin
next_count = count-1;
end
end
end
end
default: begin
next_count = count;
end
endcase
end
assign D1 = count % 10;
assign D2 = (count%100) / 10;
assign D3 = count / 100;
always @(posedge fsm_clk) begin
case(DIGIT)
4'b1110: begin
DIGIT <= 4'b1101;
case (state)
INIT: begin
value<=12;
end
default: begin
value <= D2;
end
endcase
end
4'b1101: begin
DIGIT <= 4'b1011;
case (state)
INIT: begin
value<=12;
end
default: begin
value <= D3;
end
endcase
end
4'b1011: begin
DIGIT <= 4'b0111;
case (state)
INIT: begin
value<=12;
end
STOP: begin
if(direction_de) begin
value <= 10+dir;
end
else begin
value <= 12;
end
end
COUNTING: begin
value <= 10+dir;
end
default: begin
value <= 12;
end
endcase
end
4'b0111: begin
DIGIT <= 4'b1110;
case (state)
INIT: begin
value<=12;
end
default: begin
value <= D1;
end
endcase
end
default: begin
DIGIT <= 4'b1110;
value <= 12;
end
endcase
end
always @(*) begin
case (value)
0: DISPLAY = 7'b100_0000;
1: DISPLAY = 7'b111_1001;
2: DISPLAY = 7'b010_0100;
3: DISPLAY = 7'b011_0000;
4: DISPLAY = 7'b001_1001;
5: DISPLAY = 7'b001_0010;
6: DISPLAY = 7'b000_0010;
7: DISPLAY = 7'b111_1000;
8: DISPLAY = 7'b000_0000;
9: DISPLAY = 7'b001_0000;
10: DISPLAY = 7'b101_1100;
11: DISPLAY = 7'b110_0011;
12: DISPLAY = 7'b011_1111;
default: DISPLAY = 7'b111_1111;
endcase
end
always @(posedge fsm_clk, posedge rst) begin
if(rst) begin
max <= 0;
min <= 0;
end
else begin
max = (count == 999) ? 1 : 0;
min = (count == 0) ? 1 : 0;
end
end
endmodule
module clock_div (
input wire clk,
output wire clk_div
);
reg [27:0] count;
wire [27:0] next_count;
always @(posedge clk) begin
if(count==10000000) begin
count <= 0;
end
else begin
count <= next_count;
end
end
assign next_count = count + 1;
assign clk_div = (count==10000000);
endmodule
//4-2
module lab4_2 (
input wire clk,
input wire rst,
input wire start,
input wire direction,
input wire increase,
input wire decrease,
input wire select,
output reg [3:0] DIGIT,
output reg [6:0] DISPLAY,
output reg max,
output reg min,
output reg d2,
output reg d1,
output reg d0
);
wire start_de;
wire start_1;
wire direction_de;
wire direction_1;
wire increase_de;
wire increase_1;
wire decrease_de;
wire decrease_1;
wire select_de;
wire select_1;
parameter INIT = 0;
parameter STOP = 1;
parameter COUNTING = 2;
reg [2:0] state;
reg [2:0] next_state;
wire fsm_clk;
wire count_clk;
reg update_clk;
reg [9:0] count;
reg [9:0] next_count;
wire [3:0] D1;
wire [3:0] D2;
wire [3:0] D3;
reg [3:0] value;
//0==UP 1==DOWN
reg dir;
reg next_dir;
reg [1:0] s_digit;
reg [1:0] next_s_digit;
clock_divider #(15) clock1(.clk(clk), .clk_div(fsm_clk));
clock_div clock2(.clk(clk), .clk_div(count_clk));
debounce de1(.clk(fsm_clk), .pb(start), .pb_debounced(start_de));
debounce de2(.clk(fsm_clk), .pb(direction), .pb_debounced(direction_de));
debounce de3(.clk(fsm_clk), .pb(increase), .pb_debounced(increase_de));
debounce de4(.clk(fsm_clk), .pb(decrease), .pb_debounced(decrease_de));
debounce de5(.clk(fsm_clk), .pb(select), .pb_debounced(select_de));
one_pulse pulse1(.clk(fsm_clk), .pb_in(start_de), .pb_out(start_1));
one_pulse pulse2(.clk(fsm_clk), .pb_in(direction_de), .pb_out(direction_1));
one_pulse pulse3(.clk(fsm_clk), .pb_in(increase_de), .pb_out(increase_1));
one_pulse pulse4(.clk(fsm_clk), .pb_in(decrease_de), .pb_out(decrease_1));
one_pulse pulse5(.clk(fsm_clk), .pb_in(select_de), .pb_out(select_1));
always @(posedge fsm_clk, posedge rst) begin
if(rst) begin
state <= INIT;
dir <= 0;
end
else begin
state <= next_state;
dir <= next_dir;
end
end
always @(*) begin
case (state)
INIT: begin
if(start_1) begin
next_state = STOP;
next_dir = dir;
end
else begin
next_state = state;
next_dir = dir;
end
end
STOP: begin
if(start_1) begin
next_state = COUNTING;
next_dir = dir;
end
else begin
next_state = state;
next_dir = dir;
end
end
COUNTING: begin
if(start_1) begin
next_state = STOP;
next_dir = dir;
end
else begin
next_state = state;
if(direction_1) begin
next_dir = dir^1;
end
else begin
next_dir = dir;
end
end
end
default: begin
next_state = state;
next_dir = dir;
end
endcase
end
always @(posedge update_clk, posedge rst) begin
if(rst) begin
count <= 50;
end
else begin
count <= next_count;
end
end
always @(*) begin
case (state)
INIT: begin
if(start_1) begin
next_count = count;
end
else begin
next_count = count;
end
end
STOP: begin
if(start_1) begin
next_count = count;
end
else begin
if(increase_1) begin
case (s_digit)
0: begin
if(D1!=9) begin
next_count = count+1;
end
else begin
next_count = count-9;
end
end
1: begin
if(D2!=9) begin
next_count = count+10;
end
else begin
next_count = count-90;
end
end
2: begin
if(D3!=9) begin
next_count = count+100;
end
else begin
next_count = count-900;
end
end
default: begin
next_count = count;
end
endcase
end
else if(decrease_1) begin
case (s_digit)
0: begin
if(D1!=0) begin
next_count = count-1;
end
else begin
next_count = count+9;
end
end
1: begin
if(D2!=0) begin
next_count = count-10;
end
else begin
next_count = count+90;
end
end
2: begin
if(D3!=0) begin
next_count = count-100;
end
else begin
next_count = count+900;
end
end
default: begin
next_count = count;
end
endcase
end
else begin
next_count = count;
end
end
end
COUNTING: begin
if(start_1) begin
next_count = count;
end
else begin
if(count == 999 && dir == 0) begin
next_count = count;
end
else if(count == 0 && dir == 1) begin
next_count = count;
end
else begin
if(dir == 0) begin
next_count = count+1;
end
else begin
next_count = count-1;
end
end
end
end
default: begin
next_count = count;
end
endcase
end
assign D1 = count % 10;
assign D2 = (count%100) / 10;
assign D3 = count / 100;
always @(posedge fsm_clk) begin
case(DIGIT)
4'b1110: begin
DIGIT <= 4'b1101;
case (state)
INIT: begin
value<=12;
end
default: begin
value <= D2;
end
endcase
end
4'b1101: begin
DIGIT <= 4'b1011;
case (state)
INIT: begin
value<=12;
end
default: begin
value <= D3;
end
endcase
end
4'b1011: begin
DIGIT <= 4'b0111;
case (state)
INIT: begin
value<=12;
end
STOP: begin
if(direction_de) begin
value <= 10+dir;
end
else begin
value <= 12;
end
end
COUNTING: begin
value <= 10+dir;
end
default: begin
value <= 12;
end
endcase
end
4'b0111: begin
DIGIT <= 4'b1110;
case (state)
INIT: begin
value<=12;
end
default: begin
value <= D1;
end
endcase
end
default: begin
DIGIT <= 4'b1110;
value <= 12;
end
endcase
end
always @(*) begin
case (value)
0: DISPLAY = 7'b100_0000;
1: DISPLAY = 7'b111_1001;
2: DISPLAY = 7'b010_0100;
3: DISPLAY = 7'b011_0000;
4: DISPLAY = 7'b001_1001;
5: DISPLAY = 7'b001_0010;
6: DISPLAY = 7'b000_0010;
7: DISPLAY = 7'b111_1000;
8: DISPLAY = 7'b000_0000;
9: DISPLAY = 7'b001_0000;
10: DISPLAY = 7'b101_1100;
11: DISPLAY = 7'b110_0011;
12: DISPLAY = 7'b011_1111;
default: DISPLAY = 7'b111_1111;
endcase
end
always @(posedge fsm_clk, posedge rst) begin
if(rst) begin
max <= 0;
min <= 0;
end
else begin
max = (count == 999) ? 1 : 0;
min = (count == 0) ? 1 : 0;
end
end
always @(posedge fsm_clk, posedge rst) begin
if(rst) begin
s_digit <= 0;
end
else begin
s_digit <= next_s_digit;
end
end
always @(*) begin
case (state)
STOP: begin
if(select_1) begin
if(s_digit == 0) next_s_digit = 1;
else if(s_digit == 1) next_s_digit = 2;
else next_s_digit = 0;
end
else begin
next_s_digit = s_digit;
end
end
default: begin
next_s_digit = 0;
end
endcase
end
always @(posedge fsm_clk, posedge rst) begin
if(state == STOP) begin
if(rst) begin
d0 <= 1;
d1 <= 0;
d2 <= 0;
end
else begin
d0 <= (s_digit == 0);
d1 <= (s_digit == 1);
d2 <= (s_digit == 2);
end
end
else begin
d0 <= 0;
d1 <= 0;
d2 <= 0;
end
end
always @(*) begin
if(state == STOP) begin
update_clk <= fsm_clk;
end
else begin
update_clk <= count_clk;
end
end
endmodule
module clock_div (
input wire clk,
output wire clk_div
);
reg [27:0] count;
wire [27:0] next_count;
always @(posedge clk) begin
if(count==10000000) begin
count <= 0;
end
else begin
count <= next_count;
end
end
assign next_count = count + 1;
assign clk_div = (count==10000000);
endmodule
Editor is loading...