VL33非整数倍数据位宽转换8to12

和上一题一样的,注意valid_out输出时加一个valid_in(其实32题也要加,不过不加仿真也能过)。

`timescale 1ns/1nsmodule width_8to12(    input                    clk         ,       input                   rst_n        ,    input                      valid_in    ,    input    [7:0]               data_in    ,      output  reg               valid_out,    output  reg [11:0]   data_out);reg [2:0]count;always@(posedge clk or negedge rst_n)begin    if(~rst_n)        count <= 0;    else if(valid_in)        count <= (count<2)?count + 1:0;endalways@(posedge clk or negedge rst_n)begin    if(~rst_n)        valid_out <= 0;    else if(valid_in&&(count==1||count==2))        valid_out <= 1;    else        valid_out <= 0;endreg [11:0]data_lock;always@(posedge clk or negedge rst_n)begin    if(~rst_n)begin        data_lock <= 0;        data_out <= 0;    end else if(valid_in)begin        data_lock <= {data_lock[3:0],data_in};        if(count == 1)            data_out <= {data_lock[7:0],data_in[7:4]};        else if(count == 2)            data_out <= {data_lock[3:0],data_in};    endendendmodule

VL34整数倍数据位宽转换8to16

越做越简单了,整数倍位宽转换就非常轻松了。

`timescale 1ns/1nsmodule width_8to16(    input                    clk         ,       input                    rst_n        ,    input                      valid_in    ,    input       [7:0]           data_in    ,      output    reg            valid_out,    output   reg [15:0]    data_out);reg count;always@(posedge clk or negedge rst_n)begin    if(~rst_n)        count <= 0;    else if(valid_in)        count <= count + 1;endalways@(posedge clk or negedge rst_n)begin    if(~rst_n)        valid_out <= 0;    else if(valid_in && count)            valid_out <= 1;    else        valid_out <= 0;endreg [7:0]data_lock;always@(posedge clk or negedge rst_n)begin    if(~rst_n)begin        data_lock <= 0;        data_out <= 0;    end else if(valid_in)begin        data_lock <= data_in;        if(count == 1)            data_out <= {data_lock,data_in};    endendendmodule

VL35状态机-非重叠的序列检测

也是一道比较简单的题,不过要注意是非重叠检测,用状态机比用移位寄存器更方便一点。

`timescale 1ns/1nsmodule sequence_test1(    input wire clk  ,    input wire rst  ,    input wire data ,    output reg flag);//*************code***********//reg [2:0]state,next_state;localparam S0=0,S1=1,S2=2,S3=3,S4=4;always@(posedge clk or negedge rst)begin    if(~rst)        state <= S0;    else        state <= next_state;endalways@(*)begin    case(state)    S0:next_state = data ? S1 :S0;    S1:next_state = data ? S1 :S2;    S2:next_state = data ? S3 :S0;    S3:next_state = data ? S4 :S2;    S4:next_state = data ? S0 :S2;    default:next_state = S0;    endcaseendalways@(posedge clk or negedge rst)begin    if(~rst)        flag <= 0;    else if(state == S4 && data)        flag <= 1;    else         flag <= 0;end//*************code***********//endmodule

VL36状态机-重叠序列检测

重叠序列用移位寄存器肯定更方便,不过题目要求用状态机,同样也是注意状态跳变就行了。注意输出延后了一个周期,可以通过加一个状态来实现。

`timescale 1ns/1nsmodule sequence_test2(    input wire clk  ,    input wire rst  ,    input wire data ,    output reg flag);//*************code***********//reg [2:0]state,next_state;localparam S0=0,S1=1,S2=2,S3=3,S4=4;always@(posedge clk or negedge rst)begin    if(~rst)        state <= S0;    else        state <= next_state;endalways@(*)begin    case(state)    S0:next_state = data ? S1 :S0;    S1:next_state = data ? S1 :S2;    S2:next_state = data ? S3 :S0;    S3:next_state = data ? S4 :S2;    S4:next_state = data ? S1 :S2;    default:next_state = S0;    endcaseendalways@(posedge clk or negedge rst)begin    if(~rst)        flag <= 0;    else if(state == S4)        flag <= 1;    else         flag <= 0;end//*************code***********//endmodule

