列表

详情


VL58. 游戏机计费程序

描述

要求实现一个游戏机计费模块,某游戏机具有多个模式,价格不同:普通模式每分钟1元,畅玩模式每分钟收费2元,默认情况下为普通模式,在boost按键按下之后进入畅玩模式。
游戏机采用预付费模式,输入端口money的数值为预付费用,在set信号有效时,将money的数值读入。输出端口remain的数值为剩余费用,当费用小于10元时,黄色信号灯yellow亮起。当费用不足时,红色信号灯red亮起,同时关闭电脑。在游戏过程中可以通过set端口续费。每次set信号有效将此时刻money的数值加到remain之中。
注:在程序中以每个时钟周期代表一分钟,每个单位大小表示1元。
模块的信号接口图如下:
     
请使用VerilogHDL语言实现,并编写 testbench 验证功能。

输入描述

clk:系统时钟信号
rst_n:复位信号,低电平有效
money:10bit位宽的数据,表示充值数额,当set信号有效时,将该信号的数值加到游戏余额remain中
set:充值信号,当信号等于1,表示用户充值。
boost:游戏机模式切换信号,为1时,表示进入畅玩模式,每个时钟扣费2,即remain减二,为0时,表示普通模式,remain每个时钟减一。

输出描述

remain:10bit位宽的数据,表示余额,根据充值数额和游戏模式变化
yellow:指示灯,当remain大于0且小于10时,为1。
red:指示灯,当余额不足时为1,其余时刻为0。

原站题解

Verilog 解法, 执行用时: 0ms, 内存消耗: 0KB, 提交时间: 2022-08-06

`timescale 1ns/1ns

module game_count
    (
		input rst_n, //异位复位信号,低电平有效
        input clk, 	//时钟信号
        input [9:0]money,
        input set,
		input boost,
		output reg[9:0]remain,
		output reg yellow,
		output reg red
    );
    
    //充值
    always @(posedge clk or negedge rst_n) begin
        if(!rst_n) begin
            remain <= 10'b0;
        end
        else begin
            if(set) begin
                remain <= remain + money;
            end
            else if(boost) begin
                if(remain >= 10'd2) begin
                    remain <= remain - 2'd2;
                end
            end
            else begin
                if(remain >= 10'd1) begin
                    remain <= remain - 1'b1;
                end
            end
        end
    end
    
    // 黄、红灯
    always @(posedge clk or negedge rst_n) begin
        if(!rst_n) begin
            yellow <= 1'b0;
            red <= 1'b0;
        end
        else begin
            if(remain > 10'd0 && remain < 10'd10) begin
                yellow <= 1'b1;
            end
            else begin
                yellow <= 1'b0;
            end
            if(remain == 10'd0) begin
                red <= 1'b1;
            end
            else begin
                red <= 1'b0;
            end
        end
    end
    
endmodule

Verilog 解法, 执行用时: 0ms, 内存消耗: 0KB, 提交时间: 2022-08-06

`timescale 1ns/1ns
module game_count
    (
		input rst_n, //异位复位信号,低电平有效
        input clk, 	//时钟信号
        input [9:0]money,
        input set,
		input boost,
		output reg[9:0]remain,
		output reg yellow,
		output reg red
    );
