Root/lm32/logic/sakc/rtl/lm32/lm32_decoder.v

1// =============================================================================
2// COPYRIGHT NOTICE
3// Copyright 2006 (c) Lattice Semiconductor Corporation
4// ALL RIGHTS RESERVED
5// This confidential and proprietary software may be used only as authorised by
6// a licensing agreement from Lattice Semiconductor Corporation.
7// The entire notice above must be reproduced on all authorized copies and
8// copies may only be made to the extent permitted by a licensing agreement from
9// Lattice Semiconductor Corporation.
10//
11// Lattice Semiconductor Corporation TEL : 1-800-Lattice (USA and Canada)
12// 5555 NE Moore Court 408-826-6000 (other locations)
13// Hillsboro, OR 97124 web : http://www.latticesemi.com/
14// U.S.A email: techsupport@latticesemi.com
15// =============================================================================/
16// FILE DETAILS
17// Project : LatticeMico32
18// File : lm32_decoder.v
19// Title : Instruction decoder
20// Dependencies : lm32_include.v
21// Version : 6.1.17
22// =============================================================================
23
24`include "lm32_include.v"
25
26// Index of opcode field in an instruction
27`define LM32_OPCODE_RNG 31:26
28`define LM32_OP_RNG 30:26
29
30// Opcodes - Some are only listed as 5 bits as their MSB is a don't care
31`define LM32_OPCODE_ADD 5'b01101
32`define LM32_OPCODE_AND 5'b01000
33`define LM32_OPCODE_ANDHI 6'b011000
34`define LM32_OPCODE_B 6'b110000
35`define LM32_OPCODE_BI 6'b111000
36`define LM32_OPCODE_BE 6'b010001
37`define LM32_OPCODE_BG 6'b010010
38`define LM32_OPCODE_BGE 6'b010011
39`define LM32_OPCODE_BGEU 6'b010100
40`define LM32_OPCODE_BGU 6'b010101
41`define LM32_OPCODE_BNE 6'b010111
42`define LM32_OPCODE_CALL 6'b110110
43`define LM32_OPCODE_CALLI 6'b111110
44`define LM32_OPCODE_CMPE 5'b11001
45`define LM32_OPCODE_CMPG 5'b11010
46`define LM32_OPCODE_CMPGE 5'b11011
47`define LM32_OPCODE_CMPGEU 5'b11100
48`define LM32_OPCODE_CMPGU 5'b11101
49`define LM32_OPCODE_CMPNE 5'b11111
50`define LM32_OPCODE_DIVU 6'b100011
51`define LM32_OPCODE_LB 6'b000100
52`define LM32_OPCODE_LBU 6'b010000
53`define LM32_OPCODE_LH 6'b000111
54`define LM32_OPCODE_LHU 6'b001011
55`define LM32_OPCODE_LW 6'b001010
56`define LM32_OPCODE_MODU 6'b110001
57`define LM32_OPCODE_MUL 5'b00010
58`define LM32_OPCODE_NOR 5'b00001
59`define LM32_OPCODE_OR 5'b01110
60`define LM32_OPCODE_ORHI 6'b011110
61`define LM32_OPCODE_RAISE 6'b101011
62`define LM32_OPCODE_RCSR 6'b100100
63`define LM32_OPCODE_SB 6'b001100
64`define LM32_OPCODE_SEXTB 6'b101100
65`define LM32_OPCODE_SEXTH 6'b110111
66`define LM32_OPCODE_SH 6'b000011
67`define LM32_OPCODE_SL 5'b01111
68`define LM32_OPCODE_SR 5'b00101
69`define LM32_OPCODE_SRU 5'b00000
70`define LM32_OPCODE_SUB 6'b110010
71`define LM32_OPCODE_SW 6'b010110
72`define LM32_OPCODE_USER 6'b110011
73`define LM32_OPCODE_WCSR 6'b110100
74`define LM32_OPCODE_XNOR 5'b01001
75`define LM32_OPCODE_XOR 5'b00110
76
77/////////////////////////////////////////////////////
78// Module interface
79/////////////////////////////////////////////////////
80
81module lm32_decoder (
82    // ----- Inputs -------
83    instruction,
84    // ----- Outputs -------
85    d_result_sel_0,
86    d_result_sel_1,
87    x_result_sel_csr,
88`ifdef LM32_MC_ARITHMETIC_ENABLED
89    x_result_sel_mc_arith,
90`endif
91`ifdef LM32_NO_BARREL_SHIFT
92    x_result_sel_shift,
93`endif
94`ifdef CFG_SIGN_EXTEND_ENABLED
95    x_result_sel_sext,
96`endif
97    x_result_sel_logic,
98`ifdef CFG_USER_ENABLED
99    x_result_sel_user,
100`endif
101    x_result_sel_add,
102    m_result_sel_compare,
103`ifdef CFG_PL_BARREL_SHIFT_ENABLED
104    m_result_sel_shift,
105`endif
106    w_result_sel_load,
107`ifdef CFG_PL_MULTIPLY_ENABLED
108    w_result_sel_mul,
109`endif
110    x_bypass_enable,
111    m_bypass_enable,
112    read_enable_0,
113    read_idx_0,
114    read_enable_1,
115    read_idx_1,
116    write_enable,
117    write_idx,
118    immediate,
119    branch_offset,
120    load,
121    store,
122    size,
123    sign_extend,
124    adder_op,
125    logic_op,
126`ifdef CFG_PL_BARREL_SHIFT_ENABLED
127    direction,
128`endif
129`ifdef CFG_MC_BARREL_SHIFT_ENABLED
130    shift_left,
131    shift_right,
132`endif
133`ifdef CFG_MC_MULTIPLY_ENABLED
134    multiply,
135`endif
136`ifdef CFG_MC_DIVIDE_ENABLED
137    divide,
138    modulus,
139`endif
140    branch,
141    branch_reg,
142    condition,
143`ifdef CFG_DEBUG_ENABLED
144    break,
145`endif
146    scall,
147    eret,
148`ifdef CFG_DEBUG_ENABLED
149    bret,
150`endif
151`ifdef CFG_USER_ENABLED
152    user_opcode,
153`endif
154    csr_write_enable
155    );
156
157/////////////////////////////////////////////////////
158// Inputs
159/////////////////////////////////////////////////////
160
161input [`LM32_INSTRUCTION_RNG] instruction; // Instruction to decode
162
163/////////////////////////////////////////////////////
164// Outputs
165/////////////////////////////////////////////////////
166
167output [`LM32_D_RESULT_SEL_0_RNG] d_result_sel_0;
168reg [`LM32_D_RESULT_SEL_0_RNG] d_result_sel_0;
169output [`LM32_D_RESULT_SEL_1_RNG] d_result_sel_1;
170reg [`LM32_D_RESULT_SEL_1_RNG] d_result_sel_1;
171output x_result_sel_csr;
172reg x_result_sel_csr;
173`ifdef LM32_MC_ARITHMETIC_ENABLED
174output x_result_sel_mc_arith;
175reg x_result_sel_mc_arith;
176`endif
177`ifdef LM32_NO_BARREL_SHIFT
178output x_result_sel_shift;
179reg x_result_sel_shift;
180`endif
181`ifdef CFG_SIGN_EXTEND_ENABLED
182output x_result_sel_sext;
183reg x_result_sel_sext;
184`endif
185output x_result_sel_logic;
186reg x_result_sel_logic;
187`ifdef CFG_USER_ENABLED
188output x_result_sel_user;
189reg x_result_sel_user;
190`endif
191output x_result_sel_add;
192reg x_result_sel_add;
193output m_result_sel_compare;
194reg m_result_sel_compare;
195`ifdef CFG_PL_BARREL_SHIFT_ENABLED
196output m_result_sel_shift;
197reg m_result_sel_shift;
198`endif
199output w_result_sel_load;
200reg w_result_sel_load;
201`ifdef CFG_PL_MULTIPLY_ENABLED
202output w_result_sel_mul;
203reg w_result_sel_mul;
204`endif
205output x_bypass_enable;
206wire x_bypass_enable;
207output m_bypass_enable;
208wire m_bypass_enable;
209output read_enable_0;
210wire read_enable_0;
211output [`LM32_REG_IDX_RNG] read_idx_0;
212wire [`LM32_REG_IDX_RNG] read_idx_0;
213output read_enable_1;
214wire read_enable_1;
215output [`LM32_REG_IDX_RNG] read_idx_1;
216wire [`LM32_REG_IDX_RNG] read_idx_1;
217output write_enable;
218wire write_enable;
219output [`LM32_REG_IDX_RNG] write_idx;
220wire [`LM32_REG_IDX_RNG] write_idx;
221output [`LM32_WORD_RNG] immediate;
222wire [`LM32_WORD_RNG] immediate;
223output [`LM32_PC_RNG] branch_offset;
224wire [`LM32_PC_RNG] branch_offset;
225output load;
226wire load;
227output store;
228wire store;
229output [`LM32_SIZE_RNG] size;
230wire [`LM32_SIZE_RNG] size;
231output sign_extend;
232wire sign_extend;
233output adder_op;
234wire adder_op;
235output [`LM32_LOGIC_OP_RNG] logic_op;
236wire [`LM32_LOGIC_OP_RNG] logic_op;
237`ifdef CFG_PL_BARREL_SHIFT_ENABLED
238output direction;
239wire direction;
240`endif
241`ifdef CFG_MC_BARREL_SHIFT_ENABLED
242output shift_left;
243wire shift_left;
244output shift_right;
245wire shift_right;
246`endif
247`ifdef CFG_MC_MULTIPLY_ENABLED
248output multiply;
249wire multiply;
250`endif
251`ifdef CFG_MC_DIVIDE_ENABLED
252output divide;
253wire divide;
254output modulus;
255wire modulus;
256`endif
257output branch;
258wire branch;
259output branch_reg;
260wire branch_reg;
261output [`LM32_CONDITION_RNG] condition;
262wire [`LM32_CONDITION_RNG] condition;
263`ifdef CFG_DEBUG_ENABLED
264output break;
265wire break;
266`endif
267output scall;
268wire scall;
269output eret;
270wire eret;
271`ifdef CFG_DEBUG_ENABLED
272output bret;
273wire bret;
274`endif
275`ifdef CFG_USER_ENABLED
276output [`LM32_USER_OPCODE_RNG] user_opcode;
277wire [`LM32_USER_OPCODE_RNG] user_opcode;
278`endif
279output csr_write_enable;
280wire csr_write_enable;
281
282/////////////////////////////////////////////////////
283// Internal nets and registers
284/////////////////////////////////////////////////////
285
286wire [`LM32_WORD_RNG] extended_immediate; // Zero or sign extended immediate
287wire [`LM32_WORD_RNG] high_immediate; // Immediate as high 16 bits
288wire [`LM32_WORD_RNG] call_immediate; // Call immediate
289wire [`LM32_WORD_RNG] branch_immediate; // Conditional branch immediate
290wire sign_extend_immediate; // Whether the immediate should be sign extended (`TRUE) or zero extended (`FALSE)
291wire select_high_immediate; // Whether to select the high immediate
292wire select_call_immediate; // Whether to select the call immediate
293
294/////////////////////////////////////////////////////
295// Functions
296/////////////////////////////////////////////////////
297
298`include "lm32_functions.v"
299
300/////////////////////////////////////////////////////
301// Combinational logic
302/////////////////////////////////////////////////////
303
304// Determine opcode
305wire op_add = instruction[`LM32_OP_RNG] == `LM32_OPCODE_ADD;
306wire op_and = instruction[`LM32_OP_RNG] == `LM32_OPCODE_AND;
307wire op_andhi = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_ANDHI;
308wire op_b = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_B;
309wire op_bi = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_BI;
310wire op_be = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_BE;
311wire op_bg = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_BG;
312wire op_bge = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_BGE;
313wire op_bgeu = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_BGEU;
314wire op_bgu = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_BGU;
315wire op_bne = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_BNE;
316wire op_call = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_CALL;
317wire op_calli = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_CALLI;
318wire op_cmpe = instruction[`LM32_OP_RNG] == `LM32_OPCODE_CMPE;
319wire op_cmpg = instruction[`LM32_OP_RNG] == `LM32_OPCODE_CMPG;
320wire op_cmpge = instruction[`LM32_OP_RNG] == `LM32_OPCODE_CMPGE;
321wire op_cmpgeu = instruction[`LM32_OP_RNG] == `LM32_OPCODE_CMPGEU;
322wire op_cmpgu = instruction[`LM32_OP_RNG] == `LM32_OPCODE_CMPGU;
323wire op_cmpne = instruction[`LM32_OP_RNG] == `LM32_OPCODE_CMPNE;
324`ifdef CFG_MC_DIVIDE_ENABLED
325wire op_divu = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_DIVU;
326`endif
327wire op_lb = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_LB;
328wire op_lbu = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_LBU;
329wire op_lh = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_LH;
330wire op_lhu = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_LHU;
331wire op_lw = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_LW;
332`ifdef CFG_MC_DIVIDE_ENABLED
333wire op_modu = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_MODU;
334`endif
335`ifdef LM32_MULTIPLY_ENABLED
336wire op_mul = instruction[`LM32_OP_RNG] == `LM32_OPCODE_MUL;
337`endif
338wire op_nor = instruction[`LM32_OP_RNG] == `LM32_OPCODE_NOR;
339wire op_or = instruction[`LM32_OP_RNG] == `LM32_OPCODE_OR;
340wire op_orhi = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_ORHI;
341wire op_raise = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_RAISE;
342wire op_rcsr = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_RCSR;
343wire op_sb = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_SB;
344`ifdef CFG_SIGN_EXTEND_ENABLED
345wire op_sextb = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_SEXTB;
346wire op_sexth = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_SEXTH;
347`endif
348wire op_sh = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_SH;
349`ifdef LM32_BARREL_SHIFT_ENABLED
350wire op_sl = instruction[`LM32_OP_RNG] == `LM32_OPCODE_SL;
351`endif
352wire op_sr = instruction[`LM32_OP_RNG] == `LM32_OPCODE_SR;
353wire op_sru = instruction[`LM32_OP_RNG] == `LM32_OPCODE_SRU;
354wire op_sub = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_SUB;
355wire op_sw = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_SW;
356wire op_user = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_USER;
357wire op_wcsr = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_WCSR;
358wire op_xnor = instruction[`LM32_OP_RNG] == `LM32_OPCODE_XNOR;
359wire op_xor = instruction[`LM32_OP_RNG] == `LM32_OPCODE_XOR;
360
361// Group opcodes by function
362wire arith = op_add | op_sub;
363wire logicc = op_and | op_andhi | op_nor | op_or | op_orhi | op_xor | op_xnor;
364wire cmp = op_cmpe | op_cmpg | op_cmpge | op_cmpgeu | op_cmpgu | op_cmpne;
365wire bra = op_b | op_bi | op_be | op_bg | op_bge | op_bgeu | op_bgu | op_bne;
366wire call = op_call | op_calli;
367`ifdef LM32_BARREL_SHIFT_ENABLED
368wire shift = op_sl | op_sr | op_sru;
369`endif
370`ifdef LM32_NO_BARREL_SHIFT
371wire shift = op_sr | op_sru;
372`endif
373`ifdef CFG_MC_BARREL_SHIFT_ENABLED
374assign shift_left = op_sl;
375assign shift_right = op_sr | op_sru;
376`endif
377`ifdef CFG_SIGN_EXTEND_ENABLED
378wire sext = op_sextb | op_sexth;
379`endif
380`ifdef LM32_MULTIPLY_ENABLED
381wire multiply = op_mul;
382`endif
383`ifdef CFG_MC_DIVIDE_ENABLED
384assign divide = op_divu;
385assign modulus = op_modu;
386`endif
387assign load = op_lb | op_lbu | op_lh | op_lhu | op_lw;
388assign store = op_sb | op_sh | op_sw;
389
390// Select pipeline multiplexor controls
391always @*
392begin
393    // D stage
394    if (call)
395        d_result_sel_0 = `LM32_D_RESULT_SEL_0_NEXT_PC;
396    else
397        d_result_sel_0 = `LM32_D_RESULT_SEL_0_REG_0;
398    if (call)
399        d_result_sel_1 = `LM32_D_RESULT_SEL_1_ZERO;
400    else if ((instruction[31] == 1'b0) && !bra)
401        d_result_sel_1 = `LM32_D_RESULT_SEL_1_IMMEDIATE;
402    else
403        d_result_sel_1 = `LM32_D_RESULT_SEL_1_REG_1;
404    // X stage
405    x_result_sel_csr = `FALSE;
406`ifdef LM32_MC_ARITHMETIC_ENABLED
407    x_result_sel_mc_arith = `FALSE;
408`endif
409`ifdef LM32_NO_BARREL_SHIFT
410    x_result_sel_shift = `FALSE;
411`endif
412`ifdef CFG_SIGN_EXTEND_ENABLED
413    x_result_sel_sext = `FALSE;
414`endif
415    x_result_sel_logic = `FALSE;
416`ifdef CFG_USER_ENABLED
417    x_result_sel_user = `FALSE;
418`endif
419    x_result_sel_add = `FALSE;
420    if (op_rcsr)
421        x_result_sel_csr = `TRUE;
422`ifdef LM32_MC_ARITHMETIC_ENABLED
423`ifdef CFG_MC_BARREL_SHIFT_ENABLED
424    else if (shift_left | shift_right)
425        x_result_sel_mc_arith = `TRUE;
426`endif
427`ifdef CFG_MC_DIVIDE_ENABLED
428    else if (divide | modulus)
429        x_result_sel_mc_arith = `TRUE;
430`endif
431`ifdef CFG_MC_MULTIPLY_ENABLED
432    else if (multiply)
433        x_result_sel_mc_arith = `TRUE;
434`endif
435`endif
436`ifdef LM32_NO_BARREL_SHIFT
437    else if (shift)
438        x_result_sel_shift = `TRUE;
439`endif
440`ifdef CFG_SIGN_EXTEND_ENABLED
441    else if (sext)
442        x_result_sel_sext = `TRUE;
443`endif
444    else if (logicc)
445        x_result_sel_logic = `TRUE;
446`ifdef CFG_USER_ENABLED
447    else if (op_user)
448        x_result_sel_user = `TRUE;
449`endif
450    else
451        x_result_sel_add = `TRUE;
452    
453    // M stage
454
455    m_result_sel_compare = cmp;
456`ifdef CFG_PL_BARREL_SHIFT_ENABLED
457    m_result_sel_shift = shift;
458`endif
459
460    // W stage
461    w_result_sel_load = load;
462`ifdef CFG_PL_MULTIPLY_ENABLED
463    w_result_sel_mul = op_mul;
464`endif
465end
466
467// Set if result is valid at end of X stage
468assign x_bypass_enable = arith
469                        | logicc
470`ifdef CFG_MC_BARREL_SHIFT_ENABLED
471                        | shift_left
472                        | shift_right
473`endif
474`ifdef CFG_MC_MULTIPLY_ENABLED
475                        | multiply
476`endif
477`ifdef CFG_MC_DIVIDE_ENABLED
478                        | divide
479                        | modulus
480`endif
481`ifdef LM32_NO_BARREL_SHIFT
482                        | shift
483`endif
484`ifdef CFG_SIGN_EXTEND_ENABLED
485                        | sext
486`endif
487`ifdef CFG_USER_ENABLED
488                        | op_user
489`endif
490                        | op_rcsr
491                        ;
492// Set if result is valid at end of M stage
493assign m_bypass_enable = x_bypass_enable
494`ifdef CFG_PL_BARREL_SHIFT_ENABLED
495                        | shift
496`endif
497                        | cmp
498                        ;
499// Register file read port 0
500assign read_enable_0 = ~(op_bi | op_calli);
501assign read_idx_0 = instruction[25:21];
502// Register file read port 1
503assign read_enable_1 = ~(op_bi | op_calli | load);
504assign read_idx_1 = instruction[20:16];
505// Register file write port
506assign write_enable = ~(bra | op_raise | store | op_wcsr);
507assign write_idx = call
508                    ? 5'd29
509                    : instruction[31] == 1'b0
510                        ? instruction[20:16]
511                        : instruction[15:11];
512                        
513// Size of load/stores
514assign size = instruction[27:26];
515// Whether to sign or zero extend
516assign sign_extend = instruction[28];
517// Set adder_op to 1 to perform a subtraction
518assign adder_op = op_sub | op_cmpe | op_cmpg | op_cmpge | op_cmpgeu | op_cmpgu | op_cmpne | bra;
519// Logic operation (and, or, etc)
520assign logic_op = instruction[29:26];
521`ifdef CFG_PL_BARREL_SHIFT_ENABLED
522// Shift direction
523assign direction = instruction[29];
524`endif
525// Control flow microcodes
526assign branch = bra | call;
527assign branch_reg = op_call | op_b;
528assign condition = instruction[28:26];
529`ifdef CFG_DEBUG_ENABLED
530assign break = op_raise & ~instruction[2];
531`endif
532assign scall = op_raise & instruction[2];
533assign eret = op_b & (instruction[25:21] == 5'd30);
534`ifdef CFG_DEBUG_ENABLED
535assign bret = op_b & (instruction[25:21] == 5'd31);
536`endif
537`ifdef CFG_USER_ENABLED
538// Extract user opcode
539assign user_opcode = instruction[10:0];
540`endif
541// CSR read/write
542assign csr_write_enable = op_wcsr;
543
544// Extract immediate from instruction
545
546assign sign_extend_immediate = ~(op_and | op_cmpgeu | op_cmpgu | op_nor | op_or | op_xnor | op_xor);
547assign select_high_immediate = op_andhi | op_orhi;
548assign select_call_immediate = instruction[31];
549
550assign high_immediate = {instruction[15:0], 16'h0000};
551assign extended_immediate = {{16{sign_extend_immediate & instruction[15]}}, instruction[15:0]};
552assign call_immediate = {{6{instruction[25]}}, instruction[25:0]};
553assign branch_immediate = {{16{instruction[15]}}, instruction[15:0]};
554
555assign immediate = select_high_immediate == `TRUE
556                        ? high_immediate
557                        : extended_immediate;
558   
559assign branch_offset = select_call_immediate == `TRUE
560                        ? call_immediate
561                        : branch_immediate;
562    
563endmodule
564
565

Archive Download this file

Branches:
master



interactive