独热码状态机、SR锁存器延迟模型、移位除法器模型

用modelsim仿真基本流程:
一、独热码状态机
代码以及测试代码如下:
module ex8_1(clock,reset, x,y1,y2);
input clock,reset;
input x;
output y1,y2;
reg y1,y2;
reg[3:0] cstate, nstate;
parameter
s0=4’b0001,
s1=4’b0010,
s2=4’b0100,
s3=4’b1000;
always @(posedge clock or posedge reset)
begin
if(reset)
cstate<=s0;
else
cstate<=nstate;
end
always @(cstate or x)
begin
case(cstate)
s0 : begin
if(x0)
nstate=s1;
else
nstate=s3;
end
s1:begin
if(x
0)
nstate=s2;
else
nstate=s0;
end
s2 : begin
if(x0)
nstate=s3;
else
nstate=s1;
end
s3 :begin
if(x
0)
nstate=s0;
else
nstate=s2;
end
default:nstate=s0;
endcase
end
always @(cstate or x)
begin
case(cstate)
s0 : begin
if(x0)
y1=1;
else
y1=0;
end
s1 :begin
if(x
0)
y1=0;
else
y1=0;
end
s2 : begin
if(x0)
y1=0;
else
y1=0;
end
s3 : begin
if(x
0)
y1=0;
else
y1=1;
end
default:y1=0;
endcase
end
always @(cstate or x)
begin
if(cstates0 &&x0)
y2=1;
else if(cstates3 && x1)
y2=1;
else
y2=0;
end
endmodule
测试代码:
第一个测试代码tb_ex81;
reg x,clock, reset;
wire yl, y2;
initial clock=0;
always #5clock=~clock;
initial
begin
reset=0;
#15 reset=1;

#15 reset=0;
#10000 $stop;
end
initial
begin
#10 x=1;
#500 x=0;
end
ex8_1 myex81(clock, reset,x,yl,y2);
endmodule

1.创建两个测文件,并编写代码。
2.进行编译:
点击compile,编译完成在文件后会有✔提示。
3.点击work,只需编译测试文件,如图:

4.将sim中的测试代码加入到wave:

5.点击run,开始测试

6.测试结果如图:在这里插入图片描述

二:SR锁存器延迟模型
代码以及测试代码如下:

