Неисправные выходы для реализации диаграммы состояния JK-триггера - PullRequest
0 голосов
/ 01 июля 2018

Я пытаюсь реализовать простой FSM JK триггер в Verilog. Однако я вижу, что выходные данные 'q' и 'q_not' неверны для нескольких моментов времени. Я представляю код и вывод ниже. Может кто-нибудь, пожалуйста, дайте мне знать, что не так с кодом. Особенно мне хотелось бы знать, что не так с этой реализацией, хотя существуют и другие способы реализации JK-триггеров.

модули JK-триггера и испытательного стенда

`timescale 1ns/100ps

module jk_ff(j, k, clk, reset, q, q_not);

input j, k, clk, reset;

output reg q, q_not;

reg present_state, next_state;

parameter state_a = 1'b0;
parameter state_b = 1'b1;

always @ (present_state or j or k)
begin:comb_logic

 next_state = state_a;
 //next_state = 0;

 case(present_state)

  state_a: begin
   if (j == 1'b0 && k == 1'b0) begin
     next_state = state_a;
     end
   else if (j == 1'b0 && k == 1'b1) begin
     next_state = state_a;
     end
   else if (j == 1'b1 && k == 1'b0) begin
     next_state = state_b;
     end
   else if (j == 1'b1 && k == 1'b1) begin
     next_state = state_b;
     end
   end

  state_b: begin
   if (j == 1'b0 && k == 1'b0) begin
     next_state =  state_b;
   end
   else if (j == 1'b0 && k == 1'b1) begin
     next_state = state_a;
   end
   else if (j == 1'b1 && k == 1'b0) begin
     next_state = state_b;
   end
   else if (j == 1'b1 && k == 1'b1) begin
     next_state = state_a;
   end
  end
  default: next_state = state_a;
 endcase 
end

always @ (posedge clk or reset)
begin: seq_logic

if (reset) begin
 q <= 1'b0;
 q_not <= 1'b1;
 present_state <= state_a;
 end
 else begin
 present_state <= next_state;

 case(present_state)

   state_a: begin
    q <= 1'b0;
    q_not <= 1'b1;
   end
   state_b: begin
    q <= 1'b1;
    q_not <= 1'b0;
   end
   default: present_state <= state_a;

  endcase
  end
 end

endmodule

//testbench

module jk_ff_tb;

reg j, k, clk, reset;

wire q, q_not;

jk_ff DUT(.j(j), .k(k), .clk(clk), .reset(reset), .q(q), .q_not(q_not));

initial begin
clk =0;
forever #5 clk = !clk;
end

initial begin
 $monitor("j = %b, k = %b, q = %b, q_not = %b", j, k, q, q_not);
 $dumpfile("jk_ff_wave.vcd");
 $dumpvars;
 reset = 1;
 j=1'b0;
 k=1'b1;
#10 reset = 0;

 #15 j=1'b1;
 #15 k=1'b0;
 #15 j=1'b0;
 #15 k=1'b1;
 #15 j=1'b1;
 #15 k=1'b1;


 #10 $finish;  

end

endmodule

результаты моделирования на испытательном стенде, показывающие значения входов и первичных выходов

j = 0, k = 1, reset = 1, q = 0, q_not = 1
j = 0, k = 1, reset = 0, q = 0, q_not = 1
j = 1, k = 1, reset = 0, q = 0, q_not = 1
j = 1, k = 1, reset = 0, q = 1, q_not = 0
j = 1, k = 0, reset = 0, q = 1, q_not = 0
j = 1, k = 0, reset = 0, q = 0, q_not = 1
j = 0, k = 0, reset = 0, q = 1, q_not = 0
j = 0, k = 1, reset = 0, q = 1, q_not = 0
j = 1, k = 1, reset = 0, q = 0, q_not = 1
j = 1, k = 1, reset = 0, q = 1, q_not = 0
j = 1, k = 1, reset = 0, q = 0, q_not = 1
enter code here

Спасибо!

1 Ответ

0 голосов
/ 02 июля 2018

У вас есть все виды проблем здесь:

  1. В seq_logic вы присваиваете present_state с блокирующим присваиванием , а следующий оператор - case(present_state). Это проверяет старое значение present_state, а это не то, что вы хотите
  2. Ваш процесс 'comb_logic' чувствителен к present_state, но ваш seq_logic процесс меняет present_state на растущих тактовых фронтах. На первый взгляд кажется, что это правильно, но это не так. Как вы написали это, comb_logic должен быть чувствителен только к J и K

Этих двух достаточно, чтобы получить правильный результат, но это слишком сложно для JK - начните заново, поместите все в один синхронизированный процесс, выведите следующий логический процесс, просто используйте поведение JK - загрузить, установить или переключить. Вы также должны добавить текущее время к вашему $monitor.

...