parameter idle = 2'b0;
parameter normal = 2'b01;
    parameter happy = 2'b10;
    reg[9:0] cnt;
    reg [1:0] state,next_state;
    always @(posedge clk or negedge rst_n)
        begin
            if (!rst_n)
                remain <= 10'b0;
            else
                if (set)
                   remain <= money + remain;
            else if (!boost)
                remain <= (remain < 1)? remain:remain -1'b1;
            else if (boost)
                remain <= (remain <2)? remain:remain - 2'b10;
        end
    always @(posedge clk or negedge rst_n)
          begin
            if (!rst_n)
                begin
                    state <= 2'b0;
                    next_state <= 2'b0;
                end
              else
                  begin
                      state <= next_state;
                  end
          end
    
   always @(posedge clk or negedge rst_n)
          begin
            if (!rst_n)  
    begin
        yellow <= 1'b0;
        red <= 1'b0;
    end
              else
                  begin
                      yellow <= (remain <=10 && remain > 0)? 1'b1:1'b0;
                      red <= (state == normal && remain == 0)? 1'b1:
                             (state == happy && remain <2)? 1'b1:
                             (state == idle)? 1'b1:1'b0;
                  end
          end
    
    always @(*)
        begin
            case (state)
                idle: next_state = (remain >= 0)? normal : idle;
                normal : next_state = (boost == 1 )? happy:
                                      (boost == 0 && remain >0)? normal:idle;
                happy : next_state = (boost == 0 && remain >=1)? normal: 
                                     (boost == 1 && remain >=2)? happy:idle;
                default next_state = idle;
            endcase
        end
    
                
                
endmodule

Verilog 解法, 执行用时: 0ms, 内存消耗: 0KB, 提交时间: 2022-08-06

`timescale 1ns/1ns

module game_count
    (
		input rst_n, //异位复位信号,低电平有效
        input clk, 	//时钟信号
        input [9:0]money,
        input set,
		input boost,
		output reg[9:0]remain,
		output reg yellow,
		output reg red
    );
    
always@(posedge clk or negedge rst_n) begin
        if(~rst_n) begin
            yellow <= 0;
            red    <= 0;
        end
        else begin
            yellow <= remain<10&&remain;
            red    <= boost? remain<2: remain<1;
        end
    end
     
    always@(posedge clk or negedge rst_n) begin
        if(~rst_n)
            remain <= 0;
        else if(boost)
            remain <= set     ? remain+money:
                      remain<2? remain:
                      remain-2;
        else
            remain <= set     ? remain+money:
                      remain<1? remain:
                      remain-1;
    end
    
endmodule

Verilog 解法, 执行用时: 0ms, 内存消耗: 0KB, 提交时间: 2022-08-06

`timescale 1ns/1ns

module game_count
    (
		input rst_n, //异位复位信号,低电平有效
        input clk, 	//时钟信号
        input [9:0]money,
        input set,
		input boost,
		output reg[9:0]remain,
		output reg yellow,
		output reg red
    );
    

    
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n)
            remain<='d0;
        else begin
            if(set)begin
                remain<=remain+money;
            end
            else begin
                case(boost)
                    1'd1:remain<=remain-2'd2;
                    1'd0:remain<=remain-2'd1;
                    default:remain<=remain-2'd1;
                endcase
            end
        end

    end
 
    
    
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            red<='d0;
            yellow<='d0;
          
        end
        else begin
               yellow <= remain<10&&remain;
            red    <= boost? remain<2: remain<1;
        
    end
end  
    
endmodule

Verilog 解法, 执行用时: 0ms, 内存消耗: 0KB, 提交时间: 2022-08-06

`timescale 1ns/1ns

module game_count
    (
		input rst_n, //异位复位信号,低电平有效
        input clk, 	//时钟信号
        input [9:0]money,
        input set,
		input boost,
		output reg[9:0]remain,
		output reg yellow,
		output reg red
    );
//     reg mode;
    always@(posedge clk or negedge rst_n)
        begin
            if(!rst_n)
                begin
                    remain <= 0;
                end
            else if(set)
                begin
                    remain <= boost?remain+money:remain+money;// 如果充值时也计费,这里就前面-2后面-1.现在更简洁的当然是直接写成remain+money咯
                end
            else
                begin
                    remain <= boost?(remain<2?remain:remain-2):
                              (remain<1?remain:remain-1);
                end
        end
    always@(posedge clk or negedge rst_n)
        begin
            if(!rst_n)
                begin
                    yellow <= 0;
                    red <= 0;
                end
            else
                begin
                    yellow <= remain<10&&remain>0;
                    red <= boost?remain<2:remain<1;
                end
        end
    
endmodule

上一题