module my_rs(reset,set,q,qbar);
input reset, set;
output q, qbar;
nor #(1) nl(g, reset, gbar);
nor #(1) n2 (qbar, set, a);
endmodule
测试代码:
module tb_71;
reg set, reset;
wire q, qbar;
initial
begin
set<=0;reset<=1;
#10 set<=0;reset<=0;
#10 set<=1;reset<=0;
#10 set<=1;reset<=1;
end
my_rs rsl(reset, set,q,qbar);
initial
m o n i t o r ( monitor( monitor(time, “set= %b, reset= %b,q= %b,qbar= %b”,set,reset, g, qbar);
endmodule
3.重复上诉步骤
4.结果如图:
在这里插入图片描述
三、移位除法器模型
代码及测试代码:
源代码 : module div2(clk, reset, start, A, B, D, R, ok, err);
parameter n = 32;
parameter m = 16;

input clk, reset, start;
input [n-1:0] A, B;
output [n+m-1:0] D;
output [n-1:0] R;
output ok, err;

wire invalid, carry, load, run;

div_ctl UCTL(clk, reset, start, invalid, carry, load, run, err, ok);
div_datapath UDATAPATH(clk, reset, A, B, load, run, invalid, carry, D, R);

endmodule

module div_ctl(clk, reset, start, invalid, carry, load, run, err, ok);
parameter n = 32;
parameter m = 16;
parameter STATE_INIT = 3’b001;
parameter STATE_RUN = 3’b010;
parameter STATE_FINISH = 3’b100;
input clk, reset, start, invalid, carry;
output load, run, err, ok;

reg [2:0] current_state, next_state;
reg [5:0] cnt;
reg load, run, err, ok;

always @(posedge clk or negedge reset)
begin
if(!reset) begin
current_state <= STATE_INIT;
cnt <= 0;
end else begin
current_state <= next_state;
if(run) cnt <= cnt + 1’b1;
end
end

always @(posedge clk or negedge reset)
begin
if(!reset) begin
err <= 0;
end else if(next_state==STATE_RUN) begin
if(invalid) err <= 1;
end
end

always @(current_state or start or invalid or carry or cnt)

begin
load <= 1’b0;
ok <= 1’b0;
run <= 1’b0;

  case(current_state)
     STATE_INIT: begin
        if(start) next_state <= STATE_RUN;
        else next_state <= STATE_INIT;
        load <= 1;
     end
     STATE_RUN : begin
        run <= 1;
        if(invalid) begin
           next_state <= STATE_FINISH;   
        end else if(cnt==(n+m-1)) begin
           next_state <= STATE_FINISH;    
        end else begin
           next_state <= STATE_RUN;
        end
     end
     STATE_FINISH : begin
        ok <= 1;
        next_state <= STATE_FINISH;    
     end
     default : begin
        next_state <= STATE_INIT;    
     end
  endcase

end
endmodule

module div_datapath(clk, reset, A, B, load, run, invalid, carry, D, R);
parameter n = 32;
parameter m = 16;
input clk, reset;
input [n-1:0] A, B;
input load, run;
output invalid, carry;
output [n+m-1:0] D;
output [n-1:0] R;

reg [n+n+m-2:0] R0;
reg [n+m-1:0] D;
reg [n-1:0] B0;
reg carry;

wire invalid;
wire [n-1:0] DIFF, R;
wire CO;

assign R = {carry, R0[n+n+m-2:n+m]};
assign invalid = (B0==0);

sub sub(R0[n+n+m-2:n+m-1], B0, 1’b0, DIFF, CO);

always @(posedge clk)
begin
if(load) begin
R0 <= {{(n-1){1’b0}}, A, {m{1’b0}}};
B0 <= B;
carry <= 1’b0;
end
else if(run) begin
if(CO && !carry) begin
R0 <= { R0, 1’b0 };
D <= { D[n+m-2:0], 1’b0 };
carry <= R0[n+n+m-2];
end else begin
R0 <= { DIFF, R0[n+m-2:0], 1’b0 };
D <= { D[n+m-2:0], 1’b1 };
carry <= DIFF[n-1];
end
end
end
endmodule

module sub(A, B, CI, DIFF, CO);
parameter n = 32;
input [n-1:0] A, B;
input CI;
output [n-1:0] DIFF;
output CO;

assign {CO, DIFF} = {1’b0, A} - {1’b0, B} - {{n{1’b0}}, CI};
endmodule
测试代码:
测试代码: `timescale 1ns/10ps
module tb_div2;
parameter n = 32;
parameter m = 16;

reg clk, reset;
reg start;
wire [n+m-1:0] D;
wire [n-1:0] R;
wire err, ok;
integer i;

reg [n-1:0] dividend;
reg [n-1:0] divisor;
reg [n+m-1:0] quotient;
reg [n-1:0] remainder;

div2 UDIV(clk, reset, start, dividend, divisor, D, R, ok, err);

function [n+n+(n+m)+(n)-1:0] gen_rand_data;

   input integer i;
   reg [n+m-1:0] dividend;
   reg [n+m-1:0] divisor;
   reg [n+m-1:0] quotient;
   reg [n+m-1:0] remainder;
   integer k;
   integer flag;
  
   begin
       k = (i/4) % 32 + 1;
       flag = 1;           
       while(flag)
       begin
       dividend = {{$random}, {m{1'b0}}};     
       divisor =  {{m{1'b0}}, {$random}};    
       
       divisor = divisor % ( 2 << k);           
       if(divisor == {(n+m){1'b0}})
       begin
           $display("Divisor is zero!!!");
       end else begin
           flag = 0;
       end
       quotient =  dividend / divisor;
       remainder = dividend % divisor;          
       
       if(remainder > divisor)                 
       begin
          $display("Bad remainder!!!"); 
          $stop;
       end
       
       if(quotient * divisor + remainder != dividend)     
       begin
           $display("bad values!!!");
           $stop;
       end
       end
   
       gen_rand_data = {dividend[n+m-1:m], divisor[n-1:0], quotient, remainder[n-1:0]};

   end
endfunction

initial
begin
clk=0;
forever
#10 clk=~clk;
end

initial
begin
reset = 0;
start = 0;
for(i=1; i<=1000; i=i+1)
begin
{dividend, divisor, quotient, remainder} = gen_rand_data(i);
@(posedge clk);
reset = 0;
@(posedge clk);
reset = 1;
start = 1;
@(posedge ok);
if(quotient!=D || remainder!=R)
begin
$display(“BAD RESULT!!!”);
$display(“result: quotient=48’d%d, remainder=32’d%d”, D, R);
$stop;
end
end

  $stop;   

end
endmodule
结果如图:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值