VL37时钟分频(偶数)

一眼行波计数器,不过输出定义的是wire,懒得再去改了。

我这里是组合逻辑输出,其实也不大好。

`timescale 1ns/1nsmodule even_div    (    input     wire rst ,    input     wire clk_in,    output    wire clk_out2,    output    wire clk_out4,    output    wire clk_out8    );//*************code***********//reg [2:0]count;always@(posedge clk_in or negedge rst)begin    if(~rst)        count <= 0;    else        count <= count + 1;endassign clk_out2 = count[0];assign clk_out4 = count[1:0]>0&&count[1:0]<3;assign clk_out8 = count>0&&count<5;//*************code***********//endmodule

VL38自动贩售机1

写完发现题目出的有点垃圾,输入d直接在上升沿给值,下降沿恢复,只有半个周期,晕。

状态机折磨了半天,看了看题解,用计数器确实方便多了,一遍过。

`timescale 1ns/1nsmodule seller1(    input wire clk  ,    input wire rst  ,    input wire d1 ,    input wire d2 ,    input wire d3 ,        output reg out1,    output reg [1:0]out2);//*************code***********//reg[2:0]count;always@(posedge clk or negedge rst)begin    if(~rst)begin        count <= 0;        out1 <= 0;        out2 <= 0;    end else begin        if(d1)            count <= count + 1;        else if(d2)            count <= count + 2;        else if(d3)            count <= count + 4;        if(count>=3)begin            count <= 0;            out1 <= 1;            out2 <= count -3;        end else begin            out1 <= 0;            out2 <= 0;        end    endend//*************code***********//endmodule

VL39自动贩售机2

和上一题是一样的,加了一个sel的判断。

`timescale 1ns/1nsmodule seller2(    input wire clk  ,    input wire rst  ,    input wire d1 ,    input wire d2 ,    input wire sel ,        output reg out1,    output reg out2,    output reg out3);//*************code***********//reg [2:0]count;always@(posedge clk or negedge rst)begin    if(~rst)begin        count <= 0;        out1 <= 0;        out2 <= 0;        out3 <= 0;    end else begin        if(d1)            count <= count + 1;        else if(d2)            count <= count + 2;        if(sel)begin            if(count >= 5)begin                out1 <= 0;                out2 <= 1;                out3 <= count - 5;                count <= 0;            end else begin                out1 <= 0;                out2 <= 0;                out3 <= 0;            end        end        else begin            if(count >= 3)begin                out1 <= 1;                out2 <= 0;                out3 <= count - 3;                count <= 0;            end else begin                out1 <= 0;                out2 <= 0;                out3 <= 0;            end        end    endend//*************code***********//endmodule

VL40占空比50%的奇数分频

用两个计数器,一个上升沿计数,一个下降沿计数即可。

不过感觉题目还是有点问题,第一个下降沿复位还没结束,计数器应该不会累加才对。

`timescale 1ns/1nsmodule odo_div_or   (    input    wire  rst ,    input    wire  clk_in,    output   wire  clk_out7    );//*************code***********//reg clk_out1;reg clk_out2;reg [2:0]count1;reg [2:0]count2;always@(posedge clk_in or negedge rst)begin    if(~rst)begin        count1 <= 0;        clk_out1 <= 0;    end else begin        count1 <= (count1 < 6)?(count1 + 1):0;        if(count1 == 3 || count1 ==6)            clk_out1 <= ~clk_out1;    endendalways@(negedge clk_in or negedge rst)begin    if(~rst)begin        count2 <= 0;        clk_out2 <= 0;    end else begin        count2 <= (count2 < 6)?(count2 + 1):0;        if(count2 == 3 || count2 ==6)            clk_out2 <= ~clk_out2;    endendassign clk_out7 = clk_out1 | clk_out2;//*************code***********//endmodule

