[email protected] posedge clk 中 带复位的触发器,要么全都是 同步复位 ,要么全都是 异步复位 一些建议的代码风格 如果运算符两边的信号都是...">

当前位置:网站首页>【CPU设计实战】数字逻辑电路设计基础(一)

【CPU设计实战】数字逻辑电路设计基础(一)

2022-06-22 05:45:00 阿巴阿阿巴巴巴巴

cpu设计中,需要遵守一些规定

  • 禁止出现initial语句
  • 禁止出现casex,casez
  • 禁止使用#表达电路延迟
  • 时钟信号clock只允许出现在[email protected](posedge clk)中
  • 带复位的触发器,要么全都是同步复位,要么全都是异步复位

一些建议的代码风格

如果运算符两边的信号都是单比特,应该用“&”而不是“&&”,“|”而不是“||”
表示逻辑关系时,用“&&”和“||”
表示逻辑门时,如先行进位加法器的先行进位生成逻辑、乘法器里的华莱士树,那么用“|”和“&”

实践任务一:寄存器堆仿真

regfine.v

module regfile(
  input         clk,
  input  [ 4:0] raddr1,
  output [31:0] rdata1,
  input  [ 4:0] raddr2,
  output [31:0] rdata2,
  input         we,
  input  [ 4:0] waddr,
  input  [31:0] wdata
);
reg [31:0] rf[31:0];
// WRITE
always @(posedge clk) begin
    if (we) rf[waddr]<= wdata;//如果写使能 将数据写入对应的寄存器
