📄 1verilog.exm
字号:
// 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 + -