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

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

2.实验内容:参照今日头条中教程的视频和代码,然后用modlsim软件进行仿真。

3实验代码
(1).独热码状态机


```c

```c

```c

```c

```bash

```c
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



实验结果截图:
在这里插入图片描述
(2)SR锁存器延迟模型
设计模块:

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

实验结果截图:
在这里插入图片描述
(3)移位除法器模型

```c
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

测试模块

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)			//生成1000个数
	  begin	
	    {dividend, divisor, quotient, remainder} = gen_rand_data(i);
													//调用函数返回4个值
		 @(posedge clk);					//等待时钟信号复位
		    reset = 0;
		 @(posedge clk);					//下一时钟开始运算
			reset = 1;
			start = 1;
		 @(posedge ok);					//等到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;			//1000个数后结束仿真
	end
endmodule

   实验结果截图
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210626161848967.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2M5OWx5Zg==,size_16,color_FFFFFF,t_70)

4.实验视频:请下载哔哩哔哩动画打开此网址:https://b23.tv/E2pHcE





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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值