标准化模块设计
在掌握了基本的设计方法和操作后,提升的方法无非就是在规模和速度上下功夫。规模需要实际的需求驱动,而速度则是设计的自我追求。更快的设计速度可以提高个人的思考能力和处理复杂模型的能力。而想要提高设计速度,根本的方法还是考虑全面,有章可循。为此,认真的做好每一个标准的模块的设计记录是加速的第一要务。将常见的模块类型加以总结以便以后的利用。
二、实验原理
在设计模块过程中,首先考虑的是输入和输出,而输出是模块的必要条件。至少要有一个输出,这也意味着所有的模块都可以由单输出的模块复合而成。而在设计过程中,输出的多少是实际情况决定的,对其进行分类的意义不大,顶多是功能定义是更加方便,不能提高设计速度。而输入作为输出的控制源,对输入的有效分类可以减少设计过程中出现的输入模糊和输入补充这样的额外工作。还有一个决定设计速度的是控制链的明确。控制链的长短直接决定了设计的难易程度(即always模块的赋值数量,不考虑组合电路的影响)。为了提高实际的设计速度,应当对这两个方面进行分类优化。
三、实验操作
1.系统功能的定义与划分
(1)系统功能的定义
构建2个模块,依次为0控制输入X级输出、1控制输入X级输出(之所以为X级是为了在设计时不断地优化)
(2)功能划分
按照两个模块的输入输出划分即可
2.设计规模的初步预算
两个子模块,每个子模块预计6个always模块
3.芯片选型
MAX II
4.逻辑模块划分和模块间接口定义(顶层模块设计)
实际代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
|
//for getting better design experience //it needs some standard modules //just about some usual RTL `timescale 1ns/1ns
module standard_m( input Clk, input Rst_n, input key_a, output q );
wire q1; wire q2; assign q = (q1 && q2) || q2;
I0LX U1( .Clk( Clk), .Rst_n(Rst_n), .q1(q1)
); I1LX U2(
.Clk(Clk), .Rst_n(Rst_n), .key_a(key_a), .q2(q2) );
endmodule
|
5.子模块设计
模块1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
|
module I0LX( input Clk, input Rst_n, output reg q1
);
//zero user input mean it just controled by //its own module, usually by time. //so now it is to muticounter key reg [3:0] t1_cnt; reg [3:0] t2_cnt; reg [3:0] t3_cnt; reg [3:0] t4_cnt; reg [3:0] t5_cnt; //every bit to counter parameter t1 = 4'd10, t2 = 4'd10, t3 = 4'd10, t4 = 4'd10, t5 = 4'd10; always@(posedge Clk or negedge Rst_n) begin if(!Rst_n) q1 <= 1'b0; // no effect else if(t5_cnt >= t5-1'b1 ) q1 <= ~q1; else ; // for other output situation end always@(posedge Clk or negedge Rst_n) begin if(!Rst_n) t1_cnt <= 1'b0; else if( t1_cnt >= t1) t1_cnt <= 1'b0; else t1_cnt <= t1_cnt + 1'b1; end always@(posedge Clk or negedge Rst_n) begin if(!Rst_n)
大专栏 标准化模块设计pan class="line"> t2_cnt <= 1'b0; else if( t2_cnt >= t2) t2_cnt <= 1'b0; else if( t1_cnt == t1) t2_cnt <= t2_cnt + 1'b1; else ; end always@(posedge Clk or negedge Rst_n) begin if(!Rst_n) t3_cnt <= 1'b0; else if( t3_cnt >= t3) t3_cnt <= 1'b0; else if( t2_cnt == t2) t3_cnt <= t3_cnt + 1'b1; else ; end always@(posedge Clk or negedge Rst_n) begin if(!Rst_n) t4_cnt <= 1'b0; else if( t4_cnt >= t4) t4_cnt <= 1'b0; else if( t3_cnt == t3) t4_cnt <= t4_cnt + 1'b1; else ; end always@(posedge Clk or negedge Rst_n) begin if(!Rst_n) t5_cnt <= 1'b0; else if( t5_cnt >= t5-1'b1) t5_cnt <= 1'b0; else if( t4_cnt == t4) t5_cnt <= t5_cnt + 1'b1; else ; end
endmodule
|
模块2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
|
module I1LX( input Clk, input Rst_n, input key_a, output reg q2
); //one key input is always to set switch, //and it needs analyse , it is about // key time reg key_a_cnt1; reg key_a_cnt2; reg [3:0] key_t;
always@(posedge Clk or negedge Rst_n) begin if(!Rst_n) q2 <= 1'b0; else if(key_a_cnt1) q2 <= 1'b1; else if(key_a_cnt2) q2 <= ~q2 ; else ; end always@(posedge Clk or negedge Rst_n) begin if(!Rst_n) key_a_cnt1 <= 1'b0; else if(key_a) key_a_cnt1 <= 1'b1; else key_a_cnt1 <= 1'b0; end always@(posedge Clk or negedge Rst_n) begin if(!Rst_n) key_a_cnt2 <= 1'b0; else if(key_a_cnt1) key_a_cnt2 <= 1'b1; else if(key_t >= 4'd10) key_a_cnt2 <= 1'b0; end always@(posedge Clk or negedge Rst_n) begin if(!Rst_n) key_t <=4'b0; else if(key_a_cnt2) key_t <= key_t +1'b1; else if(!key_a_cnt2) key_t <= 1'b0; else ; end endmodule
|
6.功能仿真
模块1测试代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
`timescale 1ns/1ns `define Clk_period 20 //simulation to 50 Mhz module I0LX_tb; reg Clk =1'b0; reg Rst_n=1'b0; wire q1;
I0LX U1_tb( .Clk(Clk), .Rst_n(Rst_n), .q1(q1) );
always#(`Clk_period) Clk=~Clk; initial begin #(`Clk_period*10) Rst_n = 1'b1; #(`Clk_period*100000000) $stop; end endmodule
|
7.管脚分配
略
8.时序约束
略
9.时序仿真
略
10.综合网表
略
11.板级调试
略
四、实验结果
时钟上升沿和实时判断的区别导致了时钟计时偏差,解决方法还没找到,这需要实际的设计经历来强化。时序构建和时序约束是数字电路中的重点。
五、实验优化
六、总结
这次主要是对一些常见的简易模块的常用框架熟悉,最后还是要落实到实际的模块的设计。使用自己熟悉的模块架构可以有效地提高设计的稳定性和速度。这是个积累的过程,是不可避免的。此外,开始接触一些其他人的标准模块也是不错的手段。总之,在适应了小规模的verilog设计后,要逐步的接触中等规模的设计,以训练速度和大面积设计的能力。