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

📄 1verilog.exm

📁 大型risc处理器设计源代码,这是书中的代码 基于流水线的risc cpu设计
💻 EXM
📖 第 1 页 / 共 5 页
字号:
// Asynchronous ALU pipeline                                              //002
//                                                                        //003
//--------------------------------------------------------------------    //004
                                                                          //005
//--------------------------------------------------------------------    //006
//                                                                        //007
// Module FIFO                                                            //008
//                                                                        //009
// Pipeline                                                               //010
//                                                                        //011
//--------------------------------------------------------------------    //012
                                                                          //013
module fifo (CP, RESET, WORK_IN, DATA_IN, SPACELEFT_OUT,                  //014
             WORK_OUT, DATA_OUT, SPACELEFT_IN);                           //015
                                                                          //016
parameter       WIDTH_LD_2 = 0;    // FIFO locations - 1                  //017
parameter       DATA_WIDTH = 0;    // width of data                       //018
                                                                          //019
                                                                          //020
`define         WIDTH (1 << WIDTH_LD_2)                                   //021
                                                                          //022
input           CP,                // clock                               //023
                RESET,             // reset                               //024
                WORK_IN,           // predecessor writing                 //025
                DATA_IN,           // data from predecessor               //026
                SPACELEFT_IN;      // successor ready to read             //027
                                                                          //028
output          WORK_OUT,          // FIFO writing to successor           //029
                DATA_OUT,          // data to successor                   //030
                SPACELEFT_OUT;     // FIFO ready to read                  //031
                                                                          //032
wire [DATA_WIDTH-1:0]                                                     //033
                DATA_IN;           // data from predecessor               //034
                                                                          //035
reg             WORK_OUT,          // message to successor                //036
                SPACELEFT_OUT;     // FIFO ready to read                  //037
reg  [DATA_WIDTH-1:0]                                                     //038
                DATA_OUT;          // data to successor                   //039
                                                                          //040
// Internal variables                                                     //041
reg             READ,              // did read                            //042
                WRITE;             // did write                           //043
reg  [WIDTH_LD_2 -1:0]                                                    //044
                HEAD,              // pointer to begin of data            //045
                TAIL;              // pointer to end of data              //046
reg  [DATA_WIDTH-1:0]                                                     //047
                MEMORY[0:`WIDTH-1]; // memory                             //048
                                                                          //049
