Chinaunix首页 | 论坛 | 博客
  • 博客访问: 458391
  • 博文数量: 62
  • 博客积分: 1742
  • 博客等级: 中尉
  • 技术积分: 859
  • 用 户 组: 普通用户
  • 注册时间: 2010-11-06 00:13
个人简介

这是一句很长很长而且又很啰嗦并且很无聊的废话...

文章分类

全部博文(62)

文章存档

2013年(1)

2012年(13)

2011年(48)

分类: LINUX

2012-11-26 22:11:31

    首先画出我心中的电路.该电路实现简单的从数据总线载入数据到系统总线,寄存器与寄存器之间的交换数据,加法,减法和乘法5个功能的16位处理器.Windows的画图工具太难使了,所以,整个电路是使用同一个时钟.因为是很简单的,所以最大组合逻辑电路的时延和最小的时钟周期也没有去计算,时序仿真时都是用很长的一个时钟周期.整个电路的寄存器与总线之间的连接是用三态门控制的的.贴出来,以后回顾一下.

然后再用Verilog表述出心中的电路.

点击(此处)折叠或打开

  1. //0->load,1Cycle
  2. //1->move,1Cycle
  3. //2->add,3Cycle
  4. //3->dec,3Cycle
  5. //4->mul,3Cycle

  6. module sprocess(clk, func ,data , w, cycle, bus, R0, R1, R2, R3);
  7.     parameter cycle_bit_wide = 2;
  8.     parameter dec_cycle_bit_wide = 1 << cycle_bit_wide;
  9.     parameter ctl_bit_wide = 3;
  10.     parameter dec_ctl_bit_wide = 1 << ctl_bit_wide;
  11.     parameter regx_bit_wide = 2;
  12.     parameter dec_regx_bit_wide = 1 << regx_bit_wide;
  13.     parameter regy_bit_wide = 2;
  14.     parameter dec_regy_bit_wide = 1 << regy_bit_wide;
  15.     parameter reg_bit_wide = 16;
  16.     parameter reg_count = 4;
  17.     input clk, w;
  18.     input [(ctl_bit_wide + regx_bit_wide + regy_bit_wide)-1:0]func;
  19.     input [reg_bit_wide-1:0]data;
  20.     wire stop, func_set;
  21.     output wire [cycle_bit_wide-1:0]cycle;
  22.     wire [ctl_bit_wide-1:0]func_ctl;
  23.     wire [regx_bit_wide-1:0]func_regx;
  24.     wire [regy_bit_wide-1:0]func_regy;
  25.     wire [dec_cycle_bit_wide-1:0]dec_cycle;
  26.     wire [dec_ctl_bit_wide-1:0]dec_ctl;
  27.     wire [dec_regx_bit_wide-1:0]dec_regx;
  28.     wire [dec_regy_bit_wide-1:0]dec_regy;
  29.     reg [reg_count-1:0]regx_in_en, regx_out_en, regy_in_en, regy_out_en;
  30.     output wire [reg_bit_wide-1:0]bus;
  31.     wire [reg_bit_wide-1:0]See_Reg[reg_count];
  32.     reg [reg_bit_wide-1:0]add_dec_res;
  33.     wire [reg_bit_wide-1:0]summand_out, ad_results_out, multiplicand_out, mul_res, mul_res_mask_bit, mul_results_out;
  34.     wire ad_results_out_en, mul_results_out_en;
  35.     output wire [reg_bit_wide-1:0]R0, R1, R2 ,R3;
  36.     integer i;
  37.     genvar j, k;
  38.     
  39.     //Timing Counts
  40.     assign stop = (dec_cycle[0] && !w) || (dec_cycle[1] && (dec_ctl[0] || dec_ctl[1])) || (dec_cycle[3] && (dec_ctl[2] || dec_ctl[3] || dec_ctl[4]));
  41.     counter count(clk, stop, cycle);
  42.     defparam count.n = cycle_bit_wide;
  43.     //Get Hot Only Num Of Timing Counts
  44.     decoder decoder_cycle(cycle, dec_cycle);
  45.     defparam decoder_cycle.enc_bit_wide = cycle_bit_wide;
  46.     
  47.     assign func_set = w & dec_cycle[0];
  48.     register ctl_reg(clk, func, func_set, {func_ctl,func_regx,func_regy});
  49.     defparam ctl_reg.reg_bit_wide = ctl_bit_wide + regx_bit_wide + regy_bit_wide;
  50.     //Get Hot Only Num Of Func Ctl
  51.     decoder decoder_ctl(func_ctl, dec_ctl);
  52.     defparam decoder_ctl.enc_bit_wide = ctl_bit_wide;
  53.     //Get Hot Only Num Of Func Regx
  54.     decoder decoder_regx(func_regx, dec_regx);
  55.     defparam decoder_regx.enc_bit_wide = regx_bit_wide;
  56.     //Get Hot Only Num Of Func Regx
  57.     decoder decoder_regy(func_regy, dec_regy);
  58.     defparam decoder_regy.enc_bit_wide = regy_bit_wide;
  59.     
  60.     always@(regx_in_en, regx_out_en, regy_in_en, regy_out_en, dec_cycle, dec_ctl, dec_regx, dec_regy)
  61.     begin
  62.         regx_in_en = 0;
  63.         regx_out_en = 0;
  64.         regy_in_en = 0;
  65.         regy_out_en = 0;
  66.         for(i=0;i<reg_count;i=i+1)
  67.         begin
  68.             regx_in_en[i] = (dec_cycle[1] && (dec_ctl[0] || dec_ctl[1]) && dec_regx[i]) || (dec_cycle[3] && (dec_ctl[2] || dec_ctl[3] || dec_ctl[4]) && dec_regx[i]);
  69.             regx_out_en[i] = (dec_cycle[1] && dec_regx[i] && (dec_ctl[2] || dec_ctl[3] || dec_ctl[4]));
  70.             regy_out_en[i] = (dec_cycle[1] && dec_ctl[1] && dec_regy[i]) || (dec_cycle[2] && (dec_ctl[2] || dec_ctl[3] || dec_ctl[4]) && dec_regy[i]);
  71.         end
  72.     end
  73.     
  74.     assign bus = (dec_cycle[1] && dec_ctl[0])?data:'bz;
  75.     generate
  76.         for(j=0;j<reg_count;j=j+1)
  77.         begin:regs
  78.             register nor_reg(clk, bus, (regx_in_en[j] | regy_in_en[j]), See_Reg[j]);
  79.             defparam nor_reg.reg_bit_wide = reg_bit_wide;
  80.         end
  81.         for(k=0;k<reg_count;k=k+1)
  82.         begin:set_bus
  83.             assign bus = (regx_out_en[k] | regy_out_en[k])?See_Reg[k]:'bz;
  84.         end
  85.     endgenerate
  86.     //To make the output visible
  87.     assign R0 = See_Reg[0];
  88.     assign R1 = See_Reg[1];
  89.     assign R2 = See_Reg[2];
  90.     assign R3 = See_Reg[3];
  91.     
  92.     //Add/Dec Process
  93.     register summand(clk, bus, (dec_cycle[1] && (dec_ctl[2] || dec_ctl[3])), summand_out);
  94.     defparam summand.reg_bit_wide = reg_bit_wide;
  95.     always@(add_dec_res, summand_out, bus, dec_ctl)
  96.     begin
  97.         if(dec_ctl[2])
  98.         begin
  99.             add_dec_res = summand_out + bus;
  100.         end else begin
  101.             add_dec_res = summand_out - bus;
  102.         end
  103.     end
  104.     register ad_results(clk, add_dec_res, 1, ad_results_out);
  105.     defparam ad_results.reg_bit_wide = reg_bit_wide;
  106.     assign ad_results_out_en = (dec_cycle[3] && (dec_ctl[2] || dec_ctl[3]));
  107.     assign bus = ad_results_out_en?ad_results_out:'bz;
  108.     
  109.     //Mul Process
  110.     register multiplicand(clk, bus, (dec_cycle[1] && dec_ctl[4]), multiplicand_out);
  111.     defparam multiplicand.reg_bit_wide = reg_bit_wide;
  112.     multiplier mul(multiplicand_out, bus, {mul_res_mask_bit, mul_res});
  113.     defparam mul.n = reg_bit_wide;
  114.     register mul_results(clk, mul_res, 1, mul_results_out);
  115.     defparam mul_results.reg_bit_wide = reg_bit_wide;
  116.     assign mul_results_out_en = (dec_cycle[3] && dec_ctl[4]);
  117.     assign bus = mul_results_out_en?mul_results_out:'bz;
  118. endmodule

  119. module decoder(in_const, out_hoc);
  120.     parameter enc_bit_wide = 32;
  121.     parameter dec_bit_wide = 1 << enc_bit_wide;
  122.     input [enc_bit_wide-1:0]in_const;
  123.     output reg [dec_bit_wide-1:0]out_hoc;
  124.     integer i;
  125.     
  126.     always@(in_const, out_hoc)
  127.     begin
  128.         out_hoc = 0;
  129.         for(i=0;i<dec_bit_wide;i=i+1)
  130.         begin
  131.             if(in_const == i)
  132.             begin
  133.                 out_hoc[i] = 1'b1;
  134.             end
  135.         end
  136.     end
  137. endmodule

  138. module register(clk, in_val, in_en, out_val);
  139.     parameter reg_bit_wide = 32;
  140.     input clk, in_en;
  141.     input [reg_bit_wide-1:0]in_val;
  142.     output reg [reg_bit_wide-1:0]out_val;
  143.     
  144.     always@(posedge clk)
  145.     begin
  146.         if(in_en)
  147.         begin
  148.             out_val <= in_val;
  149.         end
  150.     end

  151. endmodule

  152. module counter(clk, en, c);
  153.     parameter n = 32;
  154.     input clk;
  155.     input en;
  156.     output reg [n-1:0]c;
  157.     
  158.     always@(posedge clk)
  159.     begin
  160.         if(en)
  161.             c <= 0;
  162.         else
  163.             c <= c + 1;
  164.     end
  165. endmodule

  166. module multiplier(x, y, out);
  167.     parameter n = 16;
  168.     input [n-1:0]x, y;
  169.     output [n*2-1:0]out;
  170.     genvar i, j, k, l;
  171.     wire [n:0]tmp_sun[n-1], tmp_out[n-1];
  172.     wire [n:0]tmp_x;
  173.     
  174.     assign tmp_x = {1'b0,x};
  175.     assign out[0] = tmp_x[0] & y[0];
  176.     generate
  177.         assign tmp_out[0][0] = 1'b0;
  178.         for(i=0;i<n;i=i+1)
  179.         begin:add_bt
  180.             top_m tm (tmp_x[i+1], y[0], tmp_x[i], y[1], tmp_out[0][i], tmp_sun[0][i], tmp_out[0][i+1]);
  181.         end
  182.         assign out[1] = tmp_sun[0][0];
  183.         assign tmp_sun[0][n] = tmp_out[0][n];
  184.         
  185.         for(j=2;j<n;j=j+1)
  186.         begin:ftf
  187.             for(k=0;k<n;k=k+1)
  188.             begin:add_bb
  189.                 btm_m bm (tmp_sun[j-2][k+1], tmp_x[k], y[j], tmp_out[j-1][k], tmp_sun[j-1][k], tmp_out[j-1][k+1]);
  190.             end
  191.             assign out[j] = tmp_sun[j-1][0];
  192.             assign tmp_sun[j-1][n] = tmp_out[j-1][n];
  193.         end
  194.         
  195.         for(l=n;l<n*2;l=l+1)
  196.         begin:add_o
  197.             assign out[l] = tmp_sun[n-2][l-n+1];
  198.         end
  199.     endgenerate
  200. endmodule

  201. module top_m(m0, q0, m1, q1, cin, sun, cout);
  202.     input m0, m1, q0, q1;
  203.     input cin;
  204.     output sun, cout;
  205.     wire x, y;
  206.     
  207.     assign x = m0 & q0;
  208.     assign y = m1 & q1;
  209.     full_add fa (x, y, cin, sun, cout);
  210. endmodule

  211. module btm_m(sunin, m, q, cin, sun, cout);
  212.     input sunin, m, q, cin;
  213.     output sun, cout;
  214.     wire y;
  215.     
  216.     assign y = m & q;
  217.     full_add fa (sunin, y, cin, sun, cout);
  218. endmodule

  219. module full_add(x, y, cin, sun, cout);
  220.     input x, y, cin;
  221.     output reg sun, cout;

  222.     always@(x, y, cin)
  223.     begin
  224.         sun <= x^y^cin;
  225.         cout <= x&y | x&cin | y&cin;
  226.     end
  227. endmodule


     最后给出,该电路的时序仿真,功能测试依次为:数据载入->寄存器交换数据->加法->乘法.

小结:
     编写电路时,首先要在脑海构建好自己想要实现的电路,清楚电路每一个细节的实现.例如组合电路和时序电路的每一个时钟周期的配合,组合电路模块最大时钟时延,触发器的最短建立时间与保持时间,开关是使用三态门还是多路器,是使用计数器加译码器还是直接使用计数器等.然后再用Verilog或VHDL把心中的电路描述出来.需要牢记一点,一定要清楚自己的代码会被编译器综合出什么样的电路而写代码,如果连自己都不清楚代码综合成什么样的,那编译器就更不知道了.
阅读(2606) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~