⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 soc-gr0040.v

📁 FPGA RSIC CPU设计文档和源码是EDA中对CPU设计非常好用的程序
💻 V
📖 第 1 页 / 共 2 页
字号:
// Copyright (C) 2000, Gray Research LLC.// All rights reserved.  Use subject to the// XSOC License Agreement, see LICENSE file,// http://www.fpgapcu.org/xsoc/LICENSE.html.// Version 2001.03.09 `define W    16  // register width`define N    15  // register MSB`define AN   15  // address MSB`define IN   15  // instruction MSB  module gr0040(  clk, rst, i_ad_rst,  insn_ce, i_ad, insn, hit, int_en,  d_ad, rdy, sw, sb, do, lw, lb, data);   input  clk;         // clock  input  rst;         // reset (sync)  input [`AN:0] i_ad_rst; // reset vector   output insn_ce;     // insn clock enable   output [`AN:0] i_ad;// next insn address  input  [`IN:0] insn;// current insn  input  hit;         // insn is valid  output int_en;      // OK to intr. now   output [`AN:0] d_ad;// load/store addr  input  rdy;         // memory ready  output sw, sb;      // executing sw (sb)  output [`N:0] do;   // data to store  output lw, lb;      // executing lw (lb)  inout  [`N:0] data; // results, load data   // opcode decoding  `define JAL     (op==0)  `define ADDI    (op==1)  `define RR      (op==2)  `define RI      (op==3)  `define LW      (op==4)  `define LB      (op==5)  `define SW      (op==6)  `define SB      (op==7)  `define IMM     (op==8)  `define Bx      (op==9)  `define ALU     (`RR|`RI)   // fn decoding  `define ADD     (fn==0)  `define SUB     (fn==1)  `define AND     (fn==2)  `define XOR     (fn==3)  `define ADC     (fn==4)  `define SBC     (fn==5)  `define CMP     (fn==6)  `define SRL     (fn==7)  `define SRA     (fn==8)  `define SUM     (`ADD|`SUB|`ADC|`SBC)  `define LOG     (`AND|`XOR)  `define SR      (`SRL|`SRA)   // instruction decoding  wire [3:0] op = insn[15:12];  wire [3:0] rd = insn[11:8];  wire [3:0] rs = insn[7:4];  wire [3:0] fn = `RI ? insn[7:4] : insn[3:0];  wire [3:0] imm = insn[3:0];  wire [11:0] i12 = insn[11:0];  wire [3:0] cond = insn[11:8];  wire [7:0] disp = insn[7:0];  // register file and program counter  wire valid_insn_ce = hit & insn_ce;  wire rf_we = valid_insn_ce & ~rst &           ((`ALU&~`CMP)|`ADDI|`LB|`LW|`JAL);  wire [`N:0] dreg, sreg; // d, s registers  ram16x16d regfile(.clk(clk), .we(rf_we),    .wr_ad(rd), .ad(`RI ? rd : rs),    .d(data), .wr_o(dreg), .o(sreg));  reg [`AN:0] pc;     // program counter   // immediate prefix  reg imm_pre;          // immediate prefix  reg [11:0] i12_pre;   // imm prefix value  always @(posedge clk)    if (rst)      imm_pre <= 0;    else if (valid_insn_ce)      imm_pre <= `IMM;  always @(posedge clk)    if (valid_insn_ce)      i12_pre <= i12;   // immediate operand  wire word_off = `LW|`SW|`JAL;  wire sxi = (`ADDI|`ALU) & imm[3];  wire [10:0] sxi11 = {11{sxi}};  wire i_4 = sxi | (word_off&imm[0]);  wire i_0 = ~word_off&imm[0];  wire [`N:0] imm16 = imm_pre ? {i12_pre,imm}                  : {sxi11,i_4,imm[3:1],i_0};   // operand selection  wire [`N:0] a = `RR ? dreg : imm16;  wire [`N:0] b = sreg;  // adder/subtractor  wire [`N:0] sum;  wire add = ~(`ALU&(`SUB|`SBC|`CMP));  reg c; // carry-in if adc/sbc  wire ci = add ? c : ~c;  wire c_W, x;  addsub adder(.add(add), .ci(ci), .a(a),          .b(b), .sum(sum), .x(x), .co(c_W));   // condition codes  wire z = sum == 0;             // zero  wire n = sum[`N];              // negative  wire co = add ? c_W : ~c_W;    // carry-out  wire v = c_W^sum[`N]^a[`N]^b[`N];// overflow  reg ccz, ccn, ccc, ccv; // CC vector  always @(posedge clk)    if (rst)      {ccz,ccn,ccc,ccv} <= 0;    else if (valid_insn_ce)      {ccz,ccn,ccc,ccv} <= {z,n,co,v};    // add/subtract-with-carry state  always @(posedge clk)    if (rst)      c <= 0;    else if (valid_insn_ce)      c <= co & (`ALU&(`ADC|`SBC));   // logic unit  wire [`N:0] log = fn[0] ? a^b : a&b;  // shift right  wire [`N:0] sr = {(`SRA?b[`N]:0),b[`N:1]};   // result mux  wire sum_en = (`ALU&`SUM) | `ADDI;  assign data = sum_en      ? sum : 16'bz;  assign data = (`ALU&`LOG) ? log : 16'bz;  assign data = (`ALU&`SR)  ? sr  : 16'bz;  assign data = `JAL        ? pc  : 16'bz;   // conditional branch decoding  `define BR      0  `define BEQ     2  `define BC      4  `define BV      6  `define BLT     8  `define BLE     'hA  `define BLTU    'hC  `define BLEU    'hE   // conditional branches  reg br, t;  always @(hit or cond or op or           ccz or ccn or ccc or ccv) begin    case (cond&4'b1110)    `BR:   t = 1;    `BEQ:  t = ccz;    `BC:   t = ccc;    `BV:   t = ccv;    `BLT:  t = ccn^ccv;    `BLE:  t = (ccn^ccv)|ccz;    `BLTU: t = ~ccz&~ccc;    `BLEU: t = ccz|~ccc;    endcase    br = hit & `Bx & (cond[0] ? ~t : t);  end   // jumps, branches, insn fetch  wire [6:0] sxd7   = {7{disp[7]}};  wire [`N:0] sxd16 = {sxd7,disp,1'b0};  wire [`N:0] pcinc = br ? sxd16 : {hit,1'b0};  wire [`N:0] pcincd = pc + pcinc;  assign i_ad  = (hit & `JAL) ? sum : pcincd;  always @(posedge clk)    if (rst)      pc <= i_ad_rst;    else if (valid_insn_ce)      pc <= i_ad;  wire   mem     = hit & (`LB|`LW|`SB|`SW);  assign insn_ce = rst | ~(mem & ~rdy);   // data loads, stores  assign d_ad = sum;  assign do = dreg;  assign lw = hit & `LW;  assign lb = hit & `LB;  assign sw = hit & `SW;  assign sb = hit & `SB;   // interrupt support  assign int_en = hit &               ~(`IMM|`ALU&(`ADC|`SBC|`CMP)); endmodule   module addsub(add, ci, a, b, sum, x, co);  input  add, ci;  input  [15:0] a, b;  output [15:0] sum;  output x, co;  assign {co,sum,x}= add ? {a,ci}+{b,1'b1}                         : {a,ci}-{b,1'b1}; endmodule  module gr0041(  clk, rst, i_ad_rst, int_req,  insn_ce, i_ad, insn, hit, zero_insn,  d_ad, rdy, sw, sb, do, lw, lb, data);   input  clk;         // clock  input  rst;         // reset (sync)  input [`AN:0] i_ad_rst; // reset vector  input  int_req;     // interrupt request   output insn_ce;     // insn clock enable   output [`AN:0] i_ad;// next insn address  input  [`IN:0] insn;// current insn  input  hit;         // insn is valid  output zero_insn;   // force insn to 0000   output [`AN:0] d_ad;// load/store addr  input  rdy;         // memory ready  output sw, sb;      // executing sw (sb)  output [`N:0] do;   // data to store  output lw, lb;      // executing lw (lb)  inout  [`N:0] data; // results, load data   wire int_en;        // interrupt enabled  reg int;            // call intr in progress   // interrupt request rising edge detection  reg int_req_last, int_pend;  always @(posedge clk)    if (rst)      int_req_last <= 0;    else      int_req_last <= int_req;  always @(posedge clk)    if (rst)      int_pend <= 0;    else if (int)      int_pend <= 0;    else if (int_req && ~int_req_last)      int_pend <= 1;   // insert intr at an auspicious time  wire int_nxt = int_pend & int_en & ~int;  always @(posedge clk)    if (rst)      int <= 0;    else if (insn_ce)      int <= int_nxt;   // on int, fetch 0000 and execute 0002,  // which is 'jal r0,2(r0)' -- call intr  assign zero_insn = int_nxt;  wire [`N:0] insn_int = insn | {int, 1'b0};   gr0040 p(   .clk(clk), .rst(rst),   .i_ad_rst(i_ad_rst),   .insn_ce(insn_ce), .i_ad(i_ad),   .insn(insn_int), .hit(hit | int),   .int_en(int_en),   .d_ad(d_ad), .rdy(rdy),   .sw(sw), .sb(sb), .do(do),   .lw(lw), .lb(lb), .data(data)); endmodule  // on-chip peripheral bus defines`define IO       // on-chip periphs enabled`define CN   31  // ctrl bus MSB`define CRAN 7   // control reg addr MSB`define DN   15  // data bus MSB`define SELN 7   // select bus MSB   module soc(clk, rst, par_i, par_o);  input  clk;         // clock  input  rst;         // reset (sync)   input  [7:0] par_i; // parallel inputs  output [7:0] par_o; // parallel outputs   //  // processor ports and control signals  //  wire [`AN:0] i_ad, d_ad;  wire [`N:0]  insn, do;  tri  [`N:0]  data;  wire int_req, zero_insn;  wire rdy, sw, sb, lw, lb;   gr0041 p(   .clk(clk), .rst(rst),   .i_ad_rst(16'h0020), .int_req(int_req),   .insn_ce(insn_ce), .i_ad(i_ad),   .insn(insn), .hit(~rst),   .zero_insn(zero_insn),   .d_ad(d_ad), .rdy(rdy),   .sw(sw), .sb(sb), .do(do),   .lw(lw), .lb(lb), .data(data));   //  // rdy (wait state) control  //  reg loaded; // load data in bram out regs  always @(posedge clk)    if (rst)      loaded <= 0;    else if (insn_ce)      loaded <= 0;    else      loaded <= (lw|lb); `ifdef IO  wire io_nxt = d_ad[`AN];`else  wire io_nxt = 0;`endif   reg io; // peripheral I/O access underway  always @(posedge clk)    if (rst)      io <= 0;    else if (insn_ce)      io <= 0;    else      io <= io_nxt;  wire io_rdy;  assign rdy = ~io_nxt&~((lw|lb)&~loaded) |               io&io_rdy | rst;   //  // embedded RAM  //  wire h_we = ~rst&~io_nxt&(sw|sb&~d_ad[0]);  wire l_we = ~rst&~io_nxt&(sw|sb&d_ad[0]);  wire [7:0] do_h = sw ? do[15:8] : do[7:0];  wire [`N:0] di;   RAMB4_S8_S8 ramh(

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -