project.sv 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. interface processor_port(
  2. input clk, rst,
  3. // RAM
  4. output [23:0] ram_addr,
  5. output [15:0] ram_wr_data,
  6. input [15:0] ram_rd_data,
  7. output ram_wr_en,
  8. output ram_rd_en,
  9. input ram_busy,
  10. input ram_rd_ready,
  11. input ram_rd_ack,
  12. // COM
  13. output [7:0] com_addr,
  14. output [7:0] com_wr,
  15. input [7:0] com_rd,
  16. input com_interrupt
  17. );
  18. endinterface
  19. module com_block(
  20. input clk, rst,
  21. // Communication to processor
  22. input wire [7:0] addr,
  23. input reg [7:0] in_data,
  24. output reg [7:0] out_data,
  25. output wire interrupt,
  26. // IO
  27. output reg [7:0] leds,
  28. input wire [3:0] switches,
  29. output wire uart0_tx,
  30. input wire uart0_rx,
  31. input wire key1
  32. );
  33. /* UART */
  34. reg [2:0] uart0_reg;
  35. reg uart0_recv;
  36. reg uart0_transmit;
  37. reg [7:0] tx_byte, rx_byte;
  38. // Clock divide = 1e6 / (9600 * 4)
  39. //uart#(.CLOCK_DIVIDE(1302)) uart0(
  40. uart#(.CLOCK_DIVIDE(26)) uart0(
  41. .clk(clk),
  42. .rst(0),
  43. .rx(uart0_rx),
  44. .tx(uart0_tx),
  45. .tx_byte(tx_byte),
  46. .rx_byte(rx_byte),
  47. .received(uart0_recv),
  48. `ifdef SYNTHESIS
  49. .is_receiving(uart0_reg[0]),
  50. .is_transmitting(uart0_reg[1]),
  51. `endif
  52. .transmit(uart0_transmit)
  53. );
  54. initial uart0_reg[1:0] = 2'b00;
  55. //reg [7:0] reset_str [7];
  56. //reg [2:0] reset_seq;
  57. //always_comb begin
  58. // reset_str[0] = 8'h72;
  59. // reset_str[1] = 8'h65;
  60. // reset_str[2] = 8'h73;
  61. // reset_str[3] = 8'h65;
  62. // reset_str[4] = 8'h74;
  63. // reset_str[5] = 8'h2e;
  64. // reset_str[6] = 8'h10;
  65. //end
  66. always_ff@(posedge clk) begin
  67. if(rst) begin
  68. //reset_seq <= 0;
  69. uart0_reg[2] <= 0;
  70. leds <= 'b0000_0000;
  71. end
  72. //else if(~uart0_reg[2] && reset_seq != 7) reset_seq <= reset_seq + 1;
  73. else begin
  74. case(addr)
  75. 8'h03: uart0_reg[2] <= in_data[2];
  76. //8'h06: leds <= in_data;
  77. endcase
  78. leds <= {5'b0, uart0_reg};
  79. end
  80. end
  81. always_comb begin
  82. //tx_byte = 8'h23;
  83. //uart0_transmit = 1;
  84. uart0_transmit = (addr == 8'h05) || (uart0_recv && uart0_reg[2]);
  85. tx_byte = (uart0_recv && uart0_reg[2]) ? rx_byte : in_data;
  86. //tx_byte = in_data;
  87. case(addr)
  88. 8'h03: out_data = in_data; // Set uart0 flags
  89. 8'h04: out_data = {5'b0, uart0_reg}; // Read uart0 flags
  90. 8'h05: out_data = in_data; // Write to uart0
  91. 8'h07: out_data = leds; // Read current LEDs
  92. 8'h08: out_data = {4'b0, switches}; // Read DIP
  93. default: out_data = 0;
  94. endcase
  95. end
  96. endmodule
  97. module sdram_block(
  98. input mclk, fclk, rst_n,
  99. // SDRAM Control
  100. input [23:0] ram_addr,
  101. input [15:0] ram_wr_data,
  102. output reg [15:0] ram_rd_data,
  103. input ram_wr_en,
  104. input ram_rd_en,
  105. output ram_busy,
  106. output ram_rd_ready,
  107. output ram_rd_ack,
  108. // SDRAM I/O
  109. inout [15:0] DRAM_DQ, // Data
  110. output [12:0] DRAM_ADDR, // Address
  111. output [1:0] DRAM_DQM, // Byte Data Mask
  112. output DRAM_CLK, // Clock
  113. output DRAM_CKE, // Clock Enable
  114. output DRAM_WE_N, // Write Enable
  115. output DRAM_CAS_N, // Column Address Strobe
  116. output DRAM_RAS_N, // Row Address Strobe
  117. output DRAM_CS_N, // Chip Select
  118. output [1:0] DRAM_BA // Bank Address
  119. );
  120. /* SDRAM */
  121. // 1 MHz side wires
  122. //wire [39:0] wr_fifo;// Address 24-bit and 16-bit Data
  123. //wire wr_enable; // wr_enable ] <-> [ wr : wr_enable to push fifo
  124. //wire wr_full; // wr_full ] <-> [ full : signal that we are full
  125. //wire rd_enable; // rd_enable - wr : rd_enable to push rd addr to fifo
  126. //wire rdaddr_full; // rdaddr_full - full : signal we cannot read more
  127. //wire [15:0] rddo_fifo;
  128. //wire ctrl_rd_ready; // wr - rd_ready : push data from dram to fifo
  129. //// 100MHz side wires
  130. //wire [39:0] wro_fifo;
  131. //wire ctrl_busy; // rd ] <-> [ busy : pop fifo when ctrl not busy
  132. //wire ctrl_wr_enable; // empty_n - wr_enable : signal ctrl data is ready
  133. //wire [23:0] rdao_fifo;
  134. //wire ctrl_rd_enable; // empty_n - rd_enable : signal ctrl addr ready
  135. //wire [15:0] rddata_fifo;
  136. //wire rd_ready; // rd_ready - empty_n : signal interface data ready
  137. //wire rd_ack; // rd_ack - rd : pop fifo after data read
  138. //wire busy; // RAM is busy because RW FIFO is full
  139. //assign busy = wr_full | rdaddr_full;
  140. //fifo #(.BUS_WIDTH(40)) dram_wr_fifo (
  141. // .wr_clk (mclk),
  142. // .rd_clk (fclk),
  143. // .wr_data (wr_fifo),
  144. // .rd_data (wro_fifo),
  145. // .rd (ctrl_busy),
  146. // .wr (wr_enable),
  147. // .full (wr_full),
  148. // .empty_n (ctrl_wr_enable),
  149. // .rst_n (rst_n)
  150. //);
  151. //
  152. //fifo #(.BUS_WIDTH(24)) dram_rd_addr_fifo (
  153. // .wr_clk (mclk),
  154. // .rd_clk (fclk),
  155. // .wr_data (wr_fifo[39:16]),
  156. // .rd_data (rdao_fifo),
  157. // .rd (ctrl_busy),
  158. // .wr (rd_enable),
  159. // .full (rdaddr_full),
  160. // .empty_n (ctrl_rd_enable),
  161. // .rst_n (rst_n)
  162. //);
  163. //
  164. //fifo #(.BUS_WIDTH(16)) dram_rd_data_fifo (
  165. // .wr_clk (fclk),
  166. // .rd_clk (mclk),
  167. // .wr_data (rddo_fifo),
  168. // .rd_data (rddata_fifo),
  169. // .rd (rd_ack),
  170. // .wr (ctrl_rd_ready),
  171. // .empty_n (rd_ready),
  172. // .rst_n (rst_n)
  173. //);
  174. reg busy, rd_ready, rd_en, wr_en;
  175. reg [1:0] state;
  176. reg [15:0] wr_data, rd_data, rd_data_reg;
  177. always_ff@(posedge fclk) begin
  178. if(~rst_n) begin
  179. state <= 0;
  180. wr_en <= 0;
  181. rd_en <= 0;
  182. end
  183. else begin
  184. if(rd_ready) ram_rd_data <= rd_data;
  185. if(mclk & (state == 0)) state <= 1;
  186. //if(rd_ready) rd_data_reg <= rd_data;
  187. else if(state == 1 && ~busy) begin
  188. wr_data <= ram_wr_data;
  189. wr_en <= ram_wr_en;
  190. rd_en <= ram_rd_en;
  191. state <= (ram_wr_en | ram_rd_en) ? 2 : 1;
  192. end else if (state == 2) begin
  193. wr_en <= 0;
  194. rd_en <= 0;
  195. state <= 3;
  196. end
  197. if(~mclk & (state == 3)) state <= 0;
  198. end
  199. end
  200. //always_ff@(posedge mclk) begin
  201. //state <= 0;
  202. //ram_rd_data <= rd_data_reg;
  203. //end
  204. //assign ram_rd_data = rd_data_reg;
  205. // Setting SDRAM clock to 100MHz
  206. assign DRAM_CLK = fclk;
  207. `ifdef SYNTHESIS
  208. sdram_controller sdram_control0 (
  209. // HOST INTERFACE
  210. .wr_addr (ram_addr),
  211. .wr_data (wr_data),
  212. .wr_enable (wr_en),
  213. .rd_addr (ram_addr),
  214. .rd_data (rd_data),
  215. .rd_ready (rd_ready),
  216. .rd_enable (rd_en),
  217. .busy (busy),
  218. .rst_n (rst_n),
  219. .clk (fclk),
  220. // SDRAM SIDE
  221. .addr (DRAM_ADDR),
  222. .bank_addr (DRAM_BA),
  223. .data (DRAM_DQ),
  224. .clock_enable (DRAM_CKE),
  225. .cs_n (DRAM_CS_N),
  226. .ras_n (DRAM_RAS_N),
  227. .cas_n (DRAM_CAS_N),
  228. .we_n (DRAM_WE_N),
  229. .data_mask_low (DRAM_DQM[0]),
  230. .data_mask_high(DRAM_DQM[1])
  231. );
  232. `else
  233. reg [15:0] rd_data0;
  234. memory#(.WIDTH(16), .LENGTH(2**8)) mock_sdram0(
  235. .clk(fclk),
  236. .wr_en(wr_en),
  237. .rd_en(rd_en),
  238. .wd(wr_data),
  239. .rd(rd_data0),
  240. .addr(ram_addr[7:0])
  241. );
  242. always_ff@(posedge fclk) begin
  243. if(~rst_n) busy <= 0;
  244. else begin
  245. rd_data <= rd_data0;
  246. rd_ready <= rd_en;
  247. busy <= rd_en | wr_en;
  248. end
  249. end
  250. `endif
  251. //// Assign inputs
  252. //assign wr_fifo[39:16] = ram_addr;
  253. //assign wr_fifo[15:0] = ram_wr_data;
  254. //assign wr_enable = ram_wr_en;
  255. //assign rd_enable = ram_rd_en;
  256. //
  257. //// Assign outputs
  258. //assign ram_rd_data = rddata_fifo;
  259. //assign ram_busy = busy;
  260. //assign ram_rd_ready = rd_ready;
  261. //assign ram_rd_ack = rd_ack;
  262. endmodule
  263. /**
  264. * Testbench for sdram_controller modules, simulates:
  265. * - Iinit
  266. * - Write
  267. * - Read
  268. */
  269. module sdram_controller_tb();
  270. //vlog_tb_utils vlog_tb_utils0();
  271. /* HOST CONTROLLS */
  272. reg [23:0] haddr;
  273. reg [15:0] data_input;
  274. wire [15:0] data_output;
  275. wire busy;
  276. reg rd_enable, wr_enable, rst_n, clk;
  277. /* SDRAM SIDE */
  278. wire [12:0] addr;
  279. wire [1:0] bank_addr;
  280. wire [15:0] data;
  281. wire clock_enable, cs_n, ras_n, cas_n, we_n, data_mask_low, data_mask_high;
  282. reg [15:0] data_r;
  283. assign data = data_r;
  284. initial
  285. begin
  286. haddr = 24'd0;
  287. data_input = 16'd0;
  288. rd_enable = 1'b0;
  289. wr_enable = 1'b0;
  290. rst_n = 1'b1;
  291. clk = 1'b0;
  292. data_r = 16'hzzzz;
  293. end
  294. always
  295. #1 clk <= ~clk;
  296. initial
  297. begin
  298. #3 rst_n = 1'b0;
  299. #3 rst_n = 1'b1;
  300. #120 haddr = 24'hfedbed;
  301. data_input = 16'd3333;
  302. #3 wr_enable = 1'b1;
  303. #6 wr_enable = 1'b0;
  304. haddr = 24'd0;
  305. data_input = 16'd0;
  306. #120 haddr = 24'hbedfed;
  307. #3 rd_enable = 1'b1;
  308. #6 rd_enable = 1'b0;
  309. haddr = 24'd0;
  310. #8 data_r = 16'hbbbb;
  311. #2 data_r = 16'hzzzz;
  312. #1000 $finish;
  313. end
  314. sdram_controller sdram_controlleri (
  315. /* HOST INTERFACE */
  316. .wr_addr(haddr),
  317. .wr_data(data_input),
  318. .rd_data(data_output),
  319. .busy(busy), .rd_enable(rd_enable), .wr_enable(wr_enable), .rst_n(rst_n), .clk(clk),
  320. /* SDRAM SIDE */
  321. .addr(addr), .bank_addr(bank_addr), .data(data), .clock_enable(clock_enable), .cs_n(cs_n), .ras_n(ras_n), .cas_n(cas_n), .we_n(we_n), .data_mask_low(data_mask_low), .data_mask_high(data_mask_high)
  322. );
  323. endmodule