kekellner

decoder.v

Oct 12th, 2025
1,817
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
VeriLog 11.90 KB | None | 0 0
  1. module decoder (
  2.     input [15:0] instrReg,
  3.     input Z_decode,
  4.     input C_decode,
  5.     output S,
  6.     output [2:0] F,
  7.     output [7:0] address1,
  8.     output [7:0] address2,
  9.     output ramWE,
  10.     output loadPC,
  11.     output instrEN,
  12.     output PCinstr,
  13.     output [6:0] k,
  14.     output [7:0] K // Esta es la salida de la constante K. Esta salida sustituye al bitswizzling en la interconexión de módulos. Está conectado con el 'wire_K' desde el decoder hacia el MUX de la ALU
  15. );
  16.  
  17.     reg _S, _ramWE, _loadPC, _PCinstr, _instrEN;
  18.     reg [2:0] _F;
  19.     reg [6:0] _k;
  20.     reg [7:0] _K, _address1, _address2;
  21.     wire [3:0] instruction;
  22.  
  23.     assign instruction = instrReg[15:12];
  24.  
  25.     initial begin
  26.         _S = 0;
  27.         _ramWE = 0;
  28.         _loadPC = 0;
  29.         _PCinstr = 0;
  30.         _instrEN = 1;
  31.         _F = 0;
  32.         _k = 0;
  33.         _address1 = 0;
  34.         _address2 = 0;
  35.     end
  36.  
  37.     parameter _pasaRrk = 3'b000;
  38.     parameter _suma = 3'b001;
  39.     parameter _and = 3'b010;
  40.     parameter _resta = 3'b011;
  41.     parameter _xor = 3'b100;
  42.     parameter _pasaRd = 3'b101;
  43.     parameter _or = 3'b110;
  44.  
  45.     always @(*) begin
  46.         casez (instrReg)
  47.             // ADD
  48.             16'b0000_00??_????_????: begin
  49.                 _S = 1;  // Dejar pasar RrK
  50.                 _ramWE = 1;  // Habilitar escritura en RAM
  51.                 _loadPC = 0;  // Señal que determina si se hace o no 'load' en el PC
  52.                 _PCinstr = 0; // Señal que modifica el PC_ALU para decidir entre saltos absolutos (JMP) y saltos relativos (BRBS)
  53.                 _instrEN = 1;  // Señal para habilitar el Instruction Register
  54.                 _F = _suma;  // Señal de la función de la ALU
  55.                 _k = 0;  // Constante de dirección para saltos del PC
  56.                 _K = {
  57.                     instrReg[11:8], instrReg[3:0]
  58.                 };  // Constante de datos para instrucciones LDI, ANDI, CPI
  59.                 _address1 = {3'b000, instrReg[8:4]};
  60.                 _address2 = {3'b000, instrReg[9], instrReg[3:0]};
  61.             end
  62.             // AND
  63.             16'b0001_00??_????_????: begin
  64.                 _S = 1;  // Dejar pasar RrK
  65.                 _ramWE = 1;  // Habilitar escritura en RAM
  66.                 _loadPC = 0;
  67.                 _PCinstr = 0;
  68.                 _instrEN = 1;
  69.                 _F = _and;
  70.                 _k = 0;
  71.                 _K = {instrReg[11:8], instrReg[3:0]};
  72.                 _address1 = {3'b000, instrReg[8:4]};
  73.                 _address2 = {3'b000, instrReg[9], instrReg[3:0]};
  74.             end
  75.             // SUB
  76.             16'b0010_00??_????_????: begin
  77.                 _S = 1;  // Dejar pasar RrK
  78.                 _ramWE = 1;  // Habilitar escritura en RAM
  79.                 _loadPC = 0;
  80.                 _PCinstr = 0;
  81.                 _instrEN = 1;
  82.                 _F = 3'b011;  // ALU -> SUB
  83.                 _k = 0;
  84.                 _K = {instrReg[11:8], instrReg[3:0]};
  85.                 _address1 = {3'b000, instrReg[8:4]};
  86.                 _address2 = {3'b000, instrReg[9], instrReg[3:0]};
  87.             end
  88.             // CLR
  89.             16'b0011_00??_????_????: begin
  90.                 _S = 1;  // Dejar pasar RrK
  91.                 _ramWE = 1;  // Habilitar escritura en RAM
  92.                 _loadPC = 0;
  93.                 _PCinstr = 0;
  94.                 _instrEN = 1;
  95.                 _F = 3'b100;  // ALU -> XOR
  96.                 _k = 0;
  97.                 _K = {instrReg[11:8], instrReg[3:0]};
  98.                 _address1 = {3'b000, instrReg[8:4]};
  99.                 _address2 = {3'b000, instrReg[9], instrReg[3:0]};
  100.             end
  101.             // ANDI
  102.             16'b0100_????_????_????: begin
  103.                 _S = 0;  // Dejar pasar RrK
  104.                 _ramWE = 1;  // Habilitar escritura en RAM
  105.                 _loadPC = 0;
  106.                 _PCinstr = 0;
  107.                 _instrEN = 1;
  108.                 _F = 3'b010;  // AND
  109.                 _k = 0;
  110.                 _K = {instrReg[11:8], instrReg[3:0]};
  111.                 _address1 = {4'b0001, instrReg[7:4]};
  112.                 _address2 = 0;
  113.             end
  114.             // BRBS
  115.             16'b0101_00??_????_????: begin
  116.                 case (instrReg[2:0])
  117.                     3'b000:
  118.                     if (C_decode == 1) begin
  119.                         _S = 0;
  120.                         _ramWE = 0;
  121.                         _loadPC = 1;
  122.                         _PCinstr = 0;
  123.                         _instrEN = 0;
  124.                         _F = 0;
  125.                         _k = instrReg[9:3];
  126.                         _K = {instrReg[11:8], instrReg[3:0]};
  127.                         _address1 = 0;
  128.                         _address2 = 0;
  129.                     end
  130.                     3'b001:
  131.                     if (Z_decode == 1) begin
  132.                         _S = 0;
  133.                         _ramWE = 0;
  134.                         _loadPC = 1;
  135.                         _PCinstr = 0;
  136.                         _instrEN = 0;
  137.                         _F = 0;
  138.                         _k = instrReg[9:3];
  139.                         _K = {instrReg[11:8], instrReg[3:0]};
  140.                         _address1 = 0;
  141.                         _address2 = 0;
  142.                     end
  143.                     default: begin
  144.                         _S = 0;
  145.                         _ramWE = 0;
  146.                         _loadPC = 0;
  147.                         _PCinstr = 0;
  148.                         _instrEN = 0;
  149.                         _F = 0;
  150.                         _k = 0;
  151.                         _address1 = 0;
  152.                         _address2 = 0;
  153.                     end
  154.                 endcase
  155.             end
  156.             // CPI
  157.             16'b0110_????_????_????: begin
  158.                 _S = 0;  // Dejar pasar K
  159.                 _ramWE = 0;  // Deshabilitar escritura en RAM
  160.                 _loadPC = 0;
  161.                 _PCinstr = 0;
  162.                 _instrEN = 1;
  163.                 _F = 3'b011;  // Resta
  164.                 _k = 0;
  165.                 _K = {instrReg[11:8], instrReg[3:0]};
  166.                 _address1 = {4'b0001, instrReg[7:4]};
  167.                 _address2 = 0;
  168.             end
  169.             // JMP
  170.             16'b0111_0000_0???_????: begin
  171.                 _S = 0;
  172.                 _ramWE = 0;
  173.                 _loadPC = 1;
  174.                 _PCinstr = 1;
  175.                 _instrEN = 0;
  176.                 _F = 0;
  177.                 _k = instrReg[6:0];
  178.                 _K = {instrReg[11:8], instrReg[3:0]};
  179.                 _address1 = 0;
  180.                 _address2 = 0;
  181.             end
  182.             // IN
  183.             16'b1000_0???_????_????: begin
  184.                 _S = 1;  // Dejar pasar RrK
  185.                 _ramWE = 1;
  186.                 _loadPC = 0;
  187.                 _PCinstr = 0;
  188.                 _instrEN = 1;
  189.                 _F = _pasaRrk;
  190.                 _k = instrReg[6:0];
  191.                 _K = {instrReg[11:8], instrReg[3:0]};
  192.                 _address1 = {3'b000, instrReg[8:4]};
  193.                 _address2 = {2'b00, instrReg[10:9], instrReg[3:0]} + 8'h20;
  194.             end
  195.             // LDI
  196.             16'b1001_????_????_????: begin
  197.                 _S = 0;  // Dejar pasar K
  198.                 _ramWE = 1;  // Habilitar escritura en RAM
  199.                 _loadPC = 0;
  200.                 _PCinstr = 0;
  201.                 _instrEN = 1;
  202.                 _F = 3'b000;  // Dejar pasar RrK
  203.                 _k = 0;
  204.                 _K = {instrReg[11:8], instrReg[3:0]};
  205.                 _address1 = {4'b0001, instrReg[7:4]};
  206.                 _address2 = 0;
  207.             end
  208.             // LDS (probar)
  209.             16'b1010_????_????_????: begin
  210.                 _S = 1;  // Dejar pasar Rr
  211.                 _ramWE = 1;  // Habilitar escritura en RAM
  212.                 _loadPC = 0;
  213.                 _PCinstr = 0;
  214.                 _instrEN = 1;
  215.                 _F = _pasaRrk;  // Dejar pasar RrK
  216.                 _k = 0;
  217.                 _K = {instrReg[11:8], instrReg[3:0]};
  218.                 _address1 = {4'b0001, instrReg[7:4]};
  219.                 _address2 = {instrReg[11:8], instrReg[3:0]};
  220.             end
  221.             // MOV
  222.             16'b1011_00??_????_????: begin
  223.                 _S = 1;  // Dejar pasar RrK
  224.                 _ramWE = 1;  // Habilitar escritura en RAM
  225.                 _loadPC = 0;
  226.                 _PCinstr = 0;
  227.                 _instrEN = 1;
  228.                 _F = 3'b000;  // Dejar pasar RrK
  229.                 _k = 0;
  230.                 _K = {instrReg[11:8], instrReg[3:0]};
  231.                 _address1 = {3'b000, instrReg[8:4]};
  232.                 _address2 = {3'b000, instrReg[9], instrReg[3:0]};
  233.             end
  234.             // OUT
  235.             16'b1100_0???_????_????: begin
  236.                 _S = 1;  // Dejar pasar Rr
  237.                 _ramWE = 1;  // Habilitar escritura en RAM
  238.                 _loadPC = 0;
  239.                 _PCinstr = 0;
  240.                 _instrEN = 1;
  241.                 _F = 3'b000;  // Dejar pasar RrK
  242.                 _k = 0;
  243.                 _K = {instrReg[11:8], instrReg[3:0]};
  244.                 _address1 = {2'b00, instrReg[10:9], instrReg[3:0]} + 8'h20;
  245.                 _address2 = {3'b000, instrReg[8:4]};
  246.             end
  247.             // STS (probar)
  248.             16'b1101_????_????_????: begin
  249.                 _S = 1;  // Dejar pasar Rr
  250.                 _ramWE = 1;  // Habilitar escritura en RAM
  251.                 _loadPC = 0;
  252.                 _PCinstr = 0;
  253.                 _instrEN = 1;
  254.                 _F = _pasaRrk;  // Dejar pasar RrK
  255.                 _k = 0;
  256.                 _K = {instrReg[11:8], instrReg[3:0]};
  257.                 _address1 = {instrReg[11:8], instrReg[3:0]};
  258.                 _address2 = {4'b0001, instrReg[7:4]};
  259.             end
  260.             // CBI (pendiente)
  261.             16'b1110_????_????_????: begin
  262.                 _S = 0;  // Dejar pasar K
  263.                 _ramWE = 1;  // Habilitar escritura en RAM
  264.                 _loadPC = 0;
  265.                 _PCinstr = 0;
  266.                 _instrEN = 1;
  267.                 _F = _and;
  268.                 _k = 0;
  269.                 _address1 = {3'b000, instrReg[7:3]} + 8'h20;
  270.                 _address2 = 0;
  271.                 case (instrReg[2:0])
  272.                     3'b000:  _K = 8'b1111_1110;
  273.                     3'b001:  _K = 8'b1111_1101;
  274.                     3'b010:  _K = 8'b1111_1011;
  275.                     3'b011:  _K = 8'b1111_0111;
  276.                     3'b100:  _K = 8'b1110_1111;
  277.                     3'b101:  _K = 8'b1101_1111;
  278.                     3'b110:  _K = 8'b1011_1111;
  279.                     3'b111:  _K = 8'b0111_1111;
  280.                     default: _K = 8'b0000_0000;
  281.                 endcase
  282.             end
  283.             // SBI (pendiente)
  284.             16'b1111_????_????_????: begin
  285.                 _S = 0;  // Dejar pasar K
  286.                 _ramWE = 1;  // Habilitar escritura en RAM
  287.                 _loadPC = 0;
  288.                 _PCinstr = 0;
  289.                 _instrEN = 1;
  290.                 _F = _or;
  291.                 _k = 0;
  292.                 _address1 = {3'b000, instrReg[7:3] + 8'h20};
  293.                 _address2 = 0;
  294.                 case (instrReg[2:0])
  295.                     3'b000:  _K = 8'b0000_0001;
  296.                     3'b001:  _K = 8'b0000_0010;
  297.                     3'b010:  _K = 8'b0000_0100;
  298.                     3'b011:  _K = 8'b0000_1000;
  299.                     3'b100:  _K = 8'b0001_0000;
  300.                     3'b101:  _K = 8'b0010_0000;
  301.                     3'b110:  _K = 8'b0100_0000;
  302.                     3'b111:  _K = 8'b1000_0000;
  303.                     default: _K = 8'b0000_0000;
  304.                 endcase
  305.             end
  306.             default: begin
  307.                 _S = 0;
  308.                 _ramWE = 0;
  309.                 _loadPC = 0;
  310.                 _PCinstr = 0;
  311.                 _instrEN = 0;
  312.                 _F = 0;
  313.                 _k = 0;
  314.                 _address1 = 0;
  315.                 _address2 = 0;
  316.             end
  317.  
  318.         endcase
  319.     end
  320.  
  321.     assign S = _S;
  322.     assign PCinstr = _PCinstr;
  323.     assign ramWE = _ramWE;
  324.     assign loadPC = _loadPC;
  325.     assign F = _F;
  326.     assign address1 = _address1;
  327.     assign address2 = _address2;
  328.     assign k = _k;
  329.     assign K = _K;
  330.     assign instrEN = _instrEN;
  331. endmodule
  332.  
Advertisement
Add Comment
Please, Sign In to add comment