end
// READ OUT 1
assign rdata1 = (raddr1==5'b0) ? 32'b0 : rf[raddr1];//根据寄存器地址 读出相应寄存器中的值
// READ OUT 2
assign rdata2 = (raddr2==5'b0) ? 32'b0 : rf[raddr2];
endmodule

rf_tb.v

`timescale 1ns / 1ps

module tb_top();

reg         clk;

reg  [ 4:0] raddr1;
wire [31:0] rdata1;
reg  [ 4:0] raddr2;
wire [31:0] rdata2;
reg         we;
reg  [ 4:0] waddr;
reg  [31:0] wdata;

reg  [ 3:0] task_phase;

regfile regfile0(
    .clk      (clk       ),
    .raddr1   (raddr1    ),
    .rdata1   (rdata1    ),
    .raddr2   (raddr2    ),
    .rdata2   (rdata2    ),
    .we       (we        ),
    .waddr    (waddr     ),
    .wdata    (wdata     ) 
);

//clk
initial 
begin
    clk = 1'b1;
end
always #5 clk = ~clk;
					
initial 
begin
    raddr1 =  5'd0;
    raddr2 =  5'd0;
	waddr  =  5'd0;
	wdata  = 32'd0;
	we     =  1'd0;
	task_phase =  4'd0;
	#2000;
	
	$display("=============================");
	$display("Test Begin");
	#1;
	// Part 0 Begin
	#10;
	task_phase = 4'd0;
	we         = 1'b0;
	waddr      = 5'd1;
	wdata      = 32'hffffffff;
    raddr1     = 5'd1;
    #10;
	we         = 1'b1;
	waddr      = 5'd1;
	wdata      = 32'h1111ffff;
    #10;
	we         = 1'b0;
    raddr1     = 5'd2;
    raddr2     = 5'd1;
	#10;
    raddr1     = 5'd1;
    
    #200;
    // Part 1 Begin
    #10;
	task_phase = 4'd1;
	we         = 1'b1;
	wdata      = 32'h0000ffff;
	waddr      =  5'h10;
    raddr1     =  5'h10;
    raddr2     =  5'h0f;
	#10;
	wdata      = 32'h1111ffff;
	waddr      =  5'h11;
    raddr1     =  5'h11;
    raddr2     =  5'h10;
	#10;
	wdata      = 32'h2222ffff;
	waddr      =  5'h12;
    raddr1     =  5'h12;
    raddr2     =  5'h11;
	#10;
	wdata      = 32'h3333ffff;
	waddr      =  5'h13;
    raddr1     =  5'h13;
    raddr2     =  5'h12;
	#10;
	wdata      = 32'h4444ffff;
	waddr      =  5'h14;
    raddr1     =  5'h14;
    raddr2     =  5'h13;
	#10;
    raddr1     =  5'h15;
    raddr2     =  5'h14;
	#10;

    #200;
	// Part 2 Begin
	#10;
	task_phase = 4'd2;
	we         = 1'b1;
    raddr1     =  5'h10;
    raddr2     =  5'h0f;
	#10;
    raddr1     =  5'h11;
    raddr2     =  5'h10;
	#10;
    raddr1     =  5'h12;
    raddr2     =  5'h11;
	#10;
    raddr1     =  5'h13;
    raddr2     =  5'h12;
	#10;
    raddr1     =  5'h14;
    raddr2     =  5'h13;
	#10;
	
	#50;
	$display("TEST END");
	$finish;
end

endmodule

仿真

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

实践任务二:同步RAM和异步RAM仿真、综合与实现

为同步RAM、异步RAM各建一个工程,调用IP实例化同步RAM,异步RAM。

同步

module ram_top (
    input         clk      ,
    input  [15:0] ram_addr ,
    input  [31:0] ram_wdata,
    input         ram_wen  ,
    output [31:0] ram_rdata
);
					   
block_ram block_ram (
    .clka (clk       ),
    .wea  (ram_wen   ),
    .addra(ram_addr  ),
    .dina (ram_wdata ),
    .douta(ram_rdata ) 
);
endmodule

异步

module ram_top (
    input         clk      ,
    input  [15:0] ram_addr ,
    input  [31:0] ram_wdata,
    input         ram_wen  ,
    output [31:0] ram_rdata		   
);
					   
distributed_ram distributed_ram(
    .clk (clk       ),
    .we  (ram_wen   ),
    .a   (ram_addr  ),
    .d   (ram_wdata ),
    .spo (ram_rdata ) 
);

endmodule

测试

`timescale 1ns / 1ps

module tb_top();

reg         clk;

reg         ram_wen;
reg  [15:0] ram_addr;
reg  [31:0] ram_wdata;
wire [31:0] ram_rdata;
reg  [3 :0] task_phase;

ram_top u_ram_top(
    .clk      (clk       ),
    .ram_wen  (ram_wen   ),
    .ram_addr (ram_addr  ),
    .ram_wdata(ram_wdata ),
    .ram_rdata(ram_rdata ) 
);

//clk
initial 
begin
    clk = 1'b1;
end
always #5 clk = ~clk;
					
initial 
begin
	ram_addr   = 16'd0;
	ram_wdata  = 32'd0;
	ram_wen    =  1'd0;
	task_phase =  4'd0;
	#2000;
	
	$display("=============================");
	$display("Test Begin");
	#1;
	// Part 0 Begin
	#10;
	task_phase = 4'd0;
	ram_wen    = 1'b0;
	ram_addr   = 16'hf0;
	ram_wdata  = 32'hffffffff;
    #10;
	ram_wen    = 1'b1;
	ram_addr   = 16'hf0;
	ram_wdata  = 32'h11223344;
    #10;
	ram_wen    = 1'b0;
	ram_addr   = 16'hf1;
	#10;
	ram_wen    = 1'b0;
	ram_addr   = 16'hf0;
    
    #200;
    // Part 1 Begin
    #10;
	task_phase = 4'd1;
	ram_wen    = 1'b1;
	ram_wdata  = 32'hff00;
	ram_addr   = 16'hf0;
	#10;
	ram_wdata  = 32'hff11;
	ram_addr   = 16'hf1;
	#10;
	ram_wdata  = 32'hff22;
	ram_addr   = 16'hf2;
	#10;
	ram_wdata  = 32'hff33;
	ram_addr   = 16'hf3;
	#10;
	ram_wdata  = 32'hff44;
	ram_addr   = 16'hf4;
	#10;

    #200;
	// Part 2 Begin
	#10;
	task_phase = 4'd2;
	ram_wen    = 1'b0;
	ram_addr   = 16'hf0;
	ram_wdata  = 32'hffffffff;
	#10;
	ram_addr   = 16'hf1;
	#10;
	ram_addr   = 16'hf2;
	#10;
	ram_addr   = 16'hf3;
	#10;
	ram_addr   = 16'hf4;
	#10;
	
	#50;
	$display("TEST END");
	$finish;
end

endmodule

仿真 (确实不一样的)

上面四张是异步 下面四张是同步 具体现在我也不知道为什么。。。。。。。。。。。。。。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

原网站

版权声明
本文为[阿巴阿阿巴巴巴巴]所创,转载请带上原文链接,感谢
https://blog.csdn.net/m0_51403396/article/details/125130843