Modelsim仿真

一,实验目的
1.独热码状态机
2.SR锁存器延迟模型
3.移位除法器

二,实验工具
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 (x==0)
          nstate=s1;
    else
      nstate=s3;
  end
  s1:begin
      if (x==0)
       nstate=s2;
    else
       nstate=s0;
  end
  s2:begin
      if (x==0)
       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 (x==0)
              y1=1;
           else
              y1=0;
        end
   s1 : begin
           if (x==0)
              y1=0;
           else
              y1=0;
        end
   s2 : begin
           if (x==0)
              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 (cstate==s0  &&  x==0)
        y2=1;
    else  if (cstate==s3  &&  x==1)
        y2=1;
    else
        y2=0;
end


endmodule

实验二代码:

module my_rs(reset,set,q,qbar);
input reset,set;
output q,qbar;

nor#(1) n1(q,reset,qbar);
nor#(1) n2(qbar,set,q);

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
$monitor($time,"set= %b,reset= %b,q= %b,qbar= %b",set,reset,q,qbar);

endmodule

实验三模块代码:

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
			D <= 0;
			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

四,实验截图

在这里插入图片描述

![在这里插入图片描述](https://img-blog.csdnimg.cn/20210611145431157.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzU0MDQ2MzAz,size_16,color_FFFFFF,t_70

第三个实验截图
点击仿真tb_div2文件
Enable optimization(启用优化)看自己所安装的modelsim的版本来进行勾选,我的版本是10.6的
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210611152258601.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzU0MDQ2MzAz,size_16,color_FFFFFF,t_70

在这里插入图片描述

在这里插入图片描述

五,实验视频
独热码状态机
SR锁存器延迟模型
移位除法器

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值