Просты прыклад Verilog для святлодыёднага камутатары?

Я спрабую пабудаваць Statemachine для 1-гарачай кадаваных просты кнопкі з LED перамыкача.

Асабліва я спрабую зразумець, блякаваньне і неблокирующие прызначэння з маім прыкладам.

Вы б, што наступнае можна зрабіць лепш, або зусім няправільна ў любым блоку?

module example (
  input clk,
  input rst,
  input push,

  output reg led_on
);


reg on;
reg off;

reg t_on_off;
reg t_off_on;


always @* begin
  t_on_off = on & (push);
end

always @* begin
  t_off_on = off & (push);
end


always @(posedge clk or posedge rst) begin
  if (rst)              on <= 1'b0;
  else if (t_off_on)    on <= 1'b1;
  else if (t_on_off)    on <= 1'b0;
end

always @(posedge clk or posedge rst) begin
  if (rst)              off <= 1'b1;
  else if (t_off_on)    off <= 1'b0;
  else if (t_on_off)    off <= 1'b1;
end


always @* begin
  led_on = on;
end


endmodule

Асабліва я хацеў бы ведаць: я мог аб'яднаць прысваення пераходаў у адзін блок, як:

always @* begin
  t_on_off = on & (push);
  t_off_on = off & (push);
end

?

2

8 адказы

Калі ён не павінен быць адзін да чырвані, а затым спрасціць яго:

module example (
  input clk,
  input rst,
  input push,

  output reg led_on
);

always @(posedge clk or posedge rst) begin
  if (rst)        led_on  <= 1'b0;
  else if (push)  led_on  <= !led_on;
end

endmodule

Гэта функцыянальны эквівалент таго, што ў вас ёсць і больш чытэльныя.

3
дададзена

Калі ён не павінен быць адзін да чырвані, а затым спрасціць яго:

module example (
  input clk,
  input rst,
  input push,

  output reg led_on
);

always @(posedge clk or posedge rst) begin
  if (rst)        led_on  <= 1'b0;
  else if (push)  led_on  <= !led_on;
end

endmodule

Гэта функцыянальны эквівалент таго, што ў вас ёсць і больш чытэльныя.

3
дададзена
<�Р> Асабліва я хацеў бы ведаць: я мог аб'яднаць прысваення пераходаў у адзін блок, як ...

Так, вы можаце зрабіць гэта менавіта так, як вы апісалі.

Вы таксама можаце камбінаваць паслядоўныя блокі, а калі вы хочаце:

always @(posedge clk or posedge rst) begin
  if (rst) begin
     on  <= 1'b0;
     off <= 1'b1;
  end else if (t_off_on) begin
     on  <= 1'b1;
     off <= 1'b0;
  end 
  (etc....)
end
1
дададзена

Так, вы можаце аб'яднаць некалькі заўсёды блокі ў адзін.

Вам проста трэба вылучыць свой сінхронныя (Хронометрировали адны) і асінхронныя блокі ў асобны заўсёды блокі.

Тым не менш, добры стыль, каб мець заўсёды блок для кожнага асобнага выхаду. Гэта лягчэй чытаць і больш рэальны свет, накшталт як кожны заўсёды блок адначасова адзін з адным.

1
дададзена

Рэфактарынг Прапанова:

output reg led_on;

always @* begin
  led_on = on;
end

каб:

output led_on; //wire by default (not declared reg)

assign led_on = on;

You could also do the same with your t_on_off and t_off_on

wire t_on_off;
wire t_off_on;

assign t_on_off = on  & (push);
assign t_off_on = off & (push);

Ці, калі вы аддаеце перавагу каціць дэклараваць і прызначыць у адным радку.

wire t_on_off = on  & (push);
wire t_off_on = off & (push);

Але калі вы прокатка два заўсёды блокі з тактавай частатой у адзін няма неабходнасці ў асобных логікі, сумяшчаючы @ адказ Ціма з t_on_off праверыць:

module example (
  input clk,
  input rst,
  input push,

  output reg led_on
);

