通过开关在7段指示灯上输出字

问题描述 投票:0回答:1

我想输出到一个七段指示器,这样当按下按钮时,显示某个段上的字母,当打开开关时,显示整个单词。 逻辑适用于按钮,但不适用于开关

逻辑上,当开关切换到有效状态时,位置总线连接到移位寄存器,7段开关应该根据它进行切换,但在时间图中,位置有一个未定义的状态

模块--

module mux_decoder(
    input btn_fir,
    input btn_sec,
    input btn_thi,
    input btn_fou,
    input sw_for_fullword,
    input clk,
    input rst,
    //input BTNC,
    //input SW[9],
    
    output logic [3:0] place,
    output [7:0] segments
    );
    
    typedef enum bit [7:0]
    {
        D     = 8'b0111_1010,
        N     = 8'b1110_1100,
        Y     = 8'b0111_0110,
        A     = 8'b1110_1110,
        space = 8'b0000_0000
    }
    seven_seg;
    seven_seg letter;
    
    logic [31:0] cnt;
    always_ff@(posedge clk,posedge rst)begin
        if(rst) cnt <= '0;
        else cnt <= cnt+1'b1;
    end
    
    logic enable = (cnt[24:0] == '0);
    
    logic [3:0]shift_reg;
    
    always_ff@(posedge clk, posedge rst)begin
        if (rst) shift_reg <= 4'b1;
        else if(enable) shift_reg <= {shift_reg[0], shift_reg[3:1]};
    end
    
   always_comb begin
        if(sw_for_fullword) place = shift_reg;
        else place = {btn_fir, btn_sec,btn_thi,btn_fou};
     end
     
    always_comb begin
        case (place)
        4'b1000: letter = D;
        4'b0100: letter = A;
        4'b0010: letter = N;
        4'b0001: letter = Y;
        default: letter = space;
        endcase        
    end
    
    assign segments = letter;
    
endmodule

TB-----

module tb(

    );
    
    logic[3:0] x;
    logic[7:0] letter;
    logic[3:0] place;
    logic sw;
    logic clk;
    logic rst;
    
    
    mux_decoder ms(.btn_fou(x[0]),.btn_fir(x[3]),.btn_sec(x[2]), .btn_thi(x[1]),.sw_for_fullword(sw),
    .place(place), .segments(letter), .clk(clk), .rst(rst));
    
    parameter CLK_PERIOD = 10;
    initial begin
    #10;
    x = 4'b0001;
    #20;
    x= 4'b0010;
    
    #20;
    x=4'b0100;
    #20;
    x=4'b1000;
    #20;
    x='0;
    
    clk ='0;
    
    sw = '1;
    forever begin
        #(CLK_PERIOD/2) clk<=~clk;
    end
   
    rst <= 1'bx;
    repeat (2) @ (posedge clk);
    rst <= 1'b1;
    repeat (2) @ (posedge clk);
    rst <= 1'b0;

    $finish
    end
endmodule

time diagram

verilog system-verilog
1个回答
0
投票

只要看一下你的时序图,你就可以看到时钟的应用是错误的。在应用向量之前,Clk 甚至不会启动。我将 clk 移至单独的进程,以便时钟从 t=0 开始。

重置也被应用在错误的时间。

DUT模块在信号初始化中连续赋值。已经搬出去了

我根本不清楚这应该做什么,但至少现在你有了一个工作测试平台。您可能需要改变矢量才能获得您想要的刺激。

如果这仍然没有达到您想要的效果,请发布一个新问题,说明您认为它应该做什么以及它正在做什么。

被测设备

module mux_decoder(
    input btn_fir,
    input btn_sec,
    input btn_thi,
    input btn_fou,
    input sw_for_fullword,
    input clk,
    input rst,
    //input BTNC,
    //input SW[9],
    
    output logic [3:0] place,
    output [7:0] segments
    );
    
    typedef enum bit [7:0]
    {
        D     = 8'b0111_1010,
        N     = 8'b1110_1100,
        Y     = 8'b0111_0110,
        A     = 8'b1110_1110,
        space = 8'b0000_0000
    }
    seven_seg;
    seven_seg letter;
    
    logic [31:0] cnt;
    logic enable;
    logic [3:0]shift_reg;

    assign enable = (cnt[24:0] == '0);

    always_ff@(posedge clk,posedge rst)begin
        if(rst) cnt <= '0;
        else cnt <= cnt+1'b1;
    end
    
    always_ff@(posedge clk, posedge rst)begin
        if (rst) shift_reg <= 4'b1;
        else if(enable) shift_reg <= {shift_reg[0], shift_reg[3:1]};
    end
    
   always_comb begin
        if(sw_for_fullword) place = shift_reg;
        else place = {btn_fir, btn_sec,btn_thi,btn_fou};
     end
     
    always_comb begin
        case (place)
        4'b1000: letter = D;
        4'b0100: letter = A;
        4'b0010: letter = N;
        4'b0001: letter = Y;
        default: letter = space;
        endcase        
    end
    
    assign segments = letter;
    
endmodule

// Code your testbench here
// or browse Examples
module tb( );
    logic[3:0] x;
    logic[7:0] letter;
    logic[3:0] place;
    logic sw;
    bit clk;
    bit rst;
    
    mux_decoder ms(.btn_fou(x[0]),.btn_fir(x[3]),.btn_sec(x[2]), .btn_thi(x[1]),.sw_for_fullword(sw),
    .place(place), .segments(letter), .clk(clk), .rst(rst));
    
    parameter CLK_PERIOD = 10;
  
    // clock is a seperate process
    always #(CLK_PERIOD/2) clk = ! clk;
    
    // Test stimulus block
    initial begin
      rst <= 1'b1;
      repeat (2) @ (posedge clk);
      rst <= 1'b0;      
      
      // The test starts here after reset is released
      x='0;
      sw = '1;      
      
      repeat (2) @ (posedge clk);
      x = 4'b0001;
      repeat (2) @ (posedge clk);
      x= 4'b0010;
      repeat (2) @ (posedge clk);
      x=4'b0100;
      repeat (2) @ (posedge clk);
      x=4'b1000;
      repeat (2) @ (posedge clk);

      $finish;
    end
  
endmodule

现在,复位后 x 处什么都没有,时钟一直在运行,并且设计在应用激励向量之前就脱离了复位。

© www.soinside.com 2019 - 2024. All rights reserved.