//                                                                        //050
// Space left in FIFO                                                     //051
//                                                                        //052
task Set_spaceleft;                                                       //053
if ((HEAD + 1) % `WIDTH != TAIL)   // ring buffer                         //054
  SPACELEFT_OUT = 1;                                                      //055
else                                                                      //056
  SPACELEFT_OUT = 0;                                                      //057
endtask // Set_spaceleft                                                  //058
                                                                          //059
//                                                                        //060
// Initialize FIFO                                                        //061
//                                                                        //062
always @(posedge RESET) begin                                             //063
  HEAD = 0;                                                               //064
  TAIL = 0;                                                               //065
  SPACELEFT_OUT = 1;                                                      //066
  WORK_OUT = 0;                                                           //067
  READ = 0;                                                               //068
  WRITE = 0;                                                              //069
end                                                                       //070
                                                                          //071
//                                                                        //072
// Read                                                                   //073
//                                                                        //074
always @(CP or DATA_IN or WORK_IN)                                        //075
  if (CP == 1 && WORK_IN == 1) begin                                      //076
    MEMORY [HEAD] = DATA_IN;                                              //077
    READ = 1;                      // did read                            //078
  end                                                                     //079
                                                                          //080
//                                                                        //081
// Write                                                                  //082
//                                                                        //083
always @(CP)                                                              //084
  if (CP == 1 && HEAD != TAIL && SPACELEFT_IN == 1)                       //085
  begin                                                                   //086
    DATA_OUT = MEMORY [TAIL];      // data to successor                   //087
    WORK_OUT = 1;                  // message to successor                //088
    WRITE = 1;                     // did write                           //089
  end                                                                     //090
                                                                          //091
//                                                                        //092
// Increase HEAD, TAIL, update SPACELEFT_OUT and WORK_OUT                 //093
//                                                                        //094
always @(negedge CP) begin                                                //095
    if (READ == 1) begin                                                  //096
      HEAD = (HEAD + 1) % `WIDTH;  // increase HEAD                       //097
      READ = 0;                                                           //098
    end                                                                   //099
    if (WRITE == 1) begin                                                 //100
      TAIL = (TAIL + 1) % `WIDTH;  // increase TAIL                       //101
      WRITE = 0;                                                          //102
    end                                                                   //103
    Set_spaceleft;                 // set SPACELEFT_OUT                   //104
    WORK_OUT = 0;                                                         //105
  end                                                                     //106
endmodule // fifo                                                         //107
                                                                          //108
                                                                          //109
//--------------------------------------------------------------------    //110
//                                                                        //111
// Module ALU                                                             //112
//                                                                        //113
//--------------------------------------------------------------------    //114
                                                                          //115
module alu (CP, RESET, WORK_IN, OPERAND1, OPERAND2, OPERATION,            //116
            SPACELEFT_OUT, RESULT, WORK_OUT, SPACELEFT_IN);               //117
                                                                          //118
input           CP,                // clock                               //119
                RESET,             // reset                               //120
                OPERAND1,          // ALU operands                        //121
                OPERAND2,                                                 //122
                OPERATION,         // ALU opcode                          //123
                WORK_IN,           // predecessor writing                 //124
                SPACELEFT_IN;      // successor ready to read             //125
                                                                          //126
output          WORK_OUT,          // message to successor                //127
                SPACELEFT_OUT,     // ALU ready to read                   //128
                RESULT;            // ALU result                          //129
                                                                          //130
wire      [3:0] OPERATION;         // ALU opcode                          //131
wire      [7:0] OPERAND1,          // ALU operands                        //132
                OPERAND2;                                                 //133
                                                                          //134
reg       [7:0] RESULT,            // ALU result                          //135
                TEMPMEMORY;        // result ALU (buffer)                 //136
reg             WORK_OUT,          // message to successor                //137
                NEW_RESULT,        // ALU computing                       //138
                SPACELEFT_OUT;     // ALU ready to read                   //139
                                                                          //140
integer         CYCLES;            // remaining computing time            //141
                                                                          //142
                                                                          //143
`define         ADD 0                                                     //144
`define         SUB 1                                                     //145
`define         MUL 2                                                     //146
`define         DIV 3                                                     //147
                                                                          //148
//                                                                        //149
// Initialization                                                         //150
//                                                                        //151
always @(posedge RESET) begin                                             //152
  WORK_OUT = 0;                                                           //153
  NEW_RESULT = 0;                                                         //154
  SPACELEFT_OUT = 1;                                                      //155
end                                                                       //156
                                                                          //157
//                                                                        //158
// Execute operation                                                      //159
//                                                                        //160
always @(CP or WORK_IN or OPERAND1 or OPERAND2 or OPERATION)              //161
  if (CP == 1 && WORK_IN == 1) begin                                      //162
    case (OPERATION)                                                      //163
      `ADD: TEMPMEMORY = OPERAND1 + OPERAND2;                             //164
      `SUB: TEMPMEMORY = OPERAND1 - OPERAND2;                             //165
      `MUL: TEMPMEMORY = OPERAND1 * OPERAND2;                             //166
      `DIV: TEMPMEMORY = OPERAND1 / OPERAND2;                             //167
    endcase                                                               //168
    if (OPERATION > 1)                                                    //169
      CYCLES = 10;                 // multiplication and division         //170
    else                                                                  //171
      CYCLES = 5;                  // addition and subtraction            //172
    NEW_RESULT = 1;                // ALU computing                       //173
    SPACELEFT_OUT = 0;             // no new inputs                       //174
  end                                                                     //175
                                                                          //176
//                                                                        //177
// Report successor status to                                             //178
// predecessor                                                            //179
//                                                                        //180
always @(negedge SPACELEFT_IN) begin                                      //181
  SPACELEFT_OUT = 0;                                                      //182
  @(posedge SPACELEFT_IN);         // successor ready                     //183
  wait (CP == 0);                  // wait                                //184
  SPACELEFT_OUT = 1;                                                      //185
end                                                                       //186
                                                                          //187
//                                                                        //188
// Count down CYCLES;                                                     //189
// result to output;                                                      //190
// synchronization                                                        //191
//                                                                        //192
always @(negedge CP) begin                                                //193
  WORK_OUT = 0;                    // disable successor                   //194
  if (NEW_RESULT) begin            // ALU computing                       //195
    CYCLES = CYCLES - 1;           // emulate computation time            //196
    if (CYCLES == 0) begin                                                //197
      NEW_RESULT = 0;              // ALU not computing                   //198
      @(posedge CP);               // wait                                //199
      RESULT = TEMPMEMORY;                                                //200
      WORK_OUT = 1;                // enable successor                    //201
      SPACELEFT_OUT = 1;           // ALU ready to read                   //202
    end                                                                   //203
  end                                                                     //204
end                                                                       //205
endmodule // alu                                                          //206
                                                                          //207
                                                                          //208
//--------------------------------------------------------------------    //209
//                                                                        //210
// Test module                                                            //211
//                                                                        //212
// System environment of pipeline                                         //213
//                                                                        //214
//--------------------------------------------------------------------    //215
                                                                          //216
module test;                                                              //217
                                                                          //218
// Data widths                                                            //219
`define         DATA_WIDTH_OPERAND 8                                      //220
`define         DATA_WIDTH_OPCODE  4                                      //221
`define    DATA_WIDTH_TOTAL (2*`DATA_WIDTH_OPERAND+`DATA_WIDTH_OPCODE)    //222
                                                                          //223
// Size of FIFO                                                           //224
defparam        FIFO1.DATA_WIDTH = `DATA_WIDTH_TOTAL;                     //225
defparam        FIFO1.WIDTH_LD_2 = 2;                                     //226
defparam        FIFO2.DATA_WIDTH = `DATA_WIDTH_OPERAND;                   //227
defparam        FIFO2.WIDTH_LD_2 = 2;                                     //228
                                                                          //229
// Connections between pipeline stages                                    //230
reg             WORK_SOURCE_FIFO1;      // enable FIFO1                   //231
wire            WORK_FIFO1_ALU,         // enable ALU                     //232
                WORK_ALU_FIFO2,         // enable FIFO2                   //233
                WORK_FIFO2_SINK;        // enable sink                    //234
                                                                          //235
reg  [`DATA_WIDTH_TOTAL -1:0]                                             //236
                DATA_SOURCE_FIFO1;      // data FIFO1                     //237
wire [`DATA_WIDTH_TOTAL -1:0]                                             //238
                DATA_FIFO1_ALU;         // data ALU                       //239
wire [`DATA_WIDTH_OPERAND -1:0]                                           //240
                DATA_ALU_FIFO2,         // data FIFO2                     //241
                DATA_FIFO2_SINK;        // data sink                      //242
                                                                          //243
wire            SPACELEFT_SOURCE_FIFO1, // space in FIFO1                 //244
                SPACELEFT_FIFO1_ALU,    // space in ALU                   //245
                SPACELEFT_ALU_FIFO2;    // space in FIFO2                 //246
reg             SPACELEFT_FIFO2_SINK;   // space in sink                  //247
                                                                          //248
// Miscellaneous                                                          //249
reg             RESET,             // reset                               //250
                CP;                // global clock                        //251
reg [`DATA_WIDTH_OPERAND -1:0]                                            //252
                I;                 // test pattern                        //253
                                                                          //254
//                                                                        //255
// Instances                                                              //256
//                                                                        //257
                                                                          //258
// First FIFO                                                             //259
fifo FIFO1      (CP, RESET, WORK_SOURCE_FIFO1, DATA_SOURCE_FIFO1,         //260
                SPACELEFT_SOURCE_FIFO1,                                   //261
                WORK_FIFO1_ALU, DATA_FIFO1_ALU, SPACELEFT_FIFO1_ALU);     //262
                                                                          //263
// ALU                                                                    //264
alu ALU         (CP, RESET, WORK_FIFO1_ALU, DATA_FIFO1_ALU [15:8],        //265
                DATA_FIFO1_ALU [7:0], DATA_FIFO1_ALU [19:16],             //266
                SPACELEFT_FIFO1_ALU,                                      //267
                DATA_ALU_FIFO2, WORK_ALU_FIFO2, SPACELEFT_ALU_FIFO2);     //268
                                                                          //269
// Second FIFO                                                            //270
fifo FIFO2      (CP, RESET, WORK_ALU_FIFO2, DATA_ALU_FIFO2,               //271
                SPACELEFT_ALU_FIFO2, WORK_FIFO2_SINK,                     //272
                DATA_FIFO2_SINK, SPACELEFT_FIFO2_SINK);                   //273
                                                                          //274
//                                                                        //275
// Global clock                                                           //276
//                                                                        //277
initial begin                                                             //278
  CP = 0;                                                                 //279
  forever begin                                                           //280
    #100;                                                                 //281
    CP = ~ CP;                                                            //282
  end                                                                     //283
end                                                                       //284
                                                                          //285
//                                                                        //286
// Fifo1_write writing to FIFO, if space                                  //287
//                                                                        //288
task Fifo1_write;                                                         //289
                                                                          //290
input [`DATA_WIDTH_TOTAL -1:0]                                            //291
                DATA;              // data                                //292
                                                                          //293
reg             DONE;              // writing done                        //294
                                                                          //295
begin                                                                     //296
  DONE = 0;                        // initialize                          //297
  while (! DONE) begin             // writing in progress                 //298
    @(posedge CP);                 // wait                                //299
    if (SPACELEFT_SOURCE_FIFO1==1) // FIFO1 ready to read                 //300
    begin                                                                 //301
      DATA_SOURCE_FIFO1 = DATA;                                           //302
      WORK_SOURCE_FIFO1 = 1;       // enable                              //303
      @(negedge CP);                                                      //304
      WORK_SOURCE_FIFO1 = 0;                                              //305
      DONE = 1;                                                           //306
    end                                                                   //307
  end                                                                     //308
end                                                                       //309
endtask // Fifo1_write                                                    //310
                                                                          //311
//                                                                        //312
// Monitor interfaces                                                     //313
//                                                                        //314
always @(DATA_SOURCE_FIFO1 or DATA_FIFO1_ALU or DATA_ALU_FIFO2 or         //315
  DATA_FIFO2_SINK)                                                        //316
  $display ("%5.0f      %h            %h          %h\t\t    %h",          //317
    $time, DATA_SOURCE_FIFO1, DATA_FIFO1_ALU, DATA_ALU_FIFO2,             //318
    DATA_FIFO2_SINK);                                                     //319
                                                                          //320
//                                                                        //321
// Initialization                                                         //322
//                                                                        //323
initial begin                                                             //324
  $display (" time  SOURCE_FIFO1       FIFO1_ALU    ALU_FIFO2%s",         //325
    "        FIFO2_SINK");                                                //326
  $gr_waves     ("CP", CP, "RESET", RESET,                                //327
                "1_WORK", WORK_SOURCE_FIFO1, "1_DATA",                    //328
                DATA_SOURCE_FIFO1, "1_SPAC", SPACELEFT_SOURCE_FIFO1,      //329
                "A_WORK", WORK_FIFO1_ALU, "A_DATA", DATA_FIFO1_ALU,       //330
                "A_SPAC", SPACELEFT_FIFO1_ALU,                            //331
                "2_WORK", WORK_ALU_FIFO2, "2_DATA", DATA_ALU_FIFO2,       //332
                "2_SPAC", SPACELEFT_ALU_FIFO2,                            //333
                "S_WORK", WORK_FIFO2_SINK, "S_DATA", DATA_FIFO2_SINK,     //334
                "S_SPAC", SPACELEFT_FIFO2_SINK);                          //335
  WORK_SOURCE_FIFO1 = 0;                                                  //336
  SPACELEFT_FIFO2_SINK = 0;                                               //337
  RESET = 1;                                                    

⌨️ 快捷键说明

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