reg on;
reg off;

assign  led_on = on;

always @(posedge clk or posedge rst) begin
  if (rst) begin
    on  <= 1'b0;
    off <= 1'b1;
  end
  else if (off & push) begin
    on  <= 1'b1;
    off <= 1'b0;
  end
  else if (on  & push) begin
    on  <= 1'b0;
    off <= 1'b1;
  end
end

endmodule
1
дададзена

Рэфактарынг Прапанова:

output reg led_on;

always @* begin
  led_on = on;
end

каб:

output led_on; //wire by default (not declared reg)

assign led_on = on;

You could also do the same with your t_on_off and t_off_on

wire t_on_off;
wire t_off_on;

assign t_on_off = on  & (push);
assign t_off_on = off & (push);

Ці, калі вы аддаеце перавагу каціць дэклараваць і прызначыць у адным радку.

wire t_on_off = on  & (push);
wire t_off_on = off & (push);

Але калі вы прокатка два заўсёды блокі з тактавай частатой у адзін няма неабходнасці ў асобных логікі, сумяшчаючы @ адказ Ціма з t_on_off праверыць:

module example (
  input clk,
  input rst,
  input push,

  output reg led_on
);

reg on;
reg off;

assign  led_on = on;

always @(posedge clk or posedge rst) begin
  if (rst) begin
    on  <= 1'b0;
    off <= 1'b1;
  end
  else if (off & push) begin
    on  <= 1'b1;
    off <= 1'b0;
  end
  else if (on  & push) begin
    on  <= 1'b0;
    off <= 1'b1;
  end
end

endmodule
1
дададзена

Гэта было далёка ў мінулым ужо, але рашэнні, прадстаўленыя, магчыма, не зусім тое, што вы чакалі. З таго, што я мог бы зрабіць выснову рашэння ўсё лічаць, што святлодыёд будзе працягваць перамыкаючы таго часу, пакуль кнопка націснутая (гэта значыць, ён будзе пераходзіць на частаце тактавага генератара в), што робіць яго візуальна незаўважны, калі тактавая частата высокая. Тым не менш, я мяркую, вы хочаце нешта, перамыкае святлодыёд толькі адзін раз кожны раз пры націску кнопкі, з LED стану захоўваюцца на працягу гэтага перыяду.

Ніжэй прыклад перамыкае стану 3 святлодыёда на аснове актыўнасці 3-х кнопак.

  1. led0 is activated whenever pbutton0 is pressed.
  2. led1 keeps toggling periodically (based on the size of clk_div) and is reset whenever pbutton1 is pressed.
  3. led2 is toggled whenever pbutton2 is pressed.

Звярніце ўвагу, што led0 з'яўляецца камбінацыйная, у той час як іншыя два святлодыёда з'яўляюцца паслядоўнымі. Для пераключэння СИД2 , папярэдні стан pbutton2 павінны быць захаваны; кожны раз, калі <�ет> pbutton2 (т-1) == 0 і pbutton2 (т) == 1, гэта азначае, што кнопка толькі шлях ад нізкага да высокага і, такім чынам, стан з СИД2 павінны змяніцца.

Нарэшце, калі ласка, ігнараваць крыніца сінхранізацыі, так як гэта выкарыстоўваецца толькі для дэманстрацыі коды на камплекце распрацоўкі Xilinx SP605.

////////////////////////////////////////////////////
// This project uses 3 pushbuttons and 3 LEDs.
//  pbutton0 activates led0
//  pbutton1 serves as reset for led1 periodic toggling
//  pbutton2 toggles led2
//
// The clock source (divider+buffer) was created using the clocking IP wizard.
//

module xilinx_sp605_board_leds
(
    input CLK_IN1_P,
    input CLK_IN1_N,

    input pbutton0,
    input pbutton1,
    input pbutton2,

    output led0,
    output reg led1,
    output reg led2
);

// declarations
wire clk;
wire reset = pbutton1;
reg [19:0] clk_div;
reg pbutton2_reg;

// led0 = state of pbutton0
assign led0 = pbutton0;

// differential clock divider+buffer
clk_source CLK_SOURCE (
    .CLK_IN1_P(CLK_IN1_P),
    .CLK_IN1_N(CLK_IN1_N),
    .CLK_OUT1(clk),
    .RESET(reset));

// led1, led2 toggling
always @(posedge reset or posedge clk)
begin
    if(reset)begin
        clk_div <= 0;
        led1 <= 0;

        pbutton2_reg <= 0;
        led2 <= 0;
    end else begin
        clk_div <= clk_div + 1;
        if(clk_div==0) 
            led1 <= ~led1;

        pbutton2_reg <= pbutton2;
        if(~pbutton2_reg && pbutton2)
            led2 <= ~led2;
    end
end

endmodule
0
дададзена

Гэта было далёка ў мінулым ужо, але рашэнні, прадстаўленыя, магчыма, не зусім тое, што вы чакалі. З таго, што я мог бы зрабіць выснову рашэння ўсё лічаць, што святлодыёд будзе працягваць перамыкаючы таго часу, пакуль кнопка націснутая (гэта значыць, ён будзе пераходзіць на частаце тактавага генератара в), што робіць яго візуальна незаўважны, калі тактавая частата высокая. Тым не менш, я мяркую, вы хочаце нешта, перамыкае святлодыёд толькі адзін раз кожны раз пры націску кнопкі, з LED стану захоўваюцца на працягу гэтага перыяду.

Ніжэй прыклад перамыкае стану 3 святлодыёда на аснове актыўнасці 3-х кнопак.

  1. led0 is activated whenever pbutton0 is pressed.
  2. led1 keeps toggling periodically (based on the size of clk_div) and is reset whenever pbutton1 is pressed.
  3. led2 is toggled whenever pbutton2 is pressed.

Звярніце ўвагу, што led0 з'яўляецца камбінацыйная, у той час як іншыя два святлодыёда з'яўляюцца паслядоўнымі. Для пераключэння СИД2 , папярэдні стан pbutton2 павінны быць захаваны; кожны раз, калі <�ет> pbutton2 (т-1) == 0 і pbutton2 (т) == 1, гэта азначае, што кнопка толькі шлях ад нізкага да высокага і, такім чынам, стан з СИД2 павінны змяніцца.

Нарэшце, калі ласка, ігнараваць крыніца сінхранізацыі, так як гэта выкарыстоўваецца толькі для дэманстрацыі коды на камплекце распрацоўкі Xilinx SP605.

////////////////////////////////////////////////////
// This project uses 3 pushbuttons and 3 LEDs.
//  pbutton0 activates led0
//  pbutton1 serves as reset for led1 periodic toggling
//  pbutton2 toggles led2
//
// The clock source (divider+buffer) was created using the clocking IP wizard.
//

module xilinx_sp605_board_leds
(
    input CLK_IN1_P,
    input CLK_IN1_N,

    input pbutton0,
    input pbutton1,
    input pbutton2,

    output led0,
    output reg led1,
    output reg led2
);

// declarations
wire clk;
wire reset = pbutton1;
reg [19:0] clk_div;
reg pbutton2_reg;

// led0 = state of pbutton0
assign led0 = pbutton0;

// differential clock divider+buffer
clk_source CLK_SOURCE (
    .CLK_IN1_P(CLK_IN1_P),
    .CLK_IN1_N(CLK_IN1_N),
    .CLK_OUT1(clk),
    .RESET(reset));

// led1, led2 toggling
always @(posedge reset or posedge clk)
begin
    if(reset)begin
        clk_div <= 0;
        led1 <= 0;

        pbutton2_reg <= 0;
        led2 <= 0;
    end else begin
        clk_div <= clk_div + 1;
        if(clk_div==0) 
            led1 <= ~led1;

        pbutton2_reg <= pbutton2;
        if(~pbutton2_reg && pbutton2)
            led2 <= ~led2;
    end
end

endmodule
0
дададзена