Воистину, Бытиё - это слоенный пирог, и мы все потребляем его разные слои. Особенно когда речь заходит о роботах. Этот тезис иллюстрирует телепередача о студентах
1i7 из Нижегородского Государственного Технического Университета, изготавливающих роботов на основе микросхем программируемой логики в рамках экспериментального курса лабораторных работ "Цифровая электроника для математиков и программистов". В разработке этого курса помимо Антона Моисеева также приняли участие я (
panchul),
ramlamyammambam и
ammosov. Перечислю слои этого пирога, которые вижу я:
Слой телепередачи (для бабушек и внучат):
http://vimeo.com/44303100 Цифровые микроэлектронные биороботы на СетиНН from
1i7 on
Vimeo.
Слой съемки телепередачи:
Уровень диаграммы состояний конечного автомата робота:
Слой описания конечного автомата робота с помощью языка описания хардвера Verilog (мой вариант, варианты Антона Моисеева и его студентов отличаются):
http://panchul.com/education/2012_04_19_scorpion/sources/ module scorpion
(
input clock,
input reset_n,
input danger,
input use_posedge_danger,
output reg retreat,
output reg attack,
output [2:0] out_state
);
parameter state_wait_for_1st_danger = 3'd0,
state_1st_danger_action = 3'd1,
state_wait_for_2nd_danger = 3'd2,
state_2nd_danger_action = 3'd3,
state_wait_for_3rd_danger = 3'd4,
state_3rd_danger_action = 3'd5;
reg previous_danger;
always @ (posedge clock or negedge reset_n)
begin
if (! reset_n)
previous_danger <= 0;
else
previous_danger <= danger;
end
wire danger_indicator
= use_posedge_danger ?
danger & ~ previous_danger : danger;
reg timer_start;
reg timer_two_seconds;
wire timer_finish;
timer timer
(
.clock ( clock ),
.reset_n ( reset_n ),
.start ( timer_start ),
.two_seconds ( timer_two_seconds ),
.finish ( timer_finish )
);
reg [2:0] state, next_state;
assign out_state = state;
always @ (*)
begin
timer_start = 0;
timer_two_seconds = 0;
next_state = state;
case (state)
state_wait_for_1st_danger:
if (danger_indicator)
begin
timer_start = 1;
next_state = state_1st_danger_action;
end
state_1st_danger_action:
if (timer_finish)
next_state = state_wait_for_2nd_danger;
state_wait_for_2nd_danger:
if (danger_indicator)
begin
timer_start = 1;
next_state = state_2nd_danger_action;
end
state_2nd_danger_action:
if (timer_finish)
next_state = state_wait_for_3rd_danger;
state_wait_for_3rd_danger:
if (danger_indicator)
begin
timer_start = 1;
timer_two_seconds = 1;
next_state = state_3rd_danger_action;
end
state_3rd_danger_action:
if (timer_finish)
next_state = state_wait_for_1st_danger;
endcase
end
wire next_retreat
= state == state_1st_danger_action
|| state == state_2nd_danger_action;
wire next_attack
= state == state_3rd_danger_action;
always @ (posedge clock or negedge reset_n)
begin
if (! reset_n)
begin
retreat <= 0;
attack <= 0;
state <= state_wait_for_1st_danger;
end
else
begin
retreat <= next_retreat;
attack <= next_attack;
state <= next_state;
end
end
endmodule
UPD: Переделал reset с sync на asynch с негативной логикой по рекомендации
peacemaker_1. Хотя для данного дизайна это некритично, тем не менее (см. дискуссию в конце поста).
Уровень схемы, реализующей конечный автомат, перед оптимизацией и mapping:
Уровень схемы после mapping на логические блоки программируемой пользователем вентильной матрицы:
См. для справки википедию
Программируемая пользователем вентильная матрица Картинка floorplan FPGA после place & route:
Уровень логического элемента FPGA:
Уровень EDA софтвера который использует дизайнер конечного автомата для электронных мозгов робота, построенного на FPGA:
Poll ljpromo, приди!