Advertisement
Guest User

Untitled

a guest
Oct 18th, 2019
113
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.81 KB | None | 0 0
  1. // Last modified: 21.10.2018
  2. // Author: dosarudaniel@gmail.com
  3. `include "defines.vh"
  4. module alu #(
  5. parameter DATA_WIDTH = 8
  6. )(
  7. input wire [`OPSEL_COUNT-1:0] opsel,
  8. input wire enable,
  9. input wire [DATA_WIDTH-1:0] rd,
  10. input wire [DATA_WIDTH-1:0] rr,
  11. output reg [DATA_WIDTH-1:0] out,
  12. input wire [DATA_WIDTH-1:0] flags_in,
  13. output reg [DATA_WIDTH-1:0] flags_out
  14. );
  15.  
  16. /* flags_out a fost transformat in reg, pentru a putea
  17. * fi atribuit in interiorul unui bloc always, insa va fi
  18. * sintetizat tot combinational (UAL-ul nici macar nu are clk
  19. * drept input) */
  20.  
  21. /* TODO: De codificat cateva operatii
  22. * in defines.vh si de implementat aici folosind acest instruction set manual:
  23. * http://ww1.microchip.com/downloads/en/devicedoc/atmel-0856-avr-instruction-set-manual.pdf [1]
  24. */
  25. always @* begin
  26. case (opsel)
  27. // Example: Add with carry. See page 30 at [1].
  28. `OPSEL_ADC: begin
  29. out = rd + rr + flags_in[`FLAGS_C];
  30.  
  31. flags_out[`FLAGS_I] = flags_in[`FLAGS_I];
  32. flags_out[`FLAGS_T] = flags_in[`FLAGS_T];
  33. flags_out[`FLAGS_H] = (rd[3] & rr[3]) | (rr[3] & ~out[3]) | (~out[3] & rd[3]);
  34. flags_out[`FLAGS_V] = (rd[7] & rr[7] & ~out[7]) | (~rd[7] & ~rr[7] & out[7]);
  35. flags_out[`FLAGS_N] = out[7];
  36. flags_out[`FLAGS_S] = flags_out[`FLAGS_N] ^ flags_out[`FLAGS_V]; // S = N ⊕ V
  37. flags_out[`FLAGS_Z] = (out == 0);
  38. flags_out[`FLAGS_C] = (rd[7] & rr[7]) | (rr[7] & ~out[7]) | (~out[7] & rd[7]);
  39. end
  40.  
  41. `OPSEL_NEG: begin
  42. out = -rd;
  43. flags_out[`FLAGS_I] = flags_in[`FLAGS_I];
  44. flags_out[`FLAGS_T] = flags_in[`FLAGS_T];
  45. flags_out[`FLAGS_H] = out[3] | ~rd[3];
  46. flags_out[`FLAGS_V] = out[7] & ~out[6] & ~out[5] & ~out[4] & ~out[3] & ~out[2] & ~out[1] & ~out[0];
  47. flags_out[`FLAGS_N] = out[7];
  48. flags_out[`FLAGS_S] = flags_out[`FLAGS_N] ^ flags_out[`FLAGS_V]; // S = N ⊕ V
  49. flags_out[`FLAGS_Z] = ~out[7] & ~out[6] & ~out[5] & ~out[4] & ~out[3] & ~out[2] & ~out[1] & ~out[0];
  50. flags_out[`FLAGS_C] = out[7] | out[6] | out[5] | out[4] | out[3] | out[2] | out[1] | out[0];
  51.  
  52. end
  53.  
  54. `OPSEL_ADD: begin
  55. out = rd + rr;
  56.  
  57. flags_out[`FLAGS_I] = flags_in[`FLAGS_I];
  58. flags_out[`FLAGS_T] = flags_in[`FLAGS_T];
  59. flags_out[`FLAGS_H] = (rd[3] & rr[3]) | (rr[3] & ~out[3]) | (~out[3] & rd[3]);
  60. flags_out[`FLAGS_V] = (rd[7] & rr[7] & ~out[7]) | (~rd[7] & ~rr[7] & out[7]);
  61. flags_out[`FLAGS_N] = out[7];
  62. flags_out[`FLAGS_S] = flags_out[`FLAGS_N] ^ flags_out[`FLAGS_V]; // S = N ⊕ V
  63. flags_out[`FLAGS_Z] = ~out[7] & ~out[6] & ~out[5] & ~out[4] & ~out[3] & ~out[2] & ~out[1] & ~out[0];
  64. flags_out[`FLAGS_C] = (rd[7] & rr[7]) | (rr[7] & ~out[7]) | (~out[7] & rd[7]);
  65. end
  66.  
  67. `OPSEL_SUB: begin
  68. out = rd - rr;
  69.  
  70. flags_out[`FLAGS_I] = flags_in[`FLAGS_I];
  71. flags_out[`FLAGS_T] = flags_in[`FLAGS_T];
  72. flags_out[`FLAGS_H] = (~rd[3] & rr[3]) | (rr[3] & out[3]) | (out[3] & ~rd[3]);
  73. flags_out[`FLAGS_V] = (rd[7] & ~rr[7] & ~out[7]) | (~rd[7] & rr[7] & out[7]);
  74. flags_out[`FLAGS_N] = out[7];
  75. flags_out[`FLAGS_S] = flags_out[`FLAGS_N] ^ flags_out[`FLAGS_V]; // S = N ⊕ V
  76. flags_out[`FLAGS_Z] = (out == 0);
  77. flags_out[`FLAGS_C] = (~rd[7] & rr[7]) | (rr[7] & out[7]) | (out[7] & ~rd[7]);
  78. end
  79.  
  80. `OPSEL_AND: begin
  81. out = rd & rr;
  82.  
  83. flags_out[`FLAGS_I] = flags_in[`FLAGS_I];
  84. flags_out[`FLAGS_T] = flags_in[`FLAGS_T];
  85. flags_out[`FLAGS_H] = flags_in[`FLAGS_H];
  86. flags_out[`FLAGS_V] = 0;
  87. flags_out[`FLAGS_N] = out[7];
  88. flags_out[`FLAGS_S] = flags_out[`FLAGS_N] ^ flags_out[`FLAGS_V]; // S = N ⊕ V
  89. flags_out[`FLAGS_Z] = (out == 0);
  90. flags_out[`FLAGS_C] = flags_in[`FLAGS_C];
  91. end
  92.  
  93. `OPSEL_OR: begin
  94. out = rd | rr;
  95.  
  96. flags_out[`FLAGS_I] = flags_in[`FLAGS_I];
  97. flags_out[`FLAGS_T] = flags_in[`FLAGS_T];
  98. flags_out[`FLAGS_H] = flags_in[`FLAGS_H];
  99. flags_out[`FLAGS_V] = 0;
  100. flags_out[`FLAGS_N] = out[7];
  101. flags_out[`FLAGS_S] = flags_out[`FLAGS_N] ^ flags_out[`FLAGS_V]; // S = N ⊕ V
  102. flags_out[`FLAGS_Z] = (out == 0);
  103. flags_out[`FLAGS_C] = flags_in[`FLAGS_C];
  104. end
  105. /* TODO: Adaugati implementarea operatiilor aici. */
  106. default: begin
  107. out = 8'bx;
  108. flags_out = flags_in;
  109. end
  110. endcase
  111. end
  112. endmodule
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement