Детектор паттернов FSM в verilog

#verilog #fsm

Вопрос:

Я пытаюсь создать конечный автомат , который обнаруживает 12-битный шаблон 110001010111 , но я не могу поставить галочку там, где она должна быть. Я добавил код, тестовый стенд и форму сигнала, которую я получил.

Код:

 module seqdet  (input clk,rst,  input wire in,  output reg y);   parameter w=4'b0000,a=4'b0001,b=4'b0010,c=4'b0011,d=4'b0100,e=4'b0101,f=4'b0110,g=4'b0111,  h=4'b1000,i=4'b1001,j=4'b1010,k=4'b1011,l=4'b1100;   //wire in=Q;  //assign in=Q[17:6];*/    reg [3:0] nst, st;   always @ (posedge clk)   begin  if (rst) st lt;= w;  else st lt;= nst;  end  always @ *  begin  nst =st;  y = 1'b0;  case(st)  w: if(in) nst =a;  a: if(in)  nst =b;  else   nst =w;  b: if(in)  nst =b;   else   nst =c;  c: if(in)  nst =a;   else   nst =d;   d: if(in)  nst =a;   else   nst =e;   e: if(in)  nst =f;   else   nst =w;   f: if(in)  nst =b;   else   nst =g;   g: if(in)  nst =h;   else   nst =w;   h: if(in)  nst =b;   else   nst =i;   i: if(in)  nst =j;   else   nst =w;   j:if(in)  nst =k;   else   nst =w;   k: if(in)  nst =l;   else   nst =c;   l: begin y=1'b1;  if(in)  nst =l;   else   nst =c;   end  default:nst =w;  endcase  end endmodule  

Испытательный стенд:

 `timescale 1ns / 1ns module fsm_detector_tb();  //declerations  parameter T = 20; //clock period in nanoseconds  reg clk, reset;  reg test_input;  wire test_tick;    seqdet uut(  .clk(clk),  .rst(reset),  .in(test_input),  .y(test_tick)  );   // clock  // 20 ns clock running forever  always  begin  clk = 1'b1; //high  #(T/2); // delay half a period  clk = 1'b0; //low  #(T/2); // delay half a period  end   initial  begin  // reset = 1'b1;  // test_input = 1'b0;  // #(2*T); // delay two clock cycle   reset = 1'b0;  test_input = 1'b1;  #(T); // delay one clock cycle  test_input = 1'b1;  #(T); // delay one clock cycle  test_input = 1'b0;  #(T); // delay one clock cycle  test_input = 1'b0;  #(T); // delay one clock cycle  test_input = 1'b0;  #(T); // delay one clock cycle  test_input = 1'b1;  #(T); // delay one clock cycle  test_input = 1'b0;  #(T); // delay one clock cycle  test_input = 1'b1;  #(T); // delay one clock cycle  test_input = 1'b0;  #(T); // delay one clock cycle  test_input = 1'b1;  #(T);  test_input = 1'b1;  #(T);  test_input = 1'b1;  #(T);  $finish;   end   endmodule  

Это форма волны, которую я получаю

Выход должен быть высоким там, где он отмечен на форме сигнала, и я не могу понять, где это пошло не так.

Комментарии:

1. b: if(in) nst = b; else nst = c; — можете ли вы объяснить, почему вы считаете это правильным?

2. Где это st в симуляции?

Ответ №1:

Проблема в тестовом стенде. Входы неправильно синхронизированы с часами. Вы должны управлять входными данными в тестовой среде так же, как вы управляете ими внутри кода разработки: используйте @(posedge clk) и неблокирующие назначения ( lt;= ) вместо # задержек и блокировок назначений. Замените свой initial блок следующим:

 initial begin  reset = 1;  test_input = 0;   repeat (2) @(posedge clk); reset lt;= 0;   @(posedge clk) test_input lt;= 1;  @(posedge clk) test_input lt;= 1;  @(posedge clk) test_input lt;= 0;  @(posedge clk) test_input lt;= 0;  @(posedge clk) test_input lt;= 0;  @(posedge clk) test_input lt;= 1;  @(posedge clk) test_input lt;= 0;  @(posedge clk) test_input lt;= 1;  @(posedge clk) test_input lt;= 0;  @(posedge clk) test_input lt;= 1;  @(posedge clk) test_input lt;= 1;  @(posedge clk) test_input lt;= 1;   repeat (3) @(posedge clk);  $finish; end  

Это гарантирует, что симулятор будет работать так, как ожидалось. Я вижу test_tick , что поднимаюсь высоко, когда ты этого ожидаешь.

волны


Этот код также утверждает сброс во время 0, а затем выпускает его через пару циклов, что гарантирует, что ваш дизайн будет сброшен правильно.