笔试——原码、反码、补码

原码、反码、补码

整数的原码、反码、补码都是一致的。‘
负数的反码,除了符号位与原码一致外,其余位与原码相反。
负数的补码,在其反码的基础上加1。
负数的补码,通过求负数补码的补码来得到原码。

除法器

1、选择除法器的算法,本实验开始采用的是减法实现除法器的例子(比如十进制中的a/b,可先比较a与b的大小,如果a>b,则商加1,a<=a-b,再进行比较大小,直到a<b,商不变,余数为a);

module divider(dividend,divisor,clk,rst,quotient,reminder);
  // 端口申明 //
  input [7:0]dividend;
  input [3:0]divisor;
  input clk;
  input rst;
  output [7:0]quotient;
  output [7:0]reminder;

  // 定义寄存器 //
  reg [7:0]q;
  reg [7:0]r;
  reg [7:0]d;
  reg [7:0]quotient;
  reg [7:0]reminder;
  reg [1:0]state;
  // 定义参数 //
  parameter S0=0;
  parameter S1=1;
  parameter S2=2;
  
  always@(posedge clk or negedge rst)
  begin
    if(!rst)
      begin
      q<=0;
      d<=0;
      r<=0;
      quotient<=0;
      reminder<=0;
      state<=0;
      end
    else
      begin
        case(state)    /*synthesis full_case*/
          S0:
          begin
            d<=dividend;
            state<=S1;
          end
          S1:
          begin
            if(d>=divisor)
              begin
                q<=q+1;
                d<=d-divisor;
                state<=S1;
              end
            else
              begin
                q<=q;
                r<=d;
                state<=S2;
              end
            end
            S2:
            begin
              quotient<=q;
              reminder<=r;
            end
          endcase
        end
      end
 endmodule
                
//Verilog测试程序:

`timescale 1ns/1ns
module divider_tb  ; 

parameter S1  = 1 ;
parameter S2  = 2 ;
parameter S0  = 0 ; 
  reg  [3:0]  divisor   ;    //除数
  wire  [7:0]  quotient   ;   //商
  reg    rst   ; 
  wire  [7:0]  reminder   ;   //余数
  reg    clk   ; 
  reg  [7:0]  dividend   ; //被除数
  
initial 
  begin
  rst=0;
  #5 
  rst=1;
end


initial clk=0;
always #5 clk=~clk;
  
  //定义被除数为55,除数为7//
initial 
  begin
  dividend=8'd55;
  divisor=4'd7;
end
  
  divider  DUT  ( 
       .divisor (divisor ) ,
      .quotient (quotient ) ,
      .rst (rst ) ,
      .reminder (reminder ) ,
      .clk (clk ) ,
      .dividend (dividend ) ); 
endmodule

二、算法:
比如5/2,转化为3位二进制就是101/010。先将101转为6位数:000101,然后101在每个时钟时向左推进一位(比如第一个时钟变为001010),然后与除数010做比较,如果大于除数则被除数左移一位然后商1,否则左移商0,具体如下分析。

//除法器verilog源代码:
//被除数为dividend
//除数为divisor,
//商为quotient,
//余数为reminder,
//如被除数与除数分别为101与010;

module divider_module
(dividend,divisor,clk,rst,quotient,reminder);
//端口定义//
input [7:0]dividend;
input [7:0]divisor;
input clk;
input rst;
output [7:0]quotient;
output [7:0]reminder;

//寄存器变量定义//
reg [7:0]q;
reg [7:0]r;
reg [7:0]t;
wire [7:0]quotient;
wire [7:0]reminder;
integer i;
parameter j=8;

always@(posedge clk or negedge rst)
begin
	if(!rst)
	begin
		q=0;
		r=0;
	end
	else
	begin
		q=dividend;
		t={4'b0000,divisor};
		r=8'b00000000;
		{r,q}={r,q}<<1;

	//进行8次循环比较//
	for(i=0;i<j;i=i+1)
		if(r>=t)
		begin
			r=r-t;
			{r,q}={r,q}<<1;
			q[0]=1;
		end
		else
		begin
			r=r;
			{r,q}={r,q}<<1;
			q[0]=0;
		end
	end

end

assign quotient=q;
assign reminder=r>>1;

endmodule
//除法器textbench代码:
`timescale 1ns/1ns
module divider_module_tb  ; 

parameter j  = 8 ; 
  reg  [7:0]  divisor   ; 
  wire  [7:0]  quotient   ; 
  reg    rst   ; 
  wire  [7:0]  reminder   ; 
  reg    clk   ; 
  reg  [7:0]  dividend   ; 
  
//定义复位时钟//  
initial
  begin
    rst<=0;
    #10 rst<=1;
  end
  
//定义时钟//
initial clk<=0;
always #5 clk<=~clk;

//定义除数与被除数//
 initial
 begin
   dividend<=8'd127;
   divisor<=4'd2;
 end
  
divider_module    #( j  )
   DUT  ( 
       .divisor (divisor ) ,
      .quotient (quotient ) ,
      .rst (rst ) ,
      .reminder (reminder ) ,
      .clk (clk ) ,
      .dividend (dividend ) ); 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值