VL41任意小数分频

题目给了明示,要先3次8分频再7次9分频,连时钟切换点都给出来了。

`timescale 1ns/1nsmodule div_M_N( input  wire clk_in, input  wire rst, output wire clk_out);parameter M_N = 8'd87; parameter c89 = 8'd24; // 8/9时钟切换点parameter div_e = 5'd8; //偶数周期parameter div_o = 5'd9; //奇数周期//*************code***********//reg [6:0]count;reg [3:0]count_e;reg [3:0]count_o;reg clk_MN;always@(posedge clk_in or negedge rst)begin    if(~rst)        count <= 0;    else         count <= (count < M_N -1)?(count + 1):0;endalways@(posedge clk_in or negedge rst)begin    if(~rst)begin        count_e <= 0;        count_o <= 0;        clk_MN <= 0;    end else begin        if(count <= c89 - 1)begin            count_e <= (count_e < div_e -1)?(count_e + 1):0;            if(count_e == 0||count_e == div_e/2)                clk_MN <= ~clk_MN;        end else begin            count_o <= (count_o < div_o -1)?(count_o + 1):0;            if(count_o == 0||count_o == (div_o-1)/2)                clk_MN <= ~clk_MN;        end    endendassign clk_out = clk_MN;//*************code***********//endmodule

VL42无占空比要求的奇数分频

说是无占空比要求,其实tb还是要求的50%,无语。参照VL40即可。

写完发现其实要求占空比40%,乌鱼子。

`timescale 1ns/1nsmodule odd_div (        input     wire rst ,    input     wire clk_in,    output    wire clk_out5);//*************code***********//reg [2:0]count;reg clk_div;always@(posedge clk_in or negedge rst)begin    if(~rst)begin        count <= 0;        clk_div <= 0;    end else begin        count <= (count < 4)?(count + 1):0;        if(count == 0 ||count == 2)            clk_div <= ~clk_div;    endendassign clk_out5 = clk_div;//*************code***********//endmodule

VL43根据状态转移写状态机-三段式

`timescale 1ns/1nsmodule fsm1(    input wire clk  ,    input wire rst  ,    input wire data ,    output reg flag);//*************code***********//reg[1:0]state,next_state;localparam S0=0,S1=1,S2=2,S3=3;always@(posedge clk or negedge rst)begin    if(~rst)        state <= S0;    else        state <= next_state;endalways@(*)begin    case(state)    S0:next_state = data?S1:S0;    S1:next_state = data?S2:S1;    S2:next_state = data?S3:S2;    S3:next_state = data?S0:S3;    default:next_state = S0;    endcaseendalways@(posedge clk or negedge rst)begin    if(~rst)        flag <= 0;    else begin        if(state == S3 && data)            flag <= 1;        else            flag <= 0;    endend//*************code***********//endmodule

VL44根据状态转移写状态机-二段式

两段式把输出和状态转移条件写一起,直接通过组合逻辑输出。

`timescale 1ns/1nsmodule fsm2(    input wire clk  ,    input wire rst  ,    input wire data ,    output reg flag);//*************code***********//reg[2:0]state,next_state;localparam S0=0,S1=1,S2=2,S3=3,S4=4;always@(posedge clk or negedge rst)begin    if(~rst)        state <= S0;    else        state <= next_state;endalways@(*)begin    case(state)    S0:begin        next_state = data?S1:S0;        flag =0;    end    S1:begin        next_state = data?S2:S1;        flag =0;    end    S2:begin        next_state = data?S3:S2;        flag =0;    end    S3:begin        next_state = data?S4:S3;        flag =0;    end    S4:begin        next_state = data?S1:S0;        flag = 1;    end    default:begin        next_state = S0;        flag =0;    end    endcaseend//*************code